Fio 1.18
[fio.git] / mutex.c
CommitLineData
07739b57
JA
1#include <stdio.h>
2#include <string.h>
3#include <unistd.h>
4#include <stdlib.h>
5#include <fcntl.h>
6#include <pthread.h>
7#include <sys/mman.h>
8
9#include "mutex.h"
10
11void fio_sem_remove(struct fio_sem *sem)
12{
f7c9e00e 13 close(sem->sem_fd);
07739b57
JA
14 munmap(sem, sizeof(*sem));
15}
16
17struct fio_sem *fio_sem_init(int value)
18{
f7c9e00e 19 char sem_name[] = "/tmp/.fio_sem.XXXXXX";
e53bd0b3 20 struct fio_sem *sem = NULL;
07739b57 21 pthread_mutexattr_t attr;
108fcc11 22 pthread_condattr_t cond;
07739b57
JA
23 int fd;
24
07739b57
JA
25 fd = mkstemp(sem_name);
26 if (fd < 0) {
27 perror("open sem");
28 return NULL;
29 }
30
31 if (ftruncate(fd, sizeof(struct fio_sem)) < 0) {
32 perror("ftruncate sem");
e53bd0b3 33 goto err;
07739b57
JA
34 }
35
36 sem = mmap(NULL, sizeof(struct fio_sem), PROT_READ | PROT_WRITE,
37 MAP_SHARED, fd, 0);
38 if (sem == MAP_FAILED) {
39 perror("mmap sem");
40 close(fd);
e53bd0b3
JA
41 sem = NULL;
42 goto err;
07739b57
JA
43 }
44
f7c9e00e
JA
45 unlink(sem_name);
46 sem->sem_fd = fd;
07739b57 47 sem->value = value;
07739b57
JA
48
49 if (pthread_mutexattr_init(&attr)) {
50 perror("pthread_mutexattr_init");
51 goto err;
52 }
53 if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
54 perror("pthread_mutexattr_setpshared");
55 goto err;
56 }
108fcc11
ZY
57
58 pthread_condattr_init(&cond);
59 pthread_condattr_setpshared(&cond, PTHREAD_PROCESS_SHARED);
60 pthread_cond_init(&sem->cond, &cond);
61
07739b57
JA
62 if (pthread_mutex_init(&sem->lock, &attr)) {
63 perror("pthread_mutex_init");
64 goto err;
65 }
66
67 return sem;
68err:
e53bd0b3 69 if (sem)
f7c9e00e
JA
70 fio_sem_remove(sem);
71
07739b57
JA
72 unlink(sem_name);
73 return NULL;
74}
75
76void fio_sem_down(struct fio_sem *sem)
77{
78 pthread_mutex_lock(&sem->lock);
79 while (sem->value == 0)
80 pthread_cond_wait(&sem->cond, &sem->lock);
81 sem->value--;
82 pthread_mutex_unlock(&sem->lock);
83}
84
85void fio_sem_up(struct fio_sem *sem)
86{
87 pthread_mutex_lock(&sem->lock);
88 if (!sem->value)
89 pthread_cond_signal(&sem->cond);
90 sem->value++;
91 pthread_mutex_unlock(&sem->lock);
92}