|
Packit |
8930e1 |
#include <stdio.h>
|
|
Packit |
8930e1 |
#include <string.h>
|
|
Packit |
8930e1 |
#include <sys/mman.h>
|
|
Packit |
8930e1 |
#include <assert.h>
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
#include "log.h"
|
|
Packit |
8930e1 |
#include "rwlock.h"
|
|
Packit |
8930e1 |
#include "os/os.h"
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
void fio_rwlock_write(struct fio_rwlock *lock)
|
|
Packit |
8930e1 |
{
|
|
Packit |
8930e1 |
assert(lock->magic == FIO_RWLOCK_MAGIC);
|
|
Packit |
8930e1 |
pthread_rwlock_wrlock(&lock->lock);
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
void fio_rwlock_read(struct fio_rwlock *lock)
|
|
Packit |
8930e1 |
{
|
|
Packit |
8930e1 |
assert(lock->magic == FIO_RWLOCK_MAGIC);
|
|
Packit |
8930e1 |
pthread_rwlock_rdlock(&lock->lock);
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
void fio_rwlock_unlock(struct fio_rwlock *lock)
|
|
Packit |
8930e1 |
{
|
|
Packit |
8930e1 |
assert(lock->magic == FIO_RWLOCK_MAGIC);
|
|
Packit |
8930e1 |
pthread_rwlock_unlock(&lock->lock);
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
void fio_rwlock_remove(struct fio_rwlock *lock)
|
|
Packit |
8930e1 |
{
|
|
Packit |
8930e1 |
assert(lock->magic == FIO_RWLOCK_MAGIC);
|
|
Packit |
8930e1 |
pthread_rwlock_destroy(&lock->lock);
|
|
Packit |
8930e1 |
munmap((void *) lock, sizeof(*lock));
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
struct fio_rwlock *fio_rwlock_init(void)
|
|
Packit |
8930e1 |
{
|
|
Packit |
8930e1 |
struct fio_rwlock *lock;
|
|
Packit |
8930e1 |
pthread_rwlockattr_t attr;
|
|
Packit |
8930e1 |
int ret;
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
lock = (void *) mmap(NULL, sizeof(struct fio_rwlock),
|
|
Packit |
8930e1 |
PROT_READ | PROT_WRITE,
|
|
Packit |
8930e1 |
OS_MAP_ANON | MAP_SHARED, -1, 0);
|
|
Packit |
8930e1 |
if (lock == MAP_FAILED) {
|
|
Packit |
8930e1 |
perror("mmap rwlock");
|
|
Packit |
8930e1 |
lock = NULL;
|
|
Packit |
8930e1 |
goto err;
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
lock->magic = FIO_RWLOCK_MAGIC;
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
ret = pthread_rwlockattr_init(&attr);
|
|
Packit |
8930e1 |
if (ret) {
|
|
Packit |
8930e1 |
log_err("pthread_rwlockattr_init: %s\n", strerror(ret));
|
|
Packit |
8930e1 |
goto err;
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
#ifdef CONFIG_PSHARED
|
|
Packit |
8930e1 |
ret = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
|
|
Packit |
8930e1 |
if (ret) {
|
|
Packit |
8930e1 |
log_err("pthread_rwlockattr_setpshared: %s\n", strerror(ret));
|
|
Packit |
8930e1 |
goto destroy_attr;
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
ret = pthread_rwlock_init(&lock->lock, &attr);
|
|
Packit |
8930e1 |
#else
|
|
Packit |
8930e1 |
ret = pthread_rwlock_init(&lock->lock, NULL);
|
|
Packit |
8930e1 |
#endif
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
if (ret) {
|
|
Packit |
8930e1 |
log_err("pthread_rwlock_init: %s\n", strerror(ret));
|
|
Packit |
8930e1 |
goto destroy_attr;
|
|
Packit |
8930e1 |
}
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
pthread_rwlockattr_destroy(&attr);
|
|
Packit |
8930e1 |
|
|
Packit |
8930e1 |
return lock;
|
|
Packit |
8930e1 |
destroy_attr:
|
|
Packit |
8930e1 |
pthread_rwlockattr_destroy(&attr);
|
|
Packit |
8930e1 |
err:
|
|
Packit |
8930e1 |
if (lock)
|
|
Packit |
8930e1 |
fio_rwlock_remove(lock);
|
|
Packit |
8930e1 |
return NULL;
|
|
Packit |
8930e1 |
}
|