From b402c05504f22a553f2df8154928410f2a446972 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 9 Mar 2006 13:39:23 +0000 Subject: [PATCH] fix futex git-svn-id: http://ltt.polymtl.ca/svn@1625 04897980-b3bd-0310-b5e0-8ef037075253 --- usertrace-fast/Makefile | 8 ++- usertrace-fast/ltt-usertrace-fast.c | 82 +++++++++++-------------- usertrace-fast/ltt/ltt-usertrace-fast.h | 57 ++++++++--------- 3 files changed, 69 insertions(+), 78 deletions(-) diff --git a/usertrace-fast/Makefile b/usertrace-fast/Makefile index 2dafe002..7430a3b4 100644 --- a/usertrace-fast/Makefile +++ b/usertrace-fast/Makefile @@ -6,9 +6,10 @@ RANLIB=ranlib CC=gcc CFLAGS=-I. -O3 -CFLAGS+=-DLTT_SUBBUF_SIZE_CPU=134217728 +#CFLAGS+=-DLTT_SUBBUF_SIZE_CPU=134217728 +CFLAGS+=-DLTT_NULL_OUTPUT_TEST -all: test sample-instrument-fct libltt-instrument-functions.a libltt-instrument-functions.so.0 +all: test sample-instrument-fct libltt-instrument-functions.a libltt-instrument-functions.so.0 sample-loop test: test.c ltt-usertrace-fast.c $(CC) $(CFLAGS) -I. -lpthread -o $@ $^ @@ -17,6 +18,9 @@ test: test.c ltt-usertrace-fast.c sample-instrument-fct: sample-instrument-fct.c $(CC) $(CFLAGS) -L. -g -finstrument-functions -lltt-instrument-functions -o $@ $^ +sample-loop: sample-loop.c ltt-usertrace-fast.o ltt-facility-loader-user_generic.o + $(CC) $(CFLAGS) -L. -lpthread -g -o $@ $^ + libltt-instrument-functions.a: ltt-instrument-functions.o ltt-facility-loader-user_generic.o ltt-usertrace-fast.o @rm -f libltt-instrument-functions.a $(AR) rc $@ $^ diff --git a/usertrace-fast/ltt-usertrace-fast.c b/usertrace-fast/ltt-usertrace-fast.c index 159c00df..d722460b 100644 --- a/usertrace-fast/ltt-usertrace-fast.c +++ b/usertrace-fast/ltt-usertrace-fast.c @@ -319,14 +319,14 @@ static inline int ltt_buffer_put(struct ltt_buf *ltt_buf, * It can also happen if this is a buffer we never got. */ return -EIO; } else { - if(atomic_read(<t_buf->full) == 1) { + if(atomic_inc_return(<t_buf->writer_futex) <= 0) { + atomic_set(<t_buf->writer_futex, 1); /* tell the client that buffer is now unfull */ - ret = futex((unsigned long)<t_buf->full, + ret = futex((unsigned long)<t_buf->writer_futex, FUTEX_WAKE, 1, 0, 0, 0); if(ret != 1) { dbg_printf("LTT warning : race condition : writer not waiting or too many writers\n"); } - atomic_set(<t_buf->full, 0); } } } @@ -382,8 +382,7 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info, { struct sigaction act; int ret; - int fd_fac; - int fd_cpu; + int fd_process; char outfile_name[PATH_MAX]; char identifier_name[PATH_MAX]; @@ -434,12 +433,20 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info, } snprintf(identifier_name, PATH_MAX-1, "%lu.%lu.%llu", traced_tid, traced_pid, get_cycles()); - snprintf(outfile_name, PATH_MAX-1, "facilities-%s", identifier_name); - fd_fac = creat(outfile_name, 0644); - - snprintf(outfile_name, PATH_MAX-1, "cpu-%s", identifier_name); - fd_cpu = creat(outfile_name, 0644); - + snprintf(outfile_name, PATH_MAX-1, "process-%s", identifier_name); +#ifndef LTT_NULL_OUTPUT_TEST + fd_process = creat(outfile_name, 0644); +#else + /* NULL test */ + ret = symlink("/dev/null", outfile_name); + if(ret < 0) { + perror("error in symlink"); + } + fd_process = open(outfile_name, O_WRONLY); + if(fd_process < 0) { + perror("Error in open"); + } +#endif //LTT_NULL_OUTPUT_TEST while(1) { pause(); @@ -448,11 +455,7 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info, dbg_printf("LTT Doing a buffer switch read. pid is : %lu\n", getpid()); do { - ret = read_subbuffer(&shared_trace_info->channel.cpu, fd_cpu); - } while(ret == 0); - - do { - ret = read_subbuffer(&shared_trace_info->channel.facilities, fd_fac); + ret = read_subbuffer(&shared_trace_info->channel.process, fd_process); } while(ret == 0); } @@ -460,19 +463,13 @@ static void ltt_usertrace_fast_daemon(struct ltt_trace_info *shared_trace_info, /* Buffer force switch (flush). Using FLUSH instead of ACTIVE because we know * there is no writer. */ - flush_buffer(&shared_trace_info->channel.cpu, FORCE_FLUSH); + flush_buffer(&shared_trace_info->channel.process, FORCE_FLUSH); do { - ret = read_subbuffer(&shared_trace_info->channel.cpu, fd_cpu); + ret = read_subbuffer(&shared_trace_info->channel.process, fd_process); } while(ret == 0); - flush_buffer(&shared_trace_info->channel.facilities, FORCE_FLUSH); - do { - ret = read_subbuffer(&shared_trace_info->channel.facilities, fd_fac); - } while(ret == 0); - - close(fd_fac); - close(fd_cpu); + close(fd_process); munmap(shared_trace_info, sizeof(*shared_trace_info)); @@ -502,25 +499,16 @@ void ltt_rw_init(void) shared_trace_info->filter=0; shared_trace_info->daemon_id=0; shared_trace_info->nesting=0; - memset(&shared_trace_info->channel.facilities, 0, - sizeof(shared_trace_info->channel.facilities)); - memset(&shared_trace_info->channel.cpu, 0, - sizeof(shared_trace_info->channel.cpu)); + memset(&shared_trace_info->channel.process, 0, + sizeof(shared_trace_info->channel.process)); /* Tricky semaphore : is in a shared memory space, so it's ok for a fast * mutex (futex). */ - atomic_set(&shared_trace_info->channel.facilities.full, 0); - shared_trace_info->channel.facilities.alloc_size = LTT_BUF_SIZE_FACILITIES; - shared_trace_info->channel.facilities.subbuf_size = LTT_SUBBUF_SIZE_FACILITIES; - shared_trace_info->channel.facilities.start = - shared_trace_info->channel.facilities_buf; - ltt_buffer_begin_callback(&shared_trace_info->channel.facilities, - ltt_get_timestamp(), 0); - - atomic_set(&shared_trace_info->channel.cpu.full, 0); - shared_trace_info->channel.cpu.alloc_size = LTT_BUF_SIZE_CPU; - shared_trace_info->channel.cpu.subbuf_size = LTT_SUBBUF_SIZE_CPU; - shared_trace_info->channel.cpu.start = shared_trace_info->channel.cpu_buf; - ltt_buffer_begin_callback(&shared_trace_info->channel.cpu, + atomic_set(&shared_trace_info->channel.process.writer_futex, LTT_N_SUBBUFS); + shared_trace_info->channel.process.alloc_size = LTT_BUF_SIZE_PROCESS; + shared_trace_info->channel.process.subbuf_size = LTT_SUBBUF_SIZE_PROCESS; + shared_trace_info->channel.process.start = + shared_trace_info->channel.process_buf; + ltt_buffer_begin_callback(&shared_trace_info->channel.process, ltt_get_timestamp(), 0); shared_trace_info->init = 1; @@ -553,10 +541,12 @@ void ltt_rw_init(void) /* Child */ role = LTT_ROLE_READER; sid = setsid(); - ret = nice(1); - if(ret < 0) { - perror("Error in nice"); - } + //Not a good idea to renice, unless futex wait eventually implement + //priority inheritence. + //ret = nice(1); + //if(ret < 0) { + // perror("Error in nice"); + //} if(sid < 0) { perror("Error setting sid"); } diff --git a/usertrace-fast/ltt/ltt-usertrace-fast.h b/usertrace-fast/ltt/ltt-usertrace-fast.h index a175d895..77e0594f 100644 --- a/usertrace-fast/ltt/ltt-usertrace-fast.h +++ b/usertrace-fast/ltt/ltt-usertrace-fast.h @@ -33,17 +33,11 @@ static inline __attribute__((no_instrument_function)) #define LTT_N_SUBBUFS 2 #endif //LTT_N_SUBBUFS -#ifndef LTT_SUBBUF_SIZE_CPU -#define LTT_SUBBUF_SIZE_CPU 1048576 +#ifndef LTT_SUBBUF_SIZE_PROCESS +#define LTT_SUBBUF_SIZE_PROCESS 1048576 #endif //LTT_BUF_SIZE_CPU -#define LTT_BUF_SIZE_CPU (LTT_SUBBUF_SIZE_CPU * LTT_N_SUBBUFS) - -#ifndef LTT_SUBBUF_SIZE_FACILITIES -#define LTT_SUBBUF_SIZE_FACILITIES 4096 -#endif //LTT_BUF_SIZE_FACILITIES - -#define LTT_BUF_SIZE_FACILITIES (LTT_SUBBUF_SIZE_FACILITIES * LTT_N_SUBBUFS) +#define LTT_BUF_SIZE_PROCESS (LTT_SUBBUF_SIZE_PROCESS * LTT_N_SUBBUFS) #ifndef LTT_USERTRACE_ROOT #define LTT_USERTRACE_ROOT "/tmp/ltt-usertrace" @@ -118,7 +112,7 @@ struct ltt_buf { atomic_t events_lost; atomic_t corrupted_subbuffers; - atomic_t full; /* futex on which the writer waits : 1 : full */ + atomic_t writer_futex; /* futex on which the writer waits */ unsigned int alloc_size; unsigned int subbuf_size; }; @@ -129,10 +123,8 @@ struct ltt_trace_info { pid_t daemon_id; int nesting; struct { - struct ltt_buf facilities; - struct ltt_buf cpu; - char facilities_buf[LTT_BUF_SIZE_FACILITIES] __attribute__ ((aligned (8))); - char cpu_buf[LTT_BUF_SIZE_CPU] __attribute__ ((aligned (8))); + struct ltt_buf process; + char process_buf[LTT_BUF_SIZE_PROCESS] __attribute__ ((aligned (8))); } channel; }; @@ -171,7 +163,7 @@ static inline unsigned int __attribute__((no_instrument_function)) ltt_get_index_from_facility(ltt_facility_t fID, uint8_t eID) { - return GET_CHANNEL_INDEX(cpu); + return GET_CHANNEL_INDEX(process); } @@ -423,23 +415,28 @@ static inline void * __attribute__((no_instrument_function)) ltt_reserve_slot( ltt_buf)]); if(reserve_commit_diff == 0) { /* Next buffer not corrupted. */ - if((SUBBUF_TRUNC(offset_begin, ltt_buf) - - SUBBUF_TRUNC(atomic_read(<t_buf->consumed), ltt_buf)) - >= ltt_buf->alloc_size) { - /* We block until the reader unblocks us */ - atomic_set(<t_buf->full, 1); - /* We block until the reader tells us to wake up. - Signals will simply cause this loop to restart. - */ - do { - ret = futex((unsigned long)<t_buf->full, FUTEX_WAIT, 1, 0, 0, 0); - } while(ret != 0 && ret != EWOULDBLOCK); + //if((SUBBUF_TRUNC(offset_begin, ltt_buf) + // - SUBBUF_TRUNC(atomic_read(<t_buf->consumed), ltt_buf)) + // >= ltt_buf->alloc_size) { + if(atomic_dec_return(<t_buf->writer_futex) >= 0) { + /* non contended */ + } else { + /* We block until the reader unblocks us */ + atomic_set(<t_buf->writer_futex, -1); + /* We block until the reader tells us to wake up. + Signals will simply cause this loop to restart. + */ + do { + ret = futex((unsigned long)<t_buf->writer_futex, + FUTEX_WAIT, -1, 0, 0, 0); + } while(ret != 0 && ret != EWOULDBLOCK); + } /* go on with the write */ - } else { - /* next buffer not corrupted, we are either in overwrite mode or - * the buffer is not full. It's safe to write in this new subbuffer.*/ - } + //} else { + // /* next buffer not corrupted, we are either in overwrite mode or + // * the buffer is not full. It's safe to write in this new subbuffer.*/ + //} } else { /* Next subbuffer corrupted. Force pushing reader even in normal * mode. It's safe to write in this new subbuffer. */ -- 2.34.1