blob: 17e62c9f5152c0ab29966915b8874a4a1592ce45 [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;
Zhang, Yanmin108fcc12008-02-04 09:17:52 +010022 pthread_condattr_t cond;
Jens Axboe07739b52007-03-08 20:25:46 +010023 int fd;
24
Jens Axboe07739b52007-03-08 20:25:46 +010025 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");
Jens Axboee53bd0b2007-03-08 20:29:11 +010033 goto err;
Jens Axboe07739b52007-03-08 20:25:46 +010034 }
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);
Jens Axboee53bd0b2007-03-08 20:29:11 +010041 sem = NULL;
42 goto err;
Jens Axboe07739b52007-03-08 20:25:46 +010043 }
44
Jens Axboef7c9e002007-03-09 12:40:02 +010045 unlink(sem_name);
46 sem->sem_fd = fd;
Jens Axboe07739b52007-03-08 20:25:46 +010047 sem->value = value;
Jens Axboe07739b52007-03-08 20:25:46 +010048
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 }
Zhang, Yanmin108fcc12008-02-04 09:17:52 +010057
58 pthread_condattr_init(&cond);
59 pthread_condattr_setpshared(&cond, PTHREAD_PROCESS_SHARED);
60 pthread_cond_init(&sem->cond, &cond);
61
Jens Axboe07739b52007-03-08 20:25:46 +010062 if (pthread_mutex_init(&sem->lock, &attr)) {
63 perror("pthread_mutex_init");
64 goto err;
65 }
66
67 return sem;
68err:
Jens Axboee53bd0b2007-03-08 20:29:11 +010069 if (sem)
Jens Axboef7c9e002007-03-09 12:40:02 +010070 fio_sem_remove(sem);
71
Jens Axboe07739b52007-03-08 20:25:46 +010072 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}