]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/l4re-core/uclibc/lib/libpthread/src/manager.cc
Update
[l4.git] / l4 / pkg / l4re-core / uclibc / lib / libpthread / src / manager.cc
similarity index 96%
rename from l4/pkg/uclibc/lib/libpthread/src/manager.cc
rename to l4/pkg/l4re-core/uclibc/lib/libpthread/src/manager.cc
index 7c1fcac9b5e3e7419dbdb420d37703c0026554d8..ccd601038f48f30236d03bdd32a5d7a2dfd23040 100644 (file)
@@ -106,7 +106,7 @@ static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode)
 static void pthread_for_each_thread(void *arg,
     void (*fn)(void *, pthread_descr));
 
-static void pthread_exited(pthread_descr th);
+static int pthread_exited(pthread_descr th);
 
 /* The server thread managing requests for thread creation and termination */
 
@@ -121,7 +121,7 @@ __pthread_manager(void *arg)
 # if defined(TLS_TCB_AT_TP)
   TLS_INIT_TP(self, 0);
 #elif defined(TLS_DTV_AT_TP)
-  TLS_INIT_TP(self + 1, 0);
+  TLS_INIT_TP((char *)self + TLS_PRE_TCB_SIZE, 0);
 #else
 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 #endif
@@ -216,18 +216,17 @@ __pthread_manager(void *arg)
          break;
         case REQ_THREAD_EXIT:
             {
-              l4_msgtag_t e;
-              L4::Cap<L4::Thread> c;
-
-              pthread_exited(request.req_thread);
-
-              c = L4::Cap<L4::Thread>(request.req_thread->p_thsem_cap);
-              e = L4::Cap<L4::Task>(L4Re::This_task)
-                         ->unmap(c.fpage(), L4_FP_ALL_SPACES);
-
-              c = L4::Cap<L4::Thread>(request.req_thread->p_th_cap);
-              e = L4::Cap<L4::Task>(L4Re::This_task)
-                         ->unmap(c.fpage(), L4_FP_ALL_SPACES);
+              if (!pthread_exited(request.req_thread))
+                {
+                  auto th = request.req_thread;
+                  /* Thread still waiting to be joined. Only release
+                     L4 resources for now. */
+                  using L4Re::Util::Auto_cap;
+                  Auto_cap<void>::Cap s = L4::Cap<void>(th->p_thsem_cap);
+                  th->p_thsem_cap = L4_INVALID_CAP;
+                  Auto_cap<void>::Cap t = L4::Cap<void>(th->p_th_cap);
+                  th->p_th_cap = L4_INVALID_CAP;
+                }
             }
           break;
        }
@@ -262,7 +261,7 @@ pthread_start_thread(void *arg)
 # if defined(TLS_TCB_AT_TP)
   TLS_INIT_TP(self, 0);
 #elif defined(TLS_DTV_AT_TP)
-  TLS_INIT_TP(self + 1, 0);
+  TLS_INIT_TP((char *)self + TLS_PRE_TCB_SIZE, 0);
 #else
 #  error "Either TLS_TCB_AT_TP or TLS_DTV_AT_TP must be defined"
 #endif
@@ -358,13 +357,6 @@ static int pthread_l4_free_stack(void *stack_addr, void *guardaddr)
   if (err < 0)
     return err;
 
-  if (ds.is_valid())
-    {
-      err = ds->release();
-      if (err < 0)
-        return err;
-    }
-
   L4Re::Util::cap_alloc.free(ds);
 
   return e->rm()->free_area((l4_addr_t)guardaddr);
@@ -479,7 +471,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
 
       new_thread_bottom = (char *) map_addr + guardsize;
       err = e->rm()->attach(&new_thread_bottom, stacksize, L4Re::Rm::In_area,
-                            ds, 0);
+                            L4::Ipc::make_cap_rw(ds), 0);
 
       if (err < 0)
        {
@@ -567,7 +559,8 @@ int __pthread_mgr_create_thread(pthread_descr thread, char **tos,
 
   _t->ex_regs(l4_addr_t(__pthread_new_thread_entry), l4_addr_t(_tos), 0);
 
-  if (!(create_flags & PTHREAD_L4_ATTR_NO_START))
+  if (thread->p_start_args.start_routine
+      && !(create_flags & PTHREAD_L4_ATTR_NO_START))
     {
       l4_sched_param_t sp = l4_sched_param(prio >= 0 ? prio : 2);
       sp.affinity = affinity;
@@ -918,8 +911,11 @@ static void pthread_free(pthread_descr th)
 
 /* Handle threads that have exited */
 
-static void pthread_exited(pthread_descr th)
+static int pthread_exited(pthread_descr th)
 {
+  if (th->p_exited)
+    return 0;
+
   int detached;
   /* Remove thread from list of active threads */
   th->p_nextlive->p_prevlive = th->p_prevlive;
@@ -939,6 +935,8 @@ static void pthread_exited(pthread_descr th)
     restart(__pthread_main_thread);
     /* Same logic as REQ_MAIN_THREAD_EXIT. */
   }
+
+  return detached;
 }
 
 
@@ -959,8 +957,8 @@ static void pthread_handle_free(pthread_t th_id)
   }
   th = handle_to_descr(handle);
   __pthread_unlock(handle_to_lock(handle));
-  pthread_exited(th);
-  pthread_free(th);
+  if (!pthread_exited(th))
+    pthread_free(th);
 }
 
 /* Send a signal to all running threads */