Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Automatically release resources associated with detached threads.
[simgrid.git] / src / xbt / xbt_os_thread.c
index a04779d..3dc40c5 100644 (file)
@@ -41,6 +41,7 @@ static xbt_os_mutex_t next_sem_ID_lock;
 
 typedef struct xbt_os_thread_ {
   pthread_t t;
+  int detached;
   char *name;
   void *param;
   pvoid_f_pvoid_t start_routine;
@@ -54,9 +55,14 @@ static pthread_key_t xbt_self_thread_key;
 static int thread_mod_inited = 0;
 
 /* frees the xbt_os_thread_t corresponding to the current thread */
-static void xbt_os_thread_free_thread_data(void *d)
+static void xbt_os_thread_free_thread_data(xbt_os_thread_t thread)
 {
-  free(d);
+  if (thread == main_thread)    /* just killed main thread */
+    main_thread = NULL;
+
+  free(thread->running_ctx);
+  free(thread->name);
+  free(thread);
 }
 
 /* callback: context fetching */
@@ -144,7 +150,10 @@ static void *wrapper_start_routine(void *s)
     THROW0(system_error, errcode,
            "pthread_setspecific failed for xbt_self_thread_key");
 
-  return (*(t->start_routine)) (t->param);
+  void *res = (*(t->start_routine)) (t->param);
+  if (t->detached)
+    xbt_os_thread_free_thread_data(t);
+  return res;
 }
 
 xbt_os_thread_t xbt_os_thread_create(const char *name,
@@ -155,6 +164,7 @@ xbt_os_thread_t xbt_os_thread_create(const char *name,
   int errcode;
 
   xbt_os_thread_t res_thread = xbt_new(s_xbt_os_thread_t, 1);
+  res_thread->detached = 0;
   res_thread->name = xbt_strdup(name);
   res_thread->start_routine = start_routine;
   res_thread->param = param;
@@ -199,16 +209,7 @@ void xbt_os_thread_join(xbt_os_thread_t thread, void **thread_return)
   if ((errcode = pthread_join(thread->t, thread_return)))
     THROW1(system_error, errcode, "pthread_join failed: %s",
            strerror(errcode));
-  if (thread->running_ctx)
-    free(thread->running_ctx);
-
-  if (thread->name)
-    free(thread->name);
-
-  if (thread == main_thread)    /* just killed main thread */
-    main_thread = NULL;
-
-  free(thread);
+  xbt_os_thread_free_thread_data(thread);
 }
 
 void xbt_os_thread_exit(int *retval)
@@ -230,6 +231,7 @@ xbt_os_thread_t xbt_os_thread_self(void)
 
 void xbt_os_thread_detach(xbt_os_thread_t thread)
 {
+  thread->detached = 1;
   pthread_detach(thread->t);
 }
 
@@ -305,7 +307,7 @@ void xbt_os_mutex_timedacquire(xbt_os_mutex_t mutex, double delay)
 
     ts_end.tv_sec = (time_t) floor(end);
     ts_end.tv_nsec = (long) ((end - ts_end.tv_sec) * 1000000000);
-    DEBUG2("pthread_mutex_timedlock(%p,%p)", &(mutex->m), &ts_end);
+    XBT_DEBUG("pthread_mutex_timedlock(%p,%p)", &(mutex->m), &ts_end);
 
     errcode = pthread_mutex_timedlock(&(mutex->m), &ts_end);
 
@@ -398,7 +400,7 @@ void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex,
   } else {
     ts_end.tv_sec = (time_t) floor(end);
     ts_end.tv_nsec = (long) ((end - ts_end.tv_sec) * 1000000000);
-    DEBUG3("pthread_cond_timedwait(%p,%p,%p)", &(cond->c), &(mutex->m),
+    XBT_DEBUG("pthread_cond_timedwait(%p,%p,%p)", &(cond->c), &(mutex->m),
            &ts_end);
     switch ((errcode =
              pthread_cond_timedwait(&(cond->c), &(mutex->m), &ts_end))) {
@@ -539,7 +541,7 @@ void xbt_os_sem_timedacquire(xbt_os_sem_t sem, double delay)
 
     ts_end.tv_sec = (time_t) floor(end);
     ts_end.tv_nsec = (long) ((end - ts_end.tv_sec) * 1000000000);
-    DEBUG2("sem_timedwait(%p,%p)", sem->ps, &ts_end);
+    XBT_DEBUG("sem_timedwait(%p,%p)", sem->ps, &ts_end);
     errcode = sem_timedwait(sem->s, &ts_end);
 
 #else                           /* Okay, reimplement this function then */
@@ -911,7 +913,7 @@ void xbt_os_cond_timedwait(xbt_os_cond_t cond, xbt_os_mutex_t mutex,
   if (delay < 0) {
     xbt_os_cond_wait(cond, mutex);
   } else {
-    DEBUG3("xbt_cond_timedwait(%p,%p,%lu)", &(cond->events),
+    XBT_DEBUG("xbt_cond_timedwait(%p,%p,%lu)", &(cond->events),
            &(mutex->lock), end);
 
     /* lock the threads counter and increment it */