12 void __fio_mutex_remove(struct fio_mutex *mutex)
14 assert(mutex->magic == FIO_MUTEX_MAGIC);
15 pthread_cond_destroy(&mutex->cond);
18 * Ensure any subsequent attempt to grab this mutex will fail
19 * with an assert, instead of just silently hanging.
21 memset(mutex, 0, sizeof(*mutex));
24 void fio_mutex_remove(struct fio_mutex *mutex)
26 __fio_mutex_remove(mutex);
27 munmap((void *) mutex, sizeof(*mutex));
30 int __fio_mutex_init(struct fio_mutex *mutex, int value)
35 mutex->magic = FIO_MUTEX_MAGIC;
37 ret = mutex_cond_init_pshared(&mutex->lock, &mutex->cond);
44 struct fio_mutex *fio_mutex_init(int value)
46 struct fio_mutex *mutex = NULL;
48 mutex = (void *) mmap(NULL, sizeof(struct fio_mutex),
49 PROT_READ | PROT_WRITE,
50 OS_MAP_ANON | MAP_SHARED, -1, 0);
51 if (mutex == MAP_FAILED) {
56 if (!__fio_mutex_init(mutex, value))
59 fio_mutex_remove(mutex);
63 static bool mutex_timed_out(struct timespec *t, unsigned int msecs)
68 gettimeofday(&tv, NULL);
69 now.tv_sec = tv.tv_sec;
70 now.tv_nsec = tv.tv_usec * 1000;
72 return mtime_since(t, &now) >= msecs;
75 int fio_mutex_down_timeout(struct fio_mutex *mutex, unsigned int msecs)
82 assert(mutex->magic == FIO_MUTEX_MAGIC);
84 gettimeofday(&tv_s, NULL);
85 base.tv_sec = t.tv_sec = tv_s.tv_sec;
86 base.tv_nsec = t.tv_nsec = tv_s.tv_usec * 1000;
88 t.tv_sec += msecs / 1000;
89 t.tv_nsec += ((msecs * 1000000ULL) % 1000000000);
90 if (t.tv_nsec >= 1000000000) {
91 t.tv_nsec -= 1000000000;
95 pthread_mutex_lock(&mutex->lock);
98 while (!mutex->value && !ret) {
100 * Some platforms (FreeBSD 9?) seems to return timed out
101 * way too early, double check.
103 ret = pthread_cond_timedwait(&mutex->cond, &mutex->lock, &t);
104 if (ret == ETIMEDOUT && !mutex_timed_out(&base, msecs))
111 pthread_mutex_unlock(&mutex->lock);
115 pthread_mutex_unlock(&mutex->lock);
119 bool fio_mutex_down_trylock(struct fio_mutex *mutex)
123 assert(mutex->magic == FIO_MUTEX_MAGIC);
125 pthread_mutex_lock(&mutex->lock);
130 pthread_mutex_unlock(&mutex->lock);
135 void fio_mutex_down(struct fio_mutex *mutex)
137 assert(mutex->magic == FIO_MUTEX_MAGIC);
139 pthread_mutex_lock(&mutex->lock);
141 while (!mutex->value) {
143 pthread_cond_wait(&mutex->cond, &mutex->lock);
148 pthread_mutex_unlock(&mutex->lock);
151 void fio_mutex_up(struct fio_mutex *mutex)
155 assert(mutex->magic == FIO_MUTEX_MAGIC);
157 pthread_mutex_lock(&mutex->lock);
159 if (!mutex->value && mutex->waiters)
164 pthread_cond_signal(&mutex->cond);
166 pthread_mutex_unlock(&mutex->lock);