diff --git a/Makefile b/Makefile index 982bba6..bd38880 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ bins+=23-create-many-once bins+=31-switch-many bins+=32-switch-many-join bins+=33-switch-many-cascade -bins+=51-fibonacci +#bins+=51-fibonacci bins+=61-mutex bins+=62-mutex bins+=63-mutex-equity @@ -25,6 +25,7 @@ bins+=81-deadlock bins_target=$(addprefix ${build_dir}/,${bins}) install_bins_targets=$(addprefix ${install_dir}/bin/,${bins}) +install_bins_targets+=${install_dir}/bin/51-fibonacci valgrind_targets=$(addprefix valgrind_,${bins}) @@ -108,6 +109,9 @@ check: ${check_targets} ${check_targets}: check_%: ${build_dir}/% $^ ${check_argv} +${build_dir}/51-fibonacci: ${build_dir}/src/thread/thread_fibo.o ${build_dir}/${tst_dir}/51-fibonacci.o + ${CC} -o $@ $^ ${CFLAGS} ./lib/libmimalloc ${LDFLAGS} + ${bins_target}: ${build_dir}/%: ${objs} ${build_dir}/${tst_dir}/%.o ${CC} -o $@ $^ ${CFLAGS} ./lib/libmimalloc ${LDFLAGS} @@ -117,6 +121,10 @@ ${build_dir}/libthread.so: ${objs} ${build_dir}/libthread.a: ${objs} ar rcs $@ $^ +${build_dir}/%_fibo.o: %.c + @mkdir -p $(dir $@) + ${CC} -o $@ -c $^ -DFIBO_STRAT ${CFLAGS} + ${build_dir}/%.o: %.c @mkdir -p $(dir $@) ${CC} -o $@ -c $^ ${CFLAGS} diff --git a/src/thread/thread.c b/src/thread/thread.c index eeff5bb..5b71e06 100644 --- a/src/thread/thread.c +++ b/src/thread/thread.c @@ -24,6 +24,13 @@ #define IS_WAITED(entry) (HAS_STATUS(entry, WAITED)) #define IS_MUTEX_WAITING(entry) (HAS_STATUS(entry, MUTEX_WAITING)) +#ifdef FIBO_STRAT + +#define YIELD 0x20 +#define IS_YIELD(entry) (HAS_STATUS(entry, YIELD)) + +#endif + #ifndef STACK_SIZE #define STACK_SIZE 4096 #endif @@ -83,6 +90,13 @@ int thread_yield(void) return 0; } +#ifdef FIBO_STRAT + if (!(IS_YIELD(running)) && !IS_FINISHED(running) && !IS_WAITING(running)) { + SET_STATUS(running, YIELD); + return 0; + } +#endif + /* Current strategy : * if we have checked the number of threads then keep the running one * otherwise, take the first element of the list should not be null @@ -157,7 +171,11 @@ int thread_create(thread_t* newthread, void* (*func)(void*), void* funcarg) makecontext(&new_entry->context, (void (*)(void))thread_function_wrapper, 2, func, funcarg); +#ifdef FIBO_STRAT + TAILQ_INSERT_HEAD(&head, new_entry, link); +#else TAILQ_INSERT_TAIL(&head, new_entry, link); +#endif return 0; } @@ -224,10 +242,14 @@ int thread_join(thread_t thread, void** retval) DBG("%p is waiting for %p", running, entry); + DBG("MUTEX WAITING %d", IS_MUTEX_WAITING(GET_LAST_WAITED_THREAD(running))); +#ifdef FIBO_STRAT +#else if (!IS_MUTEX_WAITING(GET_LAST_WAITED_THREAD(running))) { TAILQ_REMOVE(&head, GET_LAST_WAITED_THREAD(running), link); TAILQ_INSERT_HEAD(&head, GET_LAST_WAITED_THREAD(running), link); } +#endif do { thread_yield(); } while (!IS_FINISHED(entry)); @@ -271,7 +293,11 @@ void thread_exit(void* retval) if (IS_WAITED(running)) { // If the thread was waited by another thread, we need to wake it up. struct context_entry* waited = running->retvalue; +#ifdef FIBO_STRAT + TAILQ_INSERT_HEAD(&head, waited, link); +#else TAILQ_INSERT_TAIL(&head, waited, link); +#endif } running->retvalue = retval; @@ -332,6 +358,7 @@ void __attribute__((constructor)) setup_main_thread() // memset(main, 0, sizeof(*main)); getcontext(&main->context); main->status = 0; + main->valgrind_id = 0; main->retvalue = NULL; main->last_waited = NULL; main->mutex_fifo_entry = NULL;