X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/blobdiff_plain/08d51720ebbcf7c327d4751d9773c913313588ab..6bcd9f539330a64088a3374717e3cae720498bf7:/src/xbt/parmap.c diff --git a/src/xbt/parmap.c b/src/xbt/parmap.c index 38ca6198a8..fcf8857aff 100644 --- a/src/xbt/parmap.c +++ b/src/xbt/parmap.c @@ -3,9 +3,17 @@ /* This program is free software; you can redistribute it and/or modify it * under the terms of the license (GNU LGPL) which comes with this package. */ +#include "gras_config.h" #include +#ifndef _XBT_WIN32 #include -#include +#endif + +#ifdef HAVE_FUTEX_H + #include +#else + #include "xbt/xbt_os_thread.h" +#endif #include #include "parmap_private.h" @@ -13,10 +21,10 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(xbt_parmap, xbt, "parmap: parallel map"); XBT_LOG_NEW_SUBCATEGORY(xbt_parmap_unit, xbt_parmap, "parmap unit testing"); static void *_xbt_parmap_worker_main(void *parmap); - -static void futex_wait(int *uaddr, int val); -static void futex_wake(int *uaddr, int val); - +#ifdef HAVE_FUTEX_H + static void futex_wait(int *uaddr, int val); + static void futex_wake(int *uaddr, int val); +#endif xbt_parmap_t xbt_parmap_new(unsigned int num_workers) { unsigned int i; @@ -33,7 +41,10 @@ xbt_parmap_t xbt_parmap_new(unsigned int num_workers) xbt_barrier_init(parmap->workers_ready, num_workers + 1); parmap->workers_done = xbt_new0(s_xbt_barrier_t, 1); xbt_barrier_init(parmap->workers_done, num_workers + 1); - +#ifndef HAVE_FUTEX_H + parmap->workers_ready->mutex = xbt_os_mutex_init(); + parmap->workers_ready->cond = xbt_os_cond_init(); +#endif /* Create the pool of worker threads */ for(i=0; i < num_workers; i++){ worker = xbt_os_thread_create(NULL, _xbt_parmap_worker_main, parmap, NULL); @@ -52,7 +63,10 @@ void xbt_parmap_destroy(xbt_parmap_t parmap) xbt_barrier_wait(parmap->workers_ready); DEBUG0("Kill job sent"); xbt_barrier_wait(parmap->workers_done); - +#ifndef HAVE_FUTEX_H + xbt_os_mutex_destroy(parmap->workers_ready->mutex); + xbt_os_cond_destroy(parmap->workers_ready->cond); +#endif xbt_free(parmap->workers_ready); xbt_free(parmap->workers_done); xbt_free(parmap); @@ -121,17 +135,19 @@ static void *_xbt_parmap_worker_main(void *arg) } } -static void futex_wait(int *uaddr, int val) -{ - DEBUG1("Waiting on futex %d", *uaddr); - syscall(SYS_futex, uaddr, FUTEX_WAIT_PRIVATE, val, NULL, NULL, 0); -} +#ifdef HAVE_FUTEX_H + static void futex_wait(int *uaddr, int val) + { + DEBUG1("Waiting on futex %d", *uaddr); + syscall(SYS_futex, uaddr, FUTEX_WAIT_PRIVATE, val, NULL, NULL, 0); + } -static void futex_wake(int *uaddr, int val) -{ - DEBUG1("Waking futex %d", *uaddr); - syscall(SYS_futex, uaddr, FUTEX_WAKE_PRIVATE, val, NULL, NULL, 0); -} + static void futex_wake(int *uaddr, int val) + { + DEBUG1("Waking futex %d", *uaddr); + syscall(SYS_futex, uaddr, FUTEX_WAKE_PRIVATE, val, NULL, NULL, 0); + } +#endif /* Futex based implementation of the barrier */ void xbt_barrier_init(xbt_barrier_t barrier, unsigned int threads_to_wait) @@ -140,21 +156,37 @@ void xbt_barrier_init(xbt_barrier_t barrier, unsigned int threads_to_wait) barrier->thread_count = 0; } -void xbt_barrier_wait(xbt_barrier_t barrier) -{ - int myflag = 0; - unsigned int mycount = 0; - - myflag = barrier->futex; - mycount = __sync_add_and_fetch(&barrier->thread_count, 1); - if(mycount < barrier->threads_to_wait){ - futex_wait(&barrier->futex, myflag); - }else{ - barrier->futex = __sync_add_and_fetch(&barrier->futex, 1); - barrier->thread_count = 0; - futex_wake(&barrier->futex, barrier->threads_to_wait); - } -} +#ifdef HAVE_FUTEX_H + void xbt_barrier_wait(xbt_barrier_t barrier) + { + int myflag = 0; + unsigned int mycount = 0; + + myflag = barrier->futex; + mycount = __sync_add_and_fetch(&barrier->thread_count, 1); + if(mycount < barrier->threads_to_wait){ + futex_wait(&barrier->futex, myflag); + }else{ + barrier->futex = __sync_add_and_fetch(&barrier->futex, 1); + barrier->thread_count = 0; + futex_wake(&barrier->futex, barrier->threads_to_wait); + } + } +#else + void xbt_barrier_wait(xbt_barrier_t barrier) + { + xbt_os_mutex_acquire(barrier->mutex); + + barrier->thread_count++; + if(barrier->thread_count < barrier->threads_to_wait){ + xbt_os_cond_wait(barrier->cond,barrier->mutex); + }else{ + barrier->thread_count = 0; + xbt_os_cond_broadcast(barrier->cond); + } + xbt_os_mutex_release(barrier->mutex); + } +#endif #ifdef SIMGRID_TEST #include "xbt.h"