null engine: update to support queuing
[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;
07739b57
JA
22 int fd;
23
07739b57
JA
24 fd = mkstemp(sem_name);
25 if (fd < 0) {
26 perror("open sem");
27 return NULL;
28 }
29
30 if (ftruncate(fd, sizeof(struct fio_sem)) < 0) {
31 perror("ftruncate sem");
e53bd0b3 32 goto err;
07739b57
JA
33 }
34
35 sem = mmap(NULL, sizeof(struct fio_sem), PROT_READ | PROT_WRITE,
36 MAP_SHARED, fd, 0);
37 if (sem == MAP_FAILED) {
38 perror("mmap sem");
39 close(fd);
e53bd0b3
JA
40 sem = NULL;
41 goto err;
07739b57
JA
42 }
43
f7c9e00e
JA
44 unlink(sem_name);
45 sem->sem_fd = fd;
07739b57 46 sem->value = value;
07739b57
JA
47
48 if (pthread_mutexattr_init(&attr)) {
49 perror("pthread_mutexattr_init");
50 goto err;
51 }
52 if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED)) {
53 perror("pthread_mutexattr_setpshared");
54 goto err;
55 }
56 if (pthread_mutex_init(&sem->lock, &attr)) {
57 perror("pthread_mutex_init");
58 goto err;
59 }
60
61 return sem;
62err:
e53bd0b3 63 if (sem)
f7c9e00e
JA
64 fio_sem_remove(sem);
65
07739b57
JA
66 unlink(sem_name);
67 return NULL;
68}
69
70void fio_sem_down(struct fio_sem *sem)
71{
72 pthread_mutex_lock(&sem->lock);
73 while (sem->value == 0)
74 pthread_cond_wait(&sem->cond, &sem->lock);
75 sem->value--;
76 pthread_mutex_unlock(&sem->lock);
77}
78
79void fio_sem_up(struct fio_sem *sem)
80{
81 pthread_mutex_lock(&sem->lock);
82 if (!sem->value)
83 pthread_cond_signal(&sem->cond);
84 sem->value++;
85 pthread_mutex_unlock(&sem->lock);
86}