Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
New function: xbt_dynar_dopar(dynar,fun)
authormquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 8 Oct 2009 14:47:18 +0000 (14:47 +0000)
committermquinson <mquinson@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Thu, 8 Oct 2009 14:47:18 +0000 (14:47 +0000)
maps a function over the dynar with one separate thread per value of the dynar.

git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@6747 48e7efb5-ca39-0410-a469-dd3cf9ba447f

ChangeLog
include/xbt/function_types.h
src/Makefile.am
src/xbt/xbt_synchro.c [new file with mode: 0644]

index a532634..8c41c61 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -77,6 +77,9 @@ SimGrid (3.3.4) unstable; urgency=low
  * Update the start_time and finish_time of tasks on completion/failure
  * Bugfix: Remove task from state swags when destroyed
 
  * Update the start_time and finish_time of tasks on completion/failure
  * Bugfix: Remove task from state swags when destroyed
 
+ XBT:
+ * New function: xbt_dynar_dopar(dynar,fun) to map a function over the
+   dynar with one separate thread per value of the dynar.
    
  Bug fixes:
  * GTNetS wrappers should now be usable again (and betterly tested too)
    
  Bug fixes:
  * GTNetS wrappers should now be usable again (and betterly tested too)
index 305d10a..291441d 100644 (file)
@@ -16,8 +16,9 @@
 
 SG_BEGIN_DECL()
 
 
 SG_BEGIN_DECL()
 
-     typedef void (*void_f_ppvoid_t) (void **);
-     typedef void (*void_f_pvoid_t) (void *);
+typedef void (*void_f_ppvoid_t) (void **);
+typedef void (*void_f_pvoid_t) (void *);
+typedef void (*void_f_int_pvoid_t) (int,void *);
      typedef void *(*pvoid_f_void_t) (void);
      typedef void *(*pvoid_f_pvoid_t) (void *);
      typedef void (*void_f_void_t) (void);
      typedef void *(*pvoid_f_void_t) (void);
      typedef void *(*pvoid_f_pvoid_t) (void *);
      typedef void (*void_f_void_t) (void);
index bd30eaa..a1545d4 100644 (file)
@@ -153,7 +153,7 @@ XBT_SRC=\
   xbt/set.c                                                                  \
   xbt/xbt_matrix.c                                                           \
   \
   xbt/set.c                                                                  \
   xbt/xbt_matrix.c                                                           \
   \
-  xbt/xbt_queue.c                                                            \
+  xbt/xbt_queue.c  xbt/xbt_synchro.c                                         \
   \
   xbt/xbt_peer.c                                                             \
   \
   \
   xbt/xbt_peer.c                                                             \
   \
@@ -391,12 +391,12 @@ else
 noinst_PROGRAMS=testall
 TEST_CFILES=xbt/cunit.c  xbt/ex.c          \
             xbt/dynar.c xbt/dict.c xbt/set.c xbt/swag.c \
 noinst_PROGRAMS=testall
 TEST_CFILES=xbt/cunit.c  xbt/ex.c          \
             xbt/dynar.c xbt/dict.c xbt/set.c xbt/swag.c \
-           xbt/xbt_str.c  xbt/xbt_sha.c                \
-            xbt/config.c 
+           xbt/xbt_str.c  xbt/xbt_strbuff.c xbt/xbt_sha.c                \
+            xbt/config.c xbt/xbt_synchro.c
 TEST_UNITS= @builddir@/cunit_unit.c   @builddir@/ex_unit.c         \
             @builddir@/dynar_unit.c   @builddir@/dict_unit.c @builddir@/set_unit.c @builddir@/swag_unit.c \
            @builddir@/xbt_str_unit.c @builddir@/xbt_strbuff_unit.c @builddir@/xbt_sha_unit.c\
 TEST_UNITS= @builddir@/cunit_unit.c   @builddir@/ex_unit.c         \
             @builddir@/dynar_unit.c   @builddir@/dict_unit.c @builddir@/set_unit.c @builddir@/swag_unit.c \
            @builddir@/xbt_str_unit.c @builddir@/xbt_strbuff_unit.c @builddir@/xbt_sha_unit.c\
-            @builddir@/config_unit.c 
+            @builddir@/config_unit.c  @builddir@/xbt_synchro_unit.c
 
 BUILT_SOURCES=../include/surf/simgrid_dtd.h surf/simgrid_dtd.c \
               ../include/xbt/graphxml.h xbt/graphxml.c \
 
 BUILT_SOURCES=../include/surf/simgrid_dtd.h surf/simgrid_dtd.c \
               ../include/xbt/graphxml.h xbt/graphxml.c \
@@ -414,8 +414,7 @@ EXTRA_DIST+=$(testall_SOURCES)
 if MAINTAINER_MODE
 CLEANFILES=$(TEST_UNITS)
 
 if MAINTAINER_MODE
 CLEANFILES=$(TEST_UNITS)
 
-$(TEST_UNITS): xbt/cunit.c xbt/ex.c xbt/xbt_str.c xbt/xbt_strbuff.c xbt/xbt_sha.c\
-               xbt/dynar.c xbt/dict.c xbt/set.c xbt/swag.c xbt/config.c
+$(TEST_UNITS): $(TEST_CFILES)
        @top_srcdir@/tools/sg_unit_extractor.pl $^
 
 @builddir@/simgrid_units_main.c: $(TEST_UNITS)
        @top_srcdir@/tools/sg_unit_extractor.pl $^
 
 @builddir@/simgrid_units_main.c: $(TEST_UNITS)
diff --git a/src/xbt/xbt_synchro.c b/src/xbt/xbt_synchro.c
new file mode 100644 (file)
index 0000000..19de24c
--- /dev/null
@@ -0,0 +1,86 @@
+/* xbt_synchro -- advanced multithreaded features                           */
+/* Working on top of real threads in RL and of simulated processes in SG    */
+
+/* Copyright 2009 Da SimGrid Team. All right reserved.                      */
+
+/* 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 "xbt/sysdep.h"
+#include "xbt/dynar.h"
+#include "xbt/synchro.h"
+
+typedef struct {
+  xbt_dynar_t data;
+  int rank;
+  void_f_int_pvoid_t function;
+  xbt_thread_t worker;
+} s_worker_data_t,*worker_data_t;
+
+static void worker_wait_n_free(void*w) {
+  worker_data_t worker=*(worker_data_t*)w;
+  xbt_thread_join(worker->worker);
+  xbt_free(worker);
+}
+static void worker_wrapper(void *w) {
+  worker_data_t me=(worker_data_t)w;
+  (*me->function)(me->rank,xbt_dynar_get_ptr(me->data,me->rank));
+  xbt_thread_exit();
+}
+
+void xbt_dynar_dopar(xbt_dynar_t datas, void_f_int_pvoid_t function) {
+  xbt_dynar_t workers = xbt_dynar_new(sizeof(worker_data_t),worker_wait_n_free);
+  unsigned int cursor;
+  void *data;
+  /* Start all workers */
+  xbt_dynar_foreach(datas,cursor,data){
+    worker_data_t w = xbt_new0(s_worker_data_t,1);
+    w->data = datas;
+    w->function = function;
+    w->rank=cursor;
+    xbt_dynar_push(workers,&w);
+    w->worker = xbt_thread_create(NULL,worker_wrapper,w);
+  }
+  /* wait them all */
+  xbt_dynar_free(&workers);
+}
+
+#ifdef SIMGRID_TEST
+#define NB_ELEM 50
+#include "xbt/synchro.h"
+
+XBT_TEST_SUITE("synchro", "Advanced synchronization mecanisms");
+XBT_LOG_EXTERNAL_CATEGORY(xbt_dyn);
+XBT_LOG_DEFAULT_CATEGORY(xbt_dyn);
+
+static void add100(int rank,void *data) {
+  //INFO2("Thread%d: Add 100 to %d",rank,*(int*)data);
+  *(int*)data +=100;
+}
+
+XBT_TEST_UNIT("dopar", test_dynar_dopar, "do parallel on dynars of integers")
+{
+  xbt_dynar_t d;
+  int i, cpt;
+  unsigned int cursor;
+
+  xbt_test_add1("==== Push %d int, add 100 to each of them in parallel and check the results", NB_ELEM);
+  d = xbt_dynar_new(sizeof(int), NULL);
+  for (cpt = 0; cpt < NB_ELEM; cpt++) {
+    xbt_dynar_push_as(d, int, cpt);     /* This is faster (and possible only with scalars) */
+    xbt_test_log2("Push %d, length=%lu", cpt, xbt_dynar_length(d));
+  }
+  xbt_dynar_dopar(d,add100);
+  cpt = 100;
+  xbt_dynar_foreach(d, cursor, i) {
+    xbt_test_assert2(i == cpt,
+                     "The retrieved value is not the expected one (%d!=%d)",
+                     i, cpt);
+    cpt++;
+  }
+  xbt_dynar_free(&d);
+}
+
+#endif /* SIMGRID_TEST */
+
+