Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add MSG_process_join [#13601]
authorPaul Bédaride <paul.bedaride@gmail.com>
Fri, 25 Apr 2014 12:52:03 +0000 (14:52 +0200)
committerPaul Bédaride <paul.bedaride@gmail.com>
Fri, 25 Apr 2014 12:54:20 +0000 (14:54 +0200)
28 files changed:
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/MakeExe.cmake
include/msg/msg.h
include/simgrid/simix.h
src/msg/instr_msg_process.c
src/msg/msg_private.h
src/msg/msg_process.c
src/simix/simcalls.in
src/simix/simcalls_generated_args_getter_setter.h
src/simix/simcalls_generated_body.c
src/simix/simcalls_generated_case.c
src/simix/simcalls_generated_enum.h
src/simix/simcalls_generated_res_getter_setter.h
src/simix/simcalls_generated_string.c
src/simix/smx_global.c
src/simix/smx_private.h
src/simix/smx_process.c
src/simix/smx_process_private.h
src/simix/smx_smurf.c
src/simix/smx_user.c
teshsuite/msg/pid.c
teshsuite/msg/process_join/CMakeLists.txt [new file with mode: 0644]
teshsuite/msg/process_join/process_join.c [new file with mode: 0644]
teshsuite/msg/process_join/process_join.tesh [new file with mode: 0644]
teshsuite/msg/process_join/process_join_d.xml [new file with mode: 0644]
teshsuite/msg/process_join/process_join_p.xml [new file with mode: 0644]
teshsuite/msg/process_join/process_log [new file with mode: 0644]

index c48c890..e27775b 100644 (file)
@@ -270,6 +270,14 @@ if(NOT enable_memcheck)
     ADD_TEST(msg-energy-concurrent-tasks-raw    ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/energy/e3/concurrent_tasks.tesh)
   endif()
 
+  ADD_TEST(msg-process-join-thread              ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join --cd ${CMAKE_BINARY_DIR}/teshsuite/msg/process_join ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join/process_join.tesh)
+  if(CONTEXT_UCONTEXT)
+    ADD_TEST(msg-process-join-ucontext          ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join --cd ${CMAKE_BINARY_DIR}/teshsuite/msg/process_join ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join/process_join.tesh)
+  endif()
+  if(HAVE_RAWCTX)
+    ADD_TEST(msg-process-join-raw               ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join --cd ${CMAKE_BINARY_DIR}/teshsuite/msg/process_join ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join/process_join.tesh)
+  endif()
+
   ADD_TEST(msg-storage-basic-thread                   ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/storage/storage_basic.tesh)
   if(CONTEXT_UCONTEXT)
     ADD_TEST(msg-storage-basic-ucontext               ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite --cd ${CMAKE_BINARY_DIR}/teshsuite ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/storage/storage_basic.tesh)
@@ -318,7 +326,6 @@ if(NOT enable_memcheck)
     ADD_TEST(msg-bittorrent-ucontext-parallel   ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/nthreads:4 ${CONTEXTS_SYNCHRO} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/bittorrent --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/bittorrent bittorrent.tesh)
     ADD_TEST(msg-kademlia-ucontext              ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/kademlia --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia kademlia.tesh)
     ADD_TEST(msg-kademlia-ucontext-parallel     ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/nthreads:4 ${CONTEXTS_SYNCHRO} --cfg contexts/factory:ucontext --setenv bindir=${CMAKE_BINARY_DIR}/examples/msg/kademlia --cd ${CMAKE_HOME_DIRECTORY}/examples/msg/kademlia kademlia.tesh)
-
   endif()
   if(HAVE_RAWCTX)
     ADD_TEST(msg-migration-raw                  ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:raw --setenv srcdir=${CMAKE_HOME_DIRECTORY}/examples/msg --cd ${CMAKE_BINARY_DIR}/examples/msg ${CMAKE_HOME_DIRECTORY}/examples/msg/migration/migration.tesh)
@@ -444,11 +451,11 @@ if(NOT enable_memcheck)
     ADD_TEST(smpi-struct-thread                 ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/struct.tesh)
     ADD_TEST(smpi-pt2pt-thread                  ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/pt2pt.tesh)
     ADD_TEST(smpi-compute-thread                ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/compute.tesh)
-    
+
     # https://gforge.inria.fr/tracker/index.php?func=detail&aid=17132&group_id=12&atid=165
     ADD_TEST(smpi-bug-17132                     ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/bug-17132 --cd ${CMAKE_BINARY_DIR}/teshsuite/bug-17132 ${CMAKE_HOME_DIRECTORY}/teshsuite/bug-17132/bug-17132.tesh)
     ADD_TEST(smpi-bug-17132-surf-debug          ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/bug-17132 --cd ${CMAKE_BINARY_DIR}/teshsuite/bug-17132 ${CMAKE_HOME_DIRECTORY}/teshsuite/bug-17132/bug-17132-surf-debug.tesh)
-    
+
     if (NOT WIN32)
       ADD_TEST(smpi-shared-thread               ${TESH_COMMAND} ${TESH_OPTION} --cfg contexts/factory:thread --setenv srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi --cd ${CMAKE_BINARY_DIR}/teshsuite/smpi ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/shared.tesh)
     endif()
@@ -579,7 +586,17 @@ if(NOT enable_memcheck)
     ADD_TEST(smpi-mpich3-coll-ompi-thread       ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/coll perl ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/coll -tests=testlist -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/coll_selector:ompi -execarg=--cfg=smpi/send_is_detached_thres:0 -execarg=--cfg=smpi/privatize_global_variables:yes)
     ADD_TEST(smpi-mpich3-coll-mpich-thread      ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/coll perl ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/coll -tests=testlist -execarg=--cfg=contexts/factory:thread -execarg=--cfg=smpi/coll_selector:mpich -execarg=--cfg=smpi/privatize_global_variables:yes)
     set_tests_properties(smpi-mpich3-coll-thread smpi-mpich3-coll-ompi-thread smpi-mpich3-coll-mpich-thread PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
-    
+<<<<<<< HEAD
+
+||||||| merged common ancestors
+
+    ADD_TEST(smpi-mpich3-topo-raw            ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/topo perl ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/topo -tests=testlist -execarg=--cfg=contexts/factory:raw)
+      set_tests_properties(smpi-mpich3-topo-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
+=======
+
+    ADD_TEST(smpi-mpich3-topo-raw            ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/topo perl ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/topo -tests=testlist -execarg=--cfg=contexts/factory:raw)
+      set_tests_properties(smpi-mpich3-topo-raw PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
+>>>>>>> Add MSG_process_join [#13601]
     if(CONTEXT_UCONTEXT)
       ADD_TEST(smpi-mpich3-coll-ompi-ucontext   ${CMAKE_COMMAND} -E chdir ${CMAKE_BINARY_DIR}/teshsuite/smpi/mpich3-test/coll perl ${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/runtests -mpiexec=${CMAKE_BINARY_DIR}/smpi_script/bin/smpirun -srcdir=${CMAKE_HOME_DIRECTORY}/teshsuite/smpi/mpich3-test/coll -tests=testlist -execarg=--cfg=contexts/factory:ucontext -execarg=--cfg=smpi/coll_selector:ompi -execarg=--cfg=smpi/send_is_detached_thres:0 -execarg=--cfg=smpi/privatize_global_variables:yes)
       set_tests_properties(smpi-mpich3-coll-ompi-ucontext PROPERTIES PASS_REGULAR_EXPRESSION "tests passed!")
index 4ed6294..0f5270f 100644 (file)
@@ -1001,6 +1001,7 @@ set(EXAMPLES_CMAKEFILES_TXT
 
 set(TESHSUITE_CMAKEFILES_TXT
   teshsuite/msg/CMakeLists.txt
+  teshsuite/msg/process_join/CMakeLists.txt
   teshsuite/msg/storage/CMakeLists.txt
   teshsuite/msg/trace/CMakeLists.txt
   teshsuite/bug-17132/CMakeLists.txt
index 513d72f..5b3c396 100644 (file)
@@ -80,6 +80,7 @@ add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/smpi/energy/f90)
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/examples/xbt)
 
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/msg)
+add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join)
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/msg/storage)
 add_subdirectory(${CMAKE_HOME_DIRECTORY}/teshsuite/msg/trace)
 
index 14da996..787df42 100644 (file)
@@ -180,7 +180,6 @@ XBT_PUBLIC(msg_process_t) MSG_process_create_with_environment(const char
                                                             properties);
 XBT_PUBLIC(void) MSG_process_kill(msg_process_t process);
 XBT_PUBLIC(int) MSG_process_killall(int reset_PIDs);
-
 XBT_PUBLIC(msg_error_t) MSG_process_migrate(msg_process_t process, msg_host_t host);
 
 XBT_PUBLIC(void *) MSG_process_get_data(msg_process_t process);
@@ -209,7 +208,7 @@ XBT_PUBLIC(const char *) MSG_process_get_property_value(msg_process_t
 XBT_PUBLIC(msg_error_t) MSG_process_suspend(msg_process_t process);
 XBT_PUBLIC(msg_error_t) MSG_process_resume(msg_process_t process);
 XBT_PUBLIC(int) MSG_process_is_suspended(msg_process_t process);
-XBT_PUBLIC(void) MSG_process_on_exit(int_f_pvoid_t fun, void *data);
+XBT_PUBLIC(void) MSG_process_on_exit(int_f_pvoid_pvoid_t fun, void *data);
 XBT_PUBLIC(void) MSG_process_auto_restart_set(msg_process_t process, int auto_restart);
 
 XBT_PUBLIC(msg_process_t) MSG_process_restart(msg_process_t process);
@@ -250,6 +249,7 @@ XBT_PUBLIC(void) MSG_task_set_priority(msg_task_t task, double priority);
 XBT_PUBLIC(void) MSG_task_set_bound(msg_task_t task, double bound);
 XBT_PUBLIC(void) MSG_task_set_affinity(msg_task_t task, msg_host_t host, unsigned long mask);
 
+XBT_PUBLIC(msg_error_t) MSG_process_join(msg_process_t process, double timeout);
 XBT_PUBLIC(msg_error_t) MSG_process_sleep(double nb_sec);
 
 XBT_PUBLIC(double) MSG_task_get_compute_duration(msg_task_t task);
index 8a32204..7bd3de8 100644 (file)
@@ -87,6 +87,10 @@ typedef struct s_smx_action *smx_action_t; /* FIXME: replace by specialized acti
     \see m_process_management
   @{ */
 typedef struct s_smx_process *smx_process_t;
+typedef enum {
+  SMX_EXIT_SUCCESS = 0,
+  SMX_EXIT_FAILURE = 1
+} smx_process_exit_status_t;
 /** @} */
 
 
@@ -227,7 +231,7 @@ XBT_PUBLIC(void) SIMIX_function_register_process_create(smx_creation_func_t func
 XBT_PUBLIC(void) SIMIX_function_register_process_kill(void_pfn_smxprocess_t_smxprocess_t function);
 
 /* Simulation execution */
-XBT_PUBLIC(void) SIMIX_run(void);    
+XBT_PUBLIC(void) SIMIX_run(void);
 XBT_PUBLIC(double) SIMIX_get_clock(void);
 
 /* Timer functions FIXME: should these be public? */
@@ -274,7 +278,7 @@ XBT_PUBLIC(smx_context_t) SIMIX_process_get_context(smx_process_t);
 XBT_PUBLIC(void) SIMIX_process_set_context(smx_process_t p,smx_context_t c);
 XBT_PUBLIC(int) SIMIX_process_has_pending_comms(smx_process_t process);
 XBT_PUBLIC(void) SIMIX_process_on_exit_runall(smx_process_t process);
-XBT_PUBLIC(void) SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data);
+XBT_PUBLIC(void) SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void *data);
 
 /****************************** Communication *********************************/
 XBT_PUBLIC(void) SIMIX_comm_set_copy_data_callback(void (*callback) (smx_action_t, void*, size_t));
@@ -388,9 +392,10 @@ XBT_PUBLIC(int) simcall_process_get_PPID(smx_process_t process);
 XBT_PUBLIC(int) simcall_process_is_suspended(smx_process_t process);
 XBT_PUBLIC(xbt_dict_t) simcall_process_get_properties(smx_process_t host);
 XBT_PUBLIC(void) simcall_process_set_kill_time(smx_process_t process, double kill_time);
-XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data);
+XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void *data);
 XBT_PUBLIC(void) simcall_process_auto_restart_set(smx_process_t process, int auto_restart);
 XBT_PUBLIC(smx_process_t) simcall_process_restart(smx_process_t process);
+XBT_PUBLIC(void) simcall_process_join(smx_process_t process, double timeout);
 /* Sleep control */
 XBT_PUBLIC(e_smx_state_t) simcall_process_sleep(double duration);
 
index e23f5d8..977c0b6 100644 (file)
@@ -77,11 +77,11 @@ void TRACE_msg_process_destroy (const char *process_name, int process_pid, msg_h
   PJ_container_free (process);
 }
 
-void TRACE_msg_process_kill(msg_process_t process)
+void TRACE_msg_process_kill(smx_process_exit_status_t status, msg_process_t process)
 {
-  if (TRACE_msg_process_is_enabled()){
+  if (TRACE_msg_process_is_enabled() && status==SMX_EXIT_FAILURE){
     //kill means that this process no longer exists, let's destroy it
-    TRACE_msg_process_destroy (MSG_process_get_name (process), MSG_process_get_PID (process), MSG_process_get_host (process));
+    TRACE_msg_process_destroy(MSG_process_get_name (process), MSG_process_get_PID (process), MSG_process_get_host (process));
   }
 }
 
index e5f4cad..fadcf96 100644 (file)
@@ -200,7 +200,7 @@ void TRACE_msg_process_change_host(msg_process_t process, msg_host_t old_host,
                                    msg_host_t new_host);
 void TRACE_msg_process_create (const char *process_name, int process_pid, msg_host_t host);
 void TRACE_msg_process_destroy (const char *process_name, int process_pid, msg_host_t host);
-void TRACE_msg_process_kill(msg_process_t process);
+void TRACE_msg_process_kill(smx_process_exit_status_t status, msg_process_t process);
 void TRACE_msg_process_suspend(msg_process_t process);
 void TRACE_msg_process_resume(msg_process_t process);
 void TRACE_msg_process_sleep_in(msg_process_t process);   //called from msg/gos.c
index 6a64e9d..d28d073 100644 (file)
@@ -182,7 +182,7 @@ msg_process_t MSG_process_create_with_environment(const char *name,
   }
   else {
     #ifdef HAVE_TRACING
-    simcall_process_on_exit(process,(int_f_pvoid_t)TRACE_msg_process_kill,MSG_process_self());
+    simcall_process_on_exit(process,(int_f_pvoid_pvoid_t)TRACE_msg_process_kill,process);
     #endif
   }
   return process;
@@ -200,12 +200,23 @@ void MSG_process_kill(msg_process_t process)
 //  if (p_simdata->waiting_task && p_simdata->waiting_task->simdata->comm) {
 //    simcall_comm_cancel(p_simdata->waiting_task->simdata->comm);
 //  }
+
   simcall_process_kill(process);
 
   return;
 }
 
+/**
+* \brief Wait for the completion of a #msg_process_t.
+*
+* \param process the process to wait for
+* \param timeout wait until the process is over, or the timeout occurs
+*/
+msg_error_t MSG_process_join(msg_process_t process, double timeout){
+  simcall_process_join(process, timeout);
+  return MSG_OK;
+}
+
 /** \ingroup m_process_management
  * \brief Migrates a process to another location.
  *
@@ -477,7 +488,7 @@ smx_context_t MSG_process_get_smx_ctx(msg_process_t process) {
  * The on_exit functions are the functions executed when your process is killed.
  * You should use them to free the data used by your process.
  */
-void MSG_process_on_exit(int_f_pvoid_t fun, void *data) {
+void MSG_process_on_exit(int_f_pvoid_pvoid_t fun, void *data) {
   simcall_process_on_exit(MSG_process_self(),fun,data);
 }
 /**
index d4b61ae..13a827c 100644 (file)
@@ -54,7 +54,7 @@ process_cleanup True (void) (process, void*, smx_process_t)
 process_change_host True (void) (process, void*, smx_process_t) (dest, void*, smx_host_t)
 process_suspend False (void) (process, void*, smx_process_t)
 process_resume True (void) (process, void*, smx_process_t)
-process_count True (int) 
+process_count True (int)
 process_get_PID True (int) (process, void*, smx_process_t)
 process_get_PPID True (int) (process, void*, smx_process_t)
 process_get_data True (void*) (process, void*, smx_process_t)
@@ -63,8 +63,9 @@ process_get_host True (void*, smx_host_t) (process, void*, smx_process_t)
 process_get_name True (const char*) (process, void*, smx_process_t)
 process_is_suspended True (int) (process, void*, smx_process_t)
 process_get_properties True (void*, xbt_dict_t) (process, void*, smx_process_t)
+process_join False (int) (process, void*, smx_process_t) (timeout, double)
 process_sleep False (int) (duration, double)
-process_on_exit True (void) (process, void*, smx_process_t) (fun, FPtr, int_f_pvoid_t) (data, void*)
+process_on_exit True (void) (process, void*, smx_process_t) (fun, FPtr, int_f_pvoid_pvoid_t) (data, void*)
 process_auto_restart_set True (void) (process, void*, smx_process_t) (auto_restart, int)
 process_restart True (void*, smx_process_t) (process, void*, smx_process_t)
 rdv_create True (void*, smx_rdv_t) (name, const char*)
@@ -90,12 +91,12 @@ comm_get_src_data True (void*) (comm, void*, smx_action_t)
 comm_get_dst_data True (void*) (comm, void*, smx_action_t)
 comm_get_src_proc True (void*, smx_process_t) (comm, void*, smx_action_t)
 comm_get_dst_proc True (void*, smx_process_t) (comm, void*, smx_action_t)
-mutex_init True (void*, smx_mutex_t) 
+mutex_init True (void*, smx_mutex_t)
 mutex_destroy True (void) (mutex, void*, smx_mutex_t)
 mutex_lock False (void) (mutex, void*, smx_mutex_t)
 mutex_trylock True (int) (mutex, void*, smx_mutex_t)
 mutex_unlock True (void) (mutex, void*, smx_mutex_t)
-cond_init True (void*, smx_cond_t) 
+cond_init True (void*, smx_cond_t)
 cond_destroy True (void) (cond, void*, smx_cond_t)
 cond_signal True (void) (cond, void*, smx_cond_t)
 cond_wait False (void) (cond, void*, smx_cond_t) (mutex, void*, smx_mutex_t)
@@ -128,6 +129,6 @@ comm_is_latency_bounded True (int) (comm, void*, smx_action_t)
 ## HAVE_TRACING
 set_category True (void) (action, void*, smx_action_t) (category, const char*)
 ## HAVE_MC
-mc_snapshot True (void*) 
+mc_snapshot True (void*)
 mc_compare_snapshots True (int) (s1, void*) (s2, void*)
 mc_random True (int) (min, int) (max, int)
index f73e443..d73a986 100644 (file)
@@ -558,6 +558,18 @@ static inline smx_process_t simcall_process_get_properties__get__process(smx_sim
 static inline void simcall_process_get_properties__set__process(smx_simcall_t simcall, void* arg){
     simcall->args[0].dp = arg;
 }
+static inline smx_process_t simcall_process_join__get__process(smx_simcall_t simcall){
+  return (smx_process_t) simcall->args[0].dp;
+}
+static inline void simcall_process_join__set__process(smx_simcall_t simcall, void* arg){
+    simcall->args[0].dp = arg;
+}
+static inline double simcall_process_join__get__timeout(smx_simcall_t simcall){
+  return  simcall->args[1].d;
+}
+static inline void simcall_process_join__set__timeout(smx_simcall_t simcall, double arg){
+    simcall->args[1].d = arg;
+}
 static inline double simcall_process_sleep__get__duration(smx_simcall_t simcall){
   return  simcall->args[0].d;
 }
@@ -570,8 +582,8 @@ static inline smx_process_t simcall_process_on_exit__get__process(smx_simcall_t
 static inline void simcall_process_on_exit__set__process(smx_simcall_t simcall, void* arg){
     simcall->args[0].dp = arg;
 }
-static inline int_f_pvoid_t simcall_process_on_exit__get__fun(smx_simcall_t simcall){
-  return (int_f_pvoid_t) simcall->args[1].fp;
+static inline int_f_pvoid_pvoid_t simcall_process_on_exit__get__fun(smx_simcall_t simcall){
+  return (int_f_pvoid_pvoid_t) simcall->args[1].fp;
 }
 static inline void simcall_process_on_exit__set__fun(smx_simcall_t simcall, FPtr arg){
     simcall->args[1].fp = arg;
index 2674738..c0f636f 100644 (file)
     }    
     return self->simcall.result.dp;
   }
+  inline static int simcall_BODY_process_join(smx_process_t process, double timeout) {
+    smx_process_t self = SIMIX_process_self();
+    self->simcall.call = SIMCALL_PROCESS_JOIN;
+    memset(&self->simcall.result, 0, sizeof(self->simcall.result));
+    memset(self->simcall.args, 0, sizeof(self->simcall.args));
+    self->simcall.args[0].dp = (void*) process;
+    self->simcall.args[1].d = (double) timeout;
+    if (self != simix_global->maestro_process) {
+      XBT_DEBUG("Yield process '%s' on simcall %s (%d)", self->name,
+                SIMIX_simcall_name(self->simcall.call), (int)self->simcall.call);
+      SIMIX_process_yield(self);
+    } else {
+      SIMIX_simcall_pre(&self->simcall, 0);
+    }    
+    return self->simcall.result.i;
+  }
   inline static int simcall_BODY_process_sleep(double duration) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_PROCESS_SLEEP;
     }    
     return self->simcall.result.i;
   }
-  inline static void simcall_BODY_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void* data) {
+  inline static void simcall_BODY_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void* data) {
     smx_process_t self = SIMIX_process_self();
     self->simcall.call = SIMCALL_PROCESS_ON_EXIT;
     memset(&self->simcall.result, 0, sizeof(self->simcall.result));
index e7ebf72..73abff2 100644 (file)
@@ -293,12 +293,16 @@ case SIMCALL_PROCESS_GET_PROPERTIES:
       SIMIX_simcall_answer(simcall);
       break;  
 
+case SIMCALL_PROCESS_JOIN:
+       SIMIX_pre_process_join(simcall , (smx_process_t) simcall->args[0].dp,  simcall->args[1].d);
+       break;  
+
 case SIMCALL_PROCESS_SLEEP:
        SIMIX_pre_process_sleep(simcall ,  simcall->args[0].d);
        break;  
 
 case SIMCALL_PROCESS_ON_EXIT:
-       SIMIX_pre_process_on_exit(simcall , (smx_process_t) simcall->args[0].dp, (int_f_pvoid_t) simcall->args[1].fp,  simcall->args[2].dp);
+       SIMIX_pre_process_on_exit(simcall , (smx_process_t) simcall->args[0].dp, (int_f_pvoid_pvoid_t) simcall->args[1].fp,  simcall->args[2].dp);
       SIMIX_simcall_answer(simcall);
       break;  
 
index 5337849..c2e7fe9 100644 (file)
@@ -63,6 +63,7 @@ SIMCALL_PROCESS_GET_HOST,
 SIMCALL_PROCESS_GET_NAME,
 SIMCALL_PROCESS_IS_SUSPENDED,
 SIMCALL_PROCESS_GET_PROPERTIES,
+SIMCALL_PROCESS_JOIN,
 SIMCALL_PROCESS_SLEEP,
 SIMCALL_PROCESS_ON_EXIT,
 SIMCALL_PROCESS_AUTO_RESTART_SET,
index defe198..6afe222 100644 (file)
@@ -241,6 +241,12 @@ static inline xbt_dict_t simcall_process_get_properties__get__result(smx_simcall
 static inline void simcall_process_get_properties__set__result(smx_simcall_t simcall, void* result){
     simcall->result.dp = result;
 }
+static inline int simcall_process_join__get__result(smx_simcall_t simcall){
+  return  simcall->result.i;
+}
+static inline void simcall_process_join__set__result(smx_simcall_t simcall, int result){
+    simcall->result.i = result;
+}
 static inline int simcall_process_sleep__get__result(smx_simcall_t simcall){
   return  simcall->result.i;
 }
index d409da2..8269d30 100644 (file)
@@ -63,6 +63,7 @@
 [SIMCALL_PROCESS_GET_NAME] = "SIMCALL_PROCESS_GET_NAME",
 [SIMCALL_PROCESS_IS_SUSPENDED] = "SIMCALL_PROCESS_IS_SUSPENDED",
 [SIMCALL_PROCESS_GET_PROPERTIES] = "SIMCALL_PROCESS_GET_PROPERTIES",
+[SIMCALL_PROCESS_JOIN] = "SIMCALL_PROCESS_JOIN",
 [SIMCALL_PROCESS_SLEEP] = "SIMCALL_PROCESS_SLEEP",
 [SIMCALL_PROCESS_ON_EXIT] = "SIMCALL_PROCESS_ON_EXIT",
 [SIMCALL_PROCESS_AUTO_RESTART_SET] = "SIMCALL_PROCESS_AUTO_RESTART_SET",
index fffa264..eb21291 100644 (file)
@@ -535,6 +535,10 @@ void SIMIX_display_process_status(void)
         action_description = "sleeping";
         break;
 
+      case SIMIX_ACTION_JOIN:
+        action_description = "joining";
+        break;
+
       case SIMIX_ACTION_SYNCHRO:
         action_description = "synchronization";
         break;
index 24d8a2c..1e5f1c1 100644 (file)
@@ -99,6 +99,7 @@ typedef enum {
   SIMIX_ACTION_EXECUTE,
   SIMIX_ACTION_PARALLEL_EXECUTE,
   SIMIX_ACTION_COMMUNICATE,
+  SIMIX_ACTION_JOIN,
   SIMIX_ACTION_SLEEP,
   SIMIX_ACTION_SYNCHRO,
   SIMIX_ACTION_IO,
index 8378a66..da0f7d2 100644 (file)
@@ -49,6 +49,8 @@ void SIMIX_process_cleanup(smx_process_t process)
   XBT_DEBUG("Cleanup process %s (%p), waiting action %p",
       process->name, process, process->waiting_action);
 
+  SIMIX_process_on_exit_runall(process);
+
   /* cancel non-blocking communications */
   smx_action_t action;
   while ((action = xbt_fifo_pop(process->comms))) {
@@ -101,7 +103,7 @@ void SIMIX_process_cleanup(smx_process_t process)
   process->context->iwannadie = 0;
 }
 
-/** 
+/**
  * Garbage collection
  *
  * Should be called some time to time to free the memory allocated for processes
@@ -253,7 +255,7 @@ void SIMIX_process_create(smx_process_t *process,
     (*process)->data = data;
     (*process)->comms = xbt_fifo_new();
     (*process)->simcall.issuer = *process;
-    
+
      if (parent_process) {
        (*process)->ppid = SIMIX_process_get_PID(parent_process);
      } else {
@@ -362,6 +364,10 @@ void SIMIX_process_kill(smx_process_t process, smx_process_t issuer) {
       SIMIX_process_sleep_destroy(process->waiting_action);
       break;
 
+    case SIMIX_ACTION_JOIN:
+      SIMIX_process_sleep_destroy(process->waiting_action);
+      break;
+
     case SIMIX_ACTION_SYNCHRO:
       SIMIX_synchro_stop_waiting(process, &process->simcall);
       SIMIX_synchro_destroy(process->waiting_action);
@@ -518,7 +524,7 @@ void SIMIX_process_resume(smx_process_t process, smx_process_t issuer)
 
       switch (process->waiting_action->type) {
 
-        case SIMIX_ACTION_EXECUTE:          
+        case SIMIX_ACTION_EXECUTE:
         case SIMIX_ACTION_PARALLEL_EXECUTE:
           SIMIX_host_execution_resume(process->waiting_action);
           break;
@@ -581,7 +587,7 @@ int SIMIX_process_get_PPID(smx_process_t self){
 }
 
 void* SIMIX_pre_process_self_get_data(smx_simcall_t simcall, smx_process_t self){
-  return SIMIX_process_self_get_data(self);    
+  return SIMIX_process_self_get_data(self);
 }
 
 void* SIMIX_process_self_get_data(smx_process_t self)
@@ -673,6 +679,43 @@ xbt_dict_t SIMIX_process_get_properties(smx_process_t process)
   return process->properties;
 }
 
+void SIMIX_pre_process_join(smx_simcall_t simcall, smx_process_t process, double timeout)
+{
+  smx_action_t action = SIMIX_process_join(simcall->issuer, process, timeout);
+  xbt_fifo_push(action->simcalls, simcall);
+  simcall->issuer->waiting_action = action;
+}
+
+static int SIMIX_process_join_finish(smx_process_exit_status_t status, smx_action_t action){
+  if (action->sleep.surf_sleep) {
+    surf_action_cancel(action->sleep.surf_sleep);
+
+    smx_simcall_t simcall;
+    while ((simcall = xbt_fifo_shift(action->simcalls))) {
+      simcall_process_sleep__set__result(simcall, SIMIX_DONE);
+      simcall->issuer->waiting_action = NULL;
+      if (simcall->issuer->suspended) {
+        XBT_DEBUG("Wait! This process is suspended and can't wake up now.");
+        simcall->issuer->suspended = 0;
+        SIMIX_pre_process_suspend(simcall, simcall->issuer);
+      } else {
+        SIMIX_simcall_answer(simcall);
+      }
+    }
+
+    SIMIX_process_sleep_destroy(action);
+  }
+  return 0;
+}
+
+smx_action_t SIMIX_process_join(smx_process_t issuer, smx_process_t process, double timeout)
+{
+  smx_action_t res = SIMIX_process_sleep(issuer, timeout);
+  res->type = SIMIX_ACTION_JOIN;
+  SIMIX_process_on_exit(process, (int_f_pvoid_pvoid_t)SIMIX_process_join_finish, res);
+  return res;
+}
+
 void SIMIX_pre_process_sleep(smx_simcall_t simcall, double duration)
 {
   if (MC_is_active()) {
@@ -718,7 +761,7 @@ void SIMIX_post_process_sleep(smx_action_t action)
 {
   smx_simcall_t simcall;
   e_smx_state_t state;
-  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
+  xbt_assert(action->type == SIMIX_ACTION_SLEEP || action->type == SIMIX_ACTION_JOIN);
 
   while ((simcall = xbt_fifo_shift(action->simcalls))) {
 
@@ -757,11 +800,14 @@ void SIMIX_post_process_sleep(smx_action_t action)
 void SIMIX_process_sleep_destroy(smx_action_t action)
 {
   XBT_DEBUG("Destroy action %p", action);
-  xbt_assert(action->type == SIMIX_ACTION_SLEEP);
+  xbt_assert(action->type == SIMIX_ACTION_SLEEP || action->type == SIMIX_ACTION_JOIN);
 
-  if (action->sleep.surf_sleep)
+  if (action->sleep.surf_sleep) {
     surf_action_unref(action->sleep.surf_sleep);
-  xbt_mallocator_release(simix_global->action_mallocator, action);
+    action->sleep.surf_sleep = NULL;
+  }
+  if (action->type == SIMIX_ACTION_SLEEP)
+    xbt_mallocator_release(simix_global->action_mallocator, action);
 }
 
 void SIMIX_process_sleep_suspend(smx_action_t action)
@@ -777,7 +823,7 @@ void SIMIX_process_sleep_resume(smx_action_t action)
   surf_action_resume(action->sleep.surf_sleep);
 }
 
-/** 
+/**
  * \brief Calling this function makes the process to yield.
  *
  * Only the current process can call this function, giving back the control to
@@ -876,19 +922,20 @@ xbt_dynar_t SIMIX_processes_as_dynar(void) {
 
 void SIMIX_process_on_exit_runall(smx_process_t process) {
   s_smx_process_exit_fun_t exit_fun;
-
+  smx_process_exit_status_t exit_status = (process->context->iwannadie) ?
+                                         SMX_EXIT_FAILURE : SMX_EXIT_SUCCESS;
   while (!xbt_dynar_is_empty(process->on_exit)) {
     exit_fun = xbt_dynar_pop_as(process->on_exit,s_smx_process_exit_fun_t);
-    (exit_fun.fun)(exit_fun.arg);
+    (exit_fun.fun)((void*)exit_status, exit_fun.arg);
   }
 }
 
 void SIMIX_pre_process_on_exit(smx_simcall_t simcall, smx_process_t process,
-                              int_f_pvoid_t fun, void *data) {
+                              int_f_pvoid_pvoid_t fun, void *data) {
   SIMIX_process_on_exit(process, fun, data);
 }
 
-void SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data) {
+void SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void *data) {
   xbt_assert(process, "current process not found: are you in maestro context ?");
 
   if (!process->on_exit) {
@@ -902,7 +949,7 @@ void SIMIX_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
 
 void SIMIX_pre_process_auto_restart_set(smx_simcall_t simcall, smx_process_t process,
                                        int auto_restart) {
-  SIMIX_process_auto_restart_set(process, auto_restart);       
+  SIMIX_process_auto_restart_set(process, auto_restart);
 }
 /**
  * \brief Sets the auto-restart status of the process.
@@ -914,7 +961,7 @@ void SIMIX_process_auto_restart_set(smx_process_t process, int auto_restart) {
 }
 
 smx_process_t SIMIX_pre_process_restart(smx_simcall_t simcall, smx_process_t process) {
-  return SIMIX_process_restart(process, simcall->issuer);      
+  return SIMIX_process_restart(process, simcall->issuer);
 }
 /**
  * \brief Restart a process.
index eb269f9..bff1f1a 100644 (file)
@@ -11,7 +11,7 @@
 #include "smx_smurf_private.h"
 
 typedef struct s_smx_process_exit_fun {
-  int_f_pvoid_t fun;
+  int_f_pvoid_pvoid_t fun;
   void *arg;
 } s_smx_process_exit_fun_t, *smx_process_exit_fun_t;
 
@@ -27,7 +27,6 @@ typedef struct s_smx_process_arg {
   unsigned auto_restart:1;
 } s_smx_process_arg_t, *smx_process_arg_t;
 
-
 /** @brief Process datatype */
 typedef struct s_smx_process {
   s_xbt_swag_hookup_t process_hookup;
@@ -99,6 +98,8 @@ const char* SIMIX_process_get_name(smx_process_t process);
 smx_process_t SIMIX_process_get_by_name(const char* name);
 int SIMIX_process_is_suspended(smx_process_t process);
 xbt_dict_t SIMIX_process_get_properties(smx_process_t process);
+void SIMIX_pre_process_join(smx_simcall_t simcall, smx_process_t process, double timeout);
+smx_action_t SIMIX_process_join(smx_process_t issuer, smx_process_t process, double timeout);
 void SIMIX_pre_process_sleep(smx_simcall_t simcall, double duration);
 smx_action_t SIMIX_process_sleep(smx_process_t process, double duration);
 void SIMIX_post_process_sleep(smx_action_t action);
@@ -130,7 +131,7 @@ const char* SIMIX_pre_process_get_name(smx_simcall_t simcall, smx_process_t proc
 int SIMIX_pre_process_is_suspended(smx_simcall_t simcall, smx_process_t process);
 xbt_dict_t SIMIX_pre_process_get_properties(smx_simcall_t simcall, smx_process_t process);
 void SIMIX_pre_process_on_exit(smx_simcall_t simcall, smx_process_t process,
-                              int_f_pvoid_t fun, void *data);
+                              int_f_pvoid_pvoid_t fun, void *data);
 void SIMIX_pre_process_auto_restart_set(smx_simcall_t simcall, smx_process_t process,
                                        int auto_restart);
 smx_process_t SIMIX_pre_process_restart(smx_simcall_t simcall, smx_process_t process);
index 515446b..e36f6d2 100644 (file)
@@ -96,6 +96,10 @@ void SIMIX_simcall_post(smx_action_t action)
       SIMIX_post_process_sleep(action);
       break;
 
+    case SIMIX_ACTION_JOIN:
+      SIMIX_post_process_sleep(action);
+      break;
+
     case SIMIX_ACTION_SYNCHRO:
       SIMIX_post_synchro(action);
       break;
@@ -120,7 +124,7 @@ void SIMIX_simcall_post(smx_action_t action)
 /* FIXME find a way to make this work
 simcall_handler_t simcall_table[NUM_SIMCALLS] = {
 #undef SIMCALL_ENUM_ELEMENT
-#define SIMCALL_ENUM_ELEMENT(x,y) &y // generate strings from the enumeration values 
+#define SIMCALL_ENUM_ELEMENT(x,y) &y // generate strings from the enumeration values
 SIMCALL_LIST
 #undef SIMCALL_ENUM_ELEMENT
 };*/
index 18be610..453c741 100644 (file)
@@ -239,7 +239,7 @@ smx_action_t simcall_host_execute(const char *name, smx_host_t host,
   /* checking for infinite values */
   xbt_assert(isfinite(computation_amount), "computation_amount is not finite!");
   xbt_assert(isfinite(priority), "priority is not finite!");
-  
+
   return simcall_BODY_host_execute(name, host, computation_amount, priority, bound, affinity_mask);
 }
 
@@ -271,14 +271,14 @@ smx_action_t simcall_host_parallel_execute(const char *name,
   for (i = 0 ; i < host_nb ; ++i) {
      xbt_assert(isfinite(computation_amount[i]), "computation_amount[%d] is not finite!", i);
      for (j = 0 ; j < host_nb ; ++j) {
-        xbt_assert(isfinite(communication_amount[i + host_nb * j]), 
+        xbt_assert(isfinite(communication_amount[i + host_nb * j]),
              "communication_amount[%d+%d*%d] is not finite!", i, host_nb, j);
-     }   
-  }   
+     }
+  }
+
   xbt_assert(isfinite(amount), "amount is not finite!");
   xbt_assert(isfinite(rate), "rate is not finite!");
-  
+
   return simcall_BODY_host_parallel_execute(name, host_nb, host_list,
                                             computation_amount,
                                             communication_amount,
@@ -346,7 +346,7 @@ void simcall_host_execution_set_priority(smx_action_t execution, double priority
 {
   /* checking for infinite values */
   xbt_assert(isfinite(priority), "priority is not finite!");
-  
+
   simcall_BODY_host_execution_set_priority(execution, priority);
 }
 
@@ -629,6 +629,11 @@ void simcall_process_change_host(smx_process_t process, smx_host_t dest)
   simcall_BODY_process_change_host(process, dest);
 }
 
+void simcall_process_join(smx_process_t process, double timeout)
+{
+  simcall_BODY_process_join(process, timeout);
+}
+
 /**
  * \ingroup simix_process_management
  * \brief Suspends a process.
@@ -814,7 +819,7 @@ xbt_dict_t simcall_process_get_properties(smx_process_t process)
  * \brief Add an on_exit function
  * Add an on_exit function which will be executed when the process exits/is killed.
  */
-XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_t fun, void *data)
+XBT_PUBLIC(void) simcall_process_on_exit(smx_process_t process, int_f_pvoid_pvoid_t fun, void *data)
 {
   simcall_BODY_process_on_exit(process, fun, data);
 }
@@ -937,7 +942,7 @@ void simcall_comm_send(smx_rdv_t rdv, double task_size, double rate,
   xbt_assert(isfinite(task_size), "task_size is not finite!");
   xbt_assert(isfinite(rate), "rate is not finite!");
   xbt_assert(isfinite(timeout), "timeout is not finite!");
-  
+
   xbt_assert(rdv, "No rendez-vous point defined for send");
 
   if (MC_is_active()) {
@@ -967,7 +972,7 @@ smx_action_t simcall_comm_isend(smx_rdv_t rdv, double task_size, double rate,
   /* checking for infinite values */
   xbt_assert(isfinite(task_size), "task_size is not finite!");
   xbt_assert(isfinite(rate), "rate is not finite!");
-  
+
   xbt_assert(rdv, "No rendez-vous point defined for isend");
 
   return simcall_BODY_comm_isend(rdv, task_size, rate, src_buff,
@@ -1134,7 +1139,7 @@ smx_process_t simcall_comm_get_src_proc(smx_action_t comm)
  */
 smx_process_t simcall_comm_get_dst_proc(smx_action_t comm)
 {
-  return simcall_BODY_comm_get_dst_proc(comm);  
+  return simcall_BODY_comm_get_dst_proc(comm);
 }
 
 #ifdef HAVE_LATENCY_BOUND_TRACKING
@@ -1172,7 +1177,7 @@ void simcall_mutex_destroy(smx_mutex_t mutex)
  */
 void simcall_mutex_lock(smx_mutex_t mutex)
 {
-  simcall_BODY_mutex_lock(mutex);  
+  simcall_BODY_mutex_lock(mutex);
 }
 
 /**
@@ -1181,7 +1186,7 @@ void simcall_mutex_lock(smx_mutex_t mutex)
  */
 int simcall_mutex_trylock(smx_mutex_t mutex)
 {
-  return simcall_BODY_mutex_trylock(mutex);  
+  return simcall_BODY_mutex_trylock(mutex);
 }
 
 /**
@@ -1190,7 +1195,7 @@ int simcall_mutex_trylock(smx_mutex_t mutex)
  */
 void simcall_mutex_unlock(smx_mutex_t mutex)
 {
-  simcall_BODY_mutex_unlock(mutex); 
+  simcall_BODY_mutex_unlock(mutex);
 }
 
 /**
@@ -1256,7 +1261,7 @@ void simcall_cond_broadcast(smx_cond_t cond)
  */
 smx_sem_t simcall_sem_init(int capacity)
 {
-  return simcall_BODY_sem_init(capacity);  
+  return simcall_BODY_sem_init(capacity);
 }
 
 /**
@@ -1274,7 +1279,7 @@ void simcall_sem_destroy(smx_sem_t sem)
  */
 void simcall_sem_release(smx_sem_t sem)
 {
-  simcall_BODY_sem_release(sem);  
+  simcall_BODY_sem_release(sem);
 }
 
 /**
@@ -1475,7 +1480,7 @@ void *simcall_mc_snapshot(void)
   return simcall_BODY_mc_snapshot();
 }
 
-int simcall_mc_compare_snapshots(void *s1, void *s2){ 
+int simcall_mc_compare_snapshots(void *s1, void *s2){
   return simcall_BODY_mc_compare_snapshots(s1, s2);
 }
 
index 6d8c14c..0fee70a 100644 (file)
@@ -5,7 +5,7 @@
  * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include "msg/msg.h"
-#include "xbt/sysdep.h"        
+#include "xbt/sysdep.h"
 
 XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
                              "Messages specific for this msg example");
@@ -13,15 +13,15 @@ const char* mailbox = "mailbox";
 #define task_comp_size 1000
 #define task_comm_size 100000
 
-static int onexit(void* data){
-  XBT_INFO("Process \"%d\" killed.", *((int*)data));
+static int onexit(smx_process_exit_status_t status, int *pid){
+  XBT_INFO("Process \"%d\" killed.", *pid);
   return 0;
 }
 
 static int sendpid(int argc, char *argv[])
 {
   int pid = MSG_process_self_PID();
-  MSG_process_on_exit(onexit, &pid);  
+  MSG_process_on_exit((int_f_pvoid_pvoid_t)onexit, &pid);
   msg_task_t task = MSG_task_create("pid", task_comp_size, task_comm_size, &pid);
   XBT_INFO("Sending pid of \"%d\".", pid);
   MSG_task_send(task, mailbox);
diff --git a/teshsuite/msg/process_join/CMakeLists.txt b/teshsuite/msg/process_join/CMakeLists.txt
new file mode 100644 (file)
index 0000000..bca2830
--- /dev/null
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 2.6)
+
+set(EXECUTABLE_OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}")
+
+add_executable(process_join ${CMAKE_HOME_DIRECTORY}/teshsuite/msg/process_join/process_join.c)
+
+### Add definitions for compile
+target_link_libraries(process_join simgrid)
+
+set(tesh_files
+  ${tesh_files}
+  ${CMAKE_CURRENT_SOURCE_DIR}/process_join.tesh
+  PARENT_SCOPE
+  )
+set(xml_files
+  ${xml_files}
+  ${CMAKE_CURRENT_SOURCE_DIR}/process_join_d.xml
+  ${CMAKE_CURRENT_SOURCE_DIR}/process_join_p.xml
+  PARENT_SCOPE
+  )
+set(teshsuite_src
+  ${teshsuite_src}
+  ${CMAKE_CURRENT_SOURCE_DIR}/process_join.c
+  PARENT_SCOPE
+  )
+set(bin_files
+  ${bin_files}
+  PARENT_SCOPE
+  )
+set(txt_files
+  ${txt_files}
+  PARENT_SCOPE
+  )
diff --git a/teshsuite/msg/process_join/process_join.c b/teshsuite/msg/process_join/process_join.c
new file mode 100644 (file)
index 0000000..8f6e9d8
--- /dev/null
@@ -0,0 +1,94 @@
+/* Copyright (c) 2010-2014. The SimGrid Team.
+ * All rights 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 <stdio.h>
+#include "msg/msg.h"            /* Yeah! If you want to use msg, you need to include msg/msg.h */
+#include "xbt/sysdep.h"         /* calloc, printf */
+
+/* Create a log channel to have nice outputs. */
+#include "xbt/log.h"
+#include "xbt/asserts.h"
+XBT_LOG_NEW_DEFAULT_CATEGORY(msg_test,
+                             "Messages specific for this msg example");
+
+int master(int argc, char *argv[]);
+int slave(int argc, char *argv[]);
+
+/** Emitter function  */
+int master(int argc, char *argv[])
+{
+  msg_process_t process;
+
+  XBT_INFO("Start slave");
+  process =  MSG_process_create("slave from master",
+                               slave, NULL, MSG_host_self());
+  XBT_INFO("Join the slave (timeout 2)");
+  MSG_process_join(process, 2);
+
+  XBT_INFO("Start slave");
+  process =  MSG_process_create("slave from master",
+                               slave, NULL, MSG_host_self());
+  XBT_INFO("Join the slave (timeout 4)");
+  MSG_process_join(process, 4);
+
+  XBT_INFO("Start slave");
+  process =  MSG_process_create("slave from master",
+                               slave, NULL, MSG_host_self());
+  XBT_INFO("Join the slave (timeout 2)");
+  MSG_process_join(process, 2);
+
+  XBT_INFO("Goodbye now!");
+
+  MSG_process_sleep(1);
+
+  XBT_INFO("Goodbye now!");
+  return 0;
+}                               /* end_of_master */
+
+/** Receiver function  */
+int slave(int argc, char *argv[])
+{
+  XBT_INFO("Slave started");
+  MSG_process_sleep(3);
+  XBT_INFO("I'm done. See you!");
+  return 0;
+}                               /* end_of_slave */
+
+/** Main function */
+int main(int argc, char *argv[])
+{
+  msg_error_t res;
+  const char *platform_file;
+  const char *application_file;
+
+  MSG_init(&argc, argv);
+  if (argc != 3) {
+    printf("Usage: %s platform_file deployment_file\n", argv[0]);
+    printf("example: %s msg_platform.xml msg_deployment.xml\n", argv[0]);
+    exit(1);
+  }
+  platform_file = argv[1];
+  application_file = argv[2];
+
+  /* MSG_config("workstation/model","KCCFLN05"); */
+  {                             /*  Simulation setting */
+    MSG_create_environment(platform_file);
+  }
+  {                             /*   Application deployment */
+    MSG_function_register("master", master);
+    MSG_function_register("slave", slave);
+
+    MSG_launch_application(application_file);
+  }
+  res = MSG_main();
+
+  XBT_INFO("Simulation time %g", MSG_get_clock());
+
+  if (res == MSG_OK)
+    return 0;
+  else
+    return 1;
+}                               /* end_of_main */
diff --git a/teshsuite/msg/process_join/process_join.tesh b/teshsuite/msg/process_join/process_join.tesh
new file mode 100644 (file)
index 0000000..90548a5
--- /dev/null
@@ -0,0 +1,17 @@
+
+$ process_join ${srcdir:=.}/process_join_p.xml ${srcdir:=.}/process_join_d.xml
+> [Tremblay:master:(1) 0.000000] [msg_test/INFO] Start slave
+> [Tremblay:slave from master:(2) 0.000000] [msg_test/INFO] Slave started
+> [Tremblay:master:(1) 0.000000] [msg_test/INFO] Join the slave (timeout 2)
+> [Tremblay:master:(1) 2.000000] [msg_test/INFO] Start slave
+> [Tremblay:slave from master:(3) 2.000000] [msg_test/INFO] Slave started
+> [Tremblay:master:(1) 2.000000] [msg_test/INFO] Join the slave (timeout 4)
+> [Tremblay:slave from master:(2) 3.000000] [msg_test/INFO] I'm done. See you!
+> [Tremblay:slave from master:(3) 5.000000] [msg_test/INFO] I'm done. See you!
+> [Tremblay:master:(1) 5.000000] [msg_test/INFO] Start slave
+> [Tremblay:slave from master:(4) 5.000000] [msg_test/INFO] Slave started
+> [Tremblay:master:(1) 5.000000] [msg_test/INFO] Join the slave (timeout 2)
+> [Tremblay:master:(1) 7.000000] [msg_test/INFO] Goodbye now!
+> [Tremblay:slave from master:(4) 8.000000] [msg_test/INFO] I'm done. See you!
+> [Tremblay:master:(1) 8.000000] [msg_test/INFO] Goodbye now!
+> [8.000000] [msg_test/INFO] Simulation time 8
diff --git a/teshsuite/msg/process_join/process_join_d.xml b/teshsuite/msg/process_join/process_join_d.xml
new file mode 100644 (file)
index 0000000..6346190
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<platform version="3">
+  <!-- The master process (with some arguments) -->
+  <process host="Tremblay" function="master">
+  </process>
+</platform>
diff --git a/teshsuite/msg/process_join/process_join_p.xml b/teshsuite/msg/process_join/process_join_p.xml
new file mode 100644 (file)
index 0000000..90e976a
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version='1.0'?>
+<!DOCTYPE platform SYSTEM "http://simgrid.gforge.inria.fr/simgrid.dtd">
+<platform version="3">
+  <!-- The hosts -->
+  <AS  id="AS0"  routing="Full">
+   <host id="Tremblay" power="98.095Mf"/>
+  </AS>
+</platform>
\ No newline at end of file
diff --git a/teshsuite/msg/process_join/process_log b/teshsuite/msg/process_join/process_log
new file mode 100644 (file)
index 0000000..22e1584
--- /dev/null
@@ -0,0 +1,74 @@
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:227: [simix_context/VERBOSE] Using raw contexts. Because the glibc is just not good enough for us.
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_environment.c:41: [simix_environment/DEBUG] PARSE TIME: 0.00112009
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_deployment.c:71: [simix_deployment/DEBUG] Starting Process master(Tremblay) right now
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d06478: SIMCALL_PROCESS_CREATE
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:237: [simix_process/DEBUG] Start process master on host 'Tremblay'
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:273: [simix_process/VERBOSE] Create context master
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:290: [simix_process/DEBUG] Start context 'master'
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:294: [simix_process/DEBUG] Inserting master(Tremblay) in the to_run list
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d06478: SIMCALL_PROCESS_GET_PID
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d06478: SIMCALL_PROCESS_ON_EXIT
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d06478: SIMCALL_PROCESS_AUTO_RESTART_SET
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:294: [simix_kernel/DEBUG] New Schedule Round; size(queue)=1
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=1
+[Tremblay:master:(1) 0.000000] [msg_test/INFO] Start slave
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:679: [simix/DEBUG] Yield process 'master' on simcall SIMCALL_PROCESS_CREATE (43)
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d079c8: SIMCALL_PROCESS_CREATE
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:237: [simix_process/DEBUG] Start process slave from master on host 'Tremblay'
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:273: [simix_process/VERBOSE] Create context slave from master
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:290: [simix_process/DEBUG] Start context 'slave from master'
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:294: [simix_process/DEBUG] Inserting slave from master(Tremblay) in the to_run list
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:45: [simix_smurf/DEBUG] Answer simcall SIMCALL_PROCESS_CREATE (43) issued by master (0x1d07930)
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=2
+[Tremblay:slave from master:(2) 0.000000] [msg_test/INFO] Slave started
+[Tremblay:slave from master:(2) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:937: [simix/DEBUG] Yield process 'slave from master' on simcall SIMCALL_PROCESS_SLEEP (60)
+[Tremblay:slave from master:(2) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'slave from master'
+[Tremblay:slave from master:(2) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:381: [simix_context/DEBUG] Run next process
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:819: [simix_process/DEBUG] Control returned to me: 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:800: [simix/DEBUG] Yield process 'master' on simcall SIMCALL_PROCESS_GET_PID (51)
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d07c98: SIMCALL_PROCESS_SLEEP
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:735: [simix_process/DEBUG] Create sleep action 0x1dc32d0
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d079c8: SIMCALL_PROCESS_GET_PID
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:45: [simix_smurf/DEBUG] Answer simcall SIMCALL_PROCESS_GET_PID (51) issued by master (0x1d07930)
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=1
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:819: [simix_process/DEBUG] Control returned to me: 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:954: [simix/DEBUG] Yield process 'master' on simcall SIMCALL_PROCESS_ON_EXIT (61)
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d079c8: SIMCALL_PROCESS_ON_EXIT
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:45: [simix_smurf/DEBUG] Answer simcall SIMCALL_PROCESS_ON_EXIT (61) issued by master (0x1d07930)
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=1
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:819: [simix_process/DEBUG] Control returned to me: 'master'
+[Tremblay:master:(1) 0.000000] [msg_test/INFO] Wait for slave
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:922: [simix/DEBUG] Yield process 'master' on simcall SIMCALL_PROCESS_WAIT (59)
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'master'
+[Tremblay:master:(1) 0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d079c8: SIMCALL_PROCESS_WAIT
+[0.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:735: [simix_process/DEBUG] Create sleep action 0x1dc31f0
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:45: [simix_smurf/DEBUG] Answer simcall SIMCALL_PROCESS_SLEEP (60) issued by slave from master (0x1d07c00)
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:782: [simix_process/DEBUG] Destroy action 0x1dc32d0
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:422: [simix_kernel/DEBUG] ### time 2.000000, empty 0
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:294: [simix_kernel/DEBUG] New Schedule Round; size(queue)=1
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=1
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:819: [simix_process/DEBUG] Control returned to me: 'slave from master'
+[Tremblay:slave from master:(2) 2.000000] [msg_test/INFO] I'm done. See you!
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/simcalls_generated_body.c:724: [simix/DEBUG] Yield process 'slave from master' on simcall SIMCALL_PROCESS_CLEANUP (46)
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:813: [simix_process/DEBUG] Yield process 'slave from master'
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:58: [simix_smurf/DEBUG] Handling simcall 0x1d07c98: SIMCALL_PROCESS_CLEANUP
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:50: [simix_process/DEBUG] Cleanup process slave from master (0x1d07c00), waiting action (nil)
+[2.000000] [simix_process/INFO] FINISHING
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:782: [simix_process/DEBUG] Destroy action 0x1dc31f0
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_smurf.c:45: [simix_smurf/DEBUG] Answer simcall SIMCALL_PROCESS_CLEANUP (46) issued by slave from master (0x1d07c00)
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:300: [simix_kernel/DEBUG] New Sub-Schedule Round; size(queue)=1
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_process.c:819: [simix_process/DEBUG] Control returned to me: 'slave from master'
+[Tremblay:slave from master:(2) 2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_context_raw.c:387: [simix_context/DEBUG] No more process to run
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:422: [simix_kernel/DEBUG] ### time -1.000000, empty 1
+[2.000000] /home/bedaride/Boulot/simgrid/src/simix/smx_global.c:434: [simix_kernel/CRITICAL] Oops ! Deadlock or code not perfectly clean.
+[2.000000] [simix_kernel/INFO] 1 processes are still running, waiting for something.
+[2.000000] [simix_kernel/INFO] Legend of the following listing: "Process <pid> (<name>@<host>): <status>"
+[2.000000] [simix_kernel/INFO] Process 1 (master@Tremblay): waiting for sleeping action 0x1dc31f0 ((null)) in state 0 to finish