blob: be3258df8347937a47bf68a99402283d2381b51a [file] [log] [blame]
Jens Axboe07739b52007-03-08 20:25:46 +01001#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{
Jens Axboef7c9e002007-03-09 12:40:02 +010013 close(sem->sem_fd);
Jens Axboe07739b52007-03-08 20:25:46 +010014 munmap(sem, sizeof(*sem));
15}
16
17struct fio_sem *fio_sem_init(int value)
18{
Jens Axboef7c9e002007-03-09 12:40:02 +010019 char sem_name[] = "/tmp/.fio_sem.XXXXXX";
Jens Axboee53bd0b2007-03-08 20:29:11 +010020 struct fio_sem *sem = NULL;
Jens Axboe07739b52007-03-08 20:25:46 +010021 pthread_mutexattr_t attr;
Jens Axboe07739b52007-03-08 20:25:46 +010022 int fd;
23
Jens Axboe07739b52007-03-08 20:25:46 +010024 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");
Jens Axboee53bd0b2007-03-08 20:29:11 +010032 goto err;
Jens Axboe07739b52007-03-08 20:25:46 +010033 }
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);
Jens Axboee53bd0b2007-03-08 20:29:11 +010040 sem = NULL;
41 goto err;
Jens Axboe07739b52007-03-08 20:25:46 +010042 }
43
Jens Axboef7c9e002007-03-09 12:40:02 +010044 unlink(sem_name);
45 sem->sem_fd = fd;
Jens Axboe07739b52007-03-08 20:25:46 +010046 sem->value = value;
Jens Axboe07739b52007-03-08 20:25:46 +010047
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:
Jens Axboee53bd0b2007-03-08 20:29:11 +010063 if (sem)
Jens Axboef7c9e002007-03-09 12:40:02 +010064 fio_sem_remove(sem);
65
Jens Axboe07739b52007-03-08 20:25:46 +010066 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}