5 #ifdef CONFIG_VALGRIND_DEV
6 #include <valgrind/valgrind.h>
8 #define RUNNING_ON_VALGRIND 0
17 void __fio_sem_remove(struct fio_sem *sem)
19 assert(sem->magic == FIO_SEM_MAGIC);
20 pthread_mutex_destroy(&sem->lock);
21 pthread_cond_destroy(&sem->cond);
24 * When not running on Valgrind, ensure any subsequent attempt to grab
25 * this semaphore will fail with an assert, instead of just silently
26 * hanging. When running on Valgrind, let Valgrind detect
29 if (!RUNNING_ON_VALGRIND)
30 memset(sem, 0, sizeof(*sem));
33 void fio_sem_remove(struct fio_sem *sem)
35 __fio_sem_remove(sem);
36 munmap((void *) sem, sizeof(*sem));
39 int __fio_sem_init(struct fio_sem *sem, int value)
44 /* Initialize .waiters explicitly for Valgrind. */
46 sem->magic = FIO_SEM_MAGIC;
48 ret = mutex_cond_init_pshared(&sem->lock, &sem->cond);
55 struct fio_sem *fio_sem_init(int value)
57 struct fio_sem *sem = NULL;
59 sem = (void *) mmap(NULL, sizeof(struct fio_sem),
60 PROT_READ | PROT_WRITE,
61 OS_MAP_ANON | MAP_SHARED, -1, 0);
62 if (sem == MAP_FAILED) {
63 perror("mmap semaphore");
67 if (!__fio_sem_init(sem, value))
74 static bool sem_timed_out(struct timespec *t, unsigned int msecs)
79 gettimeofday(&tv, NULL);
80 now.tv_sec = tv.tv_sec;
81 now.tv_nsec = tv.tv_usec * 1000;
83 return mtime_since(t, &now) >= msecs;
86 int fio_sem_down_timeout(struct fio_sem *sem, unsigned int msecs)
93 assert(sem->magic == FIO_SEM_MAGIC);
95 gettimeofday(&tv_s, NULL);
96 base.tv_sec = t.tv_sec = tv_s.tv_sec;
97 base.tv_nsec = t.tv_nsec = tv_s.tv_usec * 1000;
99 t.tv_sec += msecs / 1000;
100 t.tv_nsec += ((msecs * 1000000ULL) % 1000000000);
101 if (t.tv_nsec >= 1000000000) {
102 t.tv_nsec -= 1000000000;
106 pthread_mutex_lock(&sem->lock);
109 while (!sem->value && !ret) {
111 * Some platforms (FreeBSD 9?) seems to return timed out
112 * way too early, double check.
114 ret = pthread_cond_timedwait(&sem->cond, &sem->lock, &t);
115 if (ret == ETIMEDOUT && !sem_timed_out(&base, msecs))
122 pthread_mutex_unlock(&sem->lock);
126 pthread_mutex_unlock(&sem->lock);
130 bool fio_sem_down_trylock(struct fio_sem *sem)
134 assert(sem->magic == FIO_SEM_MAGIC);
136 pthread_mutex_lock(&sem->lock);
141 pthread_mutex_unlock(&sem->lock);
146 void fio_sem_down(struct fio_sem *sem)
148 assert(sem->magic == FIO_SEM_MAGIC);
150 pthread_mutex_lock(&sem->lock);
152 while (!sem->value) {
154 pthread_cond_wait(&sem->cond, &sem->lock);
159 pthread_mutex_unlock(&sem->lock);
162 void fio_sem_up(struct fio_sem *sem)
166 assert(sem->magic == FIO_SEM_MAGIC);
168 pthread_mutex_lock(&sem->lock);
170 if (!sem->value && sem->waiters)
175 pthread_cond_signal(&sem->cond);
177 pthread_mutex_unlock(&sem->lock);