[PATCH] Easy process shared semaphores
authorJens Axboe <axboe@suse.de>
Wed, 7 Jun 2006 17:42:54 +0000 (19:42 +0200)
committerJens Axboe <axboe@suse.de>
Wed, 7 Jun 2006 17:42:54 +0000 (19:42 +0200)
We really need a pshared semaphore, but those aren't always available.
Just implement a cruddy local semaphore type, fio only really needs
to signal start/stop conditions.

README
fio.c
fio.h
init.c

diff --git a/README b/README
index d27ee87..3240b65 100644 (file)
--- a/README
+++ b/README
@@ -25,6 +25,17 @@ can find them here:
 http://linux01.gwdg.de/~pbleser/rpm-navigation.php?cat=System/fio
 
 
+Building
+--------
+
+Just type 'make' and 'make install'. If on FreeBSD, for now you have to
+specify the FreeBSD Makefile with -f, eg:
+
+$ make -f Makefile.Freebsd && make -f Makefile.FreeBSD install
+
+This might change in the future if I opt for an autoconf type setup.
+
+
 Options
 -------
 
diff --git a/fio.c b/fio.c
index 09c960f..ccf0ad8 100644 (file)
--- a/fio.c
+++ b/fio.c
@@ -63,7 +63,7 @@ enum {
 
 #define should_fsync(td)       ((td_write(td) || td_rw(td)) && (!(td)->odirect || (td)->override_sync))
 
-static sem_t startup_sem;
+static volatile int startup_sem;
 
 #define TERMINATE_ALL          (-1)
 #define JOB_START_TIMEOUT      (5 * 1000)
@@ -1336,8 +1336,8 @@ static void *thread_main(void *data)
                goto err;
 
        td_set_runstate(td, TD_INITIALIZED);
-       sem_post(&startup_sem);
-       sem_wait(&td->mutex);
+       fio_sem_up(&startup_sem);
+       fio_sem_down(&td->mutex);
 
        if (!td->create_serialize && setup_file(td))
                goto err;
@@ -1788,7 +1788,7 @@ static void run_threads(void)
                         */
                        td_set_runstate(td, TD_CREATED);
                        map[this_jobs++] = td;
-                       sem_init(&startup_sem, 0, 1);
+                       fio_sem_init(&startup_sem, 1);
                        nr_started++;
 
                        if (td->use_thread) {
@@ -1798,7 +1798,7 @@ static void run_threads(void)
                                }
                        } else {
                                if (fork())
-                                       sem_wait(&startup_sem);
+                                       fio_sem_down(&startup_sem);
                                else {
                                        fork_main(shm_id, i);
                                        exit(0);
@@ -1862,7 +1862,7 @@ static void run_threads(void)
                        m_rate += td->ratemin;
                        t_rate += td->rate;
                        todo--;
-                       sem_post(&td->mutex);
+                       fio_sem_up(&td->mutex);
                }
 
                reap_threads(&nr_running, &t_rate, &m_rate);
diff --git a/fio.h b/fio.h
index 0b25bb8..09e56d6 100644 (file)
--- a/fio.h
+++ b/fio.h
@@ -6,7 +6,6 @@
 #include <pthread.h>
 #include <sys/time.h>
 #include <sys/resource.h>
-#include <semaphore.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
@@ -205,7 +204,7 @@ struct thread_data {
        unsigned long long zone_bytes;
        unsigned long long this_io_bytes[2];
        unsigned long long last_pos;
-       sem_t mutex;
+       volatile int mutex;
 
        os_random_state_t random_state;
        unsigned long *file_map;
@@ -391,4 +390,28 @@ extern void rate_throttle(struct thread_data *, unsigned long, unsigned int);
 extern int parse_options(int, char **);
 extern int init_random_state(struct thread_data *);
 
+/*
+ * This is a pretty crappy semaphore implementation, but with the use that fio
+ * has (just signalling start/go conditions), it doesn't have to be better.
+ * Naturally this would not work for any type of contended semaphore or
+ * for real locking.
+ */
+static inline void fio_sem_init(volatile int volatile *sem, int val)
+{
+       *sem = val;
+}
+
+static inline void fio_sem_down(volatile int volatile *sem)
+{
+       while (*sem == 0)
+               usleep(10000);
+
+       (*sem)--;
+}
+
+static inline void fio_sem_up(volatile int volatile *sem)
+{
+       (*sem)++;
+}
+
 #endif
diff --git a/init.c b/init.c
index 2c6c820..8c6b2e1 100644 (file)
--- a/init.c
+++ b/init.c
@@ -174,7 +174,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num)
        } else
                strncpy(td->file_name, jobname, sizeof(td->file_name) - 1);
 
-       sem_init(&td->mutex, 0, 0);
+       fio_sem_init(&td->mutex, 0);
 
        td->clat_stat[0].min_val = td->clat_stat[1].min_val = ULONG_MAX;
        td->slat_stat[0].min_val = td->slat_stat[1].min_val = ULONG_MAX;