- pthread_mutex_lock(&mutex->lock);
- mutex->value++;
- read_barrier();
- if (mutex->value >= 0 && mutex->waiters)
- pthread_cond_signal(&mutex->cond);
- pthread_mutex_unlock(&mutex->lock);
+ struct fio_rwlock *lock;
+ pthread_rwlockattr_t attr;
+ int ret;
+
+ lock = (void *) mmap(NULL, sizeof(struct fio_rwlock),
+ PROT_READ | PROT_WRITE,
+ OS_MAP_ANON | MAP_SHARED, -1, 0);
+ if (lock == MAP_FAILED) {
+ perror("mmap rwlock");
+ lock = NULL;
+ goto err;
+ }
+
+ lock->magic = FIO_RWLOCK_MAGIC;
+
+ ret = pthread_rwlockattr_init(&attr);
+ if (ret) {
+ log_err("pthread_rwlockattr_init: %s\n", strerror(ret));
+ goto err;
+ }
+#ifdef FIO_HAVE_PSHARED_MUTEX
+ ret = pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
+ if (ret) {
+ log_err("pthread_rwlockattr_setpshared: %s\n", strerror(ret));
+ goto destroy_attr;
+ }
+
+ ret = pthread_rwlock_init(&lock->lock, &attr);
+#else
+ ret = pthread_rwlock_init(&lock->lock, NULL);
+#endif
+
+ if (ret) {
+ log_err("pthread_rwlock_init: %s\n", strerror(ret));
+ goto destroy_attr;
+ }
+
+ pthread_rwlockattr_destroy(&attr);
+
+ return lock;
+destroy_attr:
+ pthread_rwlockattr_destroy(&attr);
+err:
+ if (lock)
+ fio_rwlock_remove(lock);
+ return NULL;