From e25fc7e784bc78c83bc1b07b595711957782432a Mon Sep 17 00:00:00 2001 From: Avi Kivity <avi@cloudius-systems.com> Date: Tue, 7 May 2013 19:10:26 +0300 Subject: [PATCH] pthread: drop pthread's zombie reaper Use the generic one instead; the cleanup function allows destroying the pthread object. --- libc/pthread.cc | 61 +++---------------------------------------------- loader.cc | 1 - 2 files changed, 3 insertions(+), 59 deletions(-) diff --git a/libc/pthread.cc b/libc/pthread.cc index 34a1cae16..e3556cbb5 100644 --- a/libc/pthread.cc +++ b/libc/pthread.cc @@ -15,58 +15,6 @@ namespace pthread_private { - // Because a pthread cannot pthread_join() itself (this will destroy - // the stack currently in use), provide a separate thread which joins - // exiting detached pthreads. - // This is code duplication from sched::detached_thread::reaper - // TODO: Have one class (and even one thread) do both. - class reaper { - public: - reaper(); - void add_zombie(pthread_t z); - private: - void reap(); - mutex _mtx; - std::list<pthread_t> _zombies; - sched::thread _thread; - }; - - reaper::reaper() : _mtx{}, _zombies{}, _thread([=] { reap(); }) - { - _thread.start(); - } - - void reaper::reap() - { - while (true) { - with_lock(_mtx, [=] { - sched::thread::wait_until(_mtx, - [=] { return !_zombies.empty(); }); - while (!_zombies.empty()) { - auto z = _zombies.front(); - _zombies.pop_front(); - pthread_join(z, nullptr); - } - }); - } - } - - void reaper::add_zombie(pthread_t z) - { - with_lock(_mtx, [=] { - _zombies.push_back(z); - _thread.wake(); - }); - } - - reaper *s_reaper; - - void init_detached_pthreads_reaper() - { - s_reaper = new reaper; - } - - const unsigned tsd_nkeys = 100; __thread void* tsd[tsd_nkeys]; @@ -115,14 +63,9 @@ namespace pthread_private { current_pthread = to_libc(); sigprocmask(SIG_SETMASK, &sigset, nullptr); _retval = start(arg); - if (attr && attr->detached) { - // It would have been nice to just call pthread_join here, - // but this would be messy because we'll free the stack we - // are using now... So do this from another thread. - pthread_private::s_reaper->add_zombie(current_pthread); - } }, attributes(attr ? *attr : thread_attr())) { + _thread.set_cleanup([=] { delete this; }); _thread.start(); } @@ -130,6 +73,7 @@ namespace pthread_private { { sched::thread::attr a; a.stack = allocate_stack(attr); + a.detached = attr.detached; return a; } @@ -153,6 +97,7 @@ namespace pthread_private { int pthread::join(void** retval) { + _thread.set_cleanup({}); _thread.join(); if (retval) { *retval = _retval; diff --git a/loader.cc b/loader.cc index f7f4dd44a..7ddecf015 100644 --- a/loader.cc +++ b/loader.cc @@ -208,7 +208,6 @@ void main_cont(int ac, char** av) memory::enable_debug_allocator(); enable_trace(); sched::init_detached_threads_reaper(); - pthread_private::init_detached_pthreads_reaper(); vfs_init(); ramdisk_init(); -- GitLab