mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-27 14:58:30 +00:00
Improve pthread_join()
Since we're now on Windows 8, we can have clone() work as advertised on Windows, where it sends a futex wake to the child tid. It's also likely we no longer need to work around thread flakes on OpenBSD, in _wait0().
This commit is contained in:
parent
3733b43a8f
commit
994e1f4386
19 changed files with 154 additions and 74 deletions
|
@ -16,36 +16,43 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/atomic.h"
|
||||
#include "libc/thread/thread.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/thread/posixthread.internal.h"
|
||||
#include "libc/thread/spawn.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
/**
|
||||
* Asks POSIX thread to free itself automatically on termination.
|
||||
*
|
||||
* @return 0 on success, or errno with error
|
||||
* @raise EINVAL if thread is null or already detached
|
||||
*/
|
||||
int pthread_detach(pthread_t thread) {
|
||||
struct PosixThread *pt;
|
||||
enum PosixThreadStatus status;
|
||||
struct PosixThread *pt = (struct PosixThread *)thread;
|
||||
if (!(pt = (struct PosixThread *)thread)) {
|
||||
return EINVAL;
|
||||
}
|
||||
for (;;) {
|
||||
status = atomic_load_explicit(&pt->status, memory_order_relaxed);
|
||||
status = atomic_load_explicit(&pt->status, memory_order_acquire);
|
||||
if (status == kPosixThreadDetached || status == kPosixThreadZombie) {
|
||||
// these two states indicate the thread was already detached, in
|
||||
// which case it's already listed under _pthread_zombies.
|
||||
break;
|
||||
return EINVAL;
|
||||
} else if (status == kPosixThreadTerminated) {
|
||||
// thread was joinable and finished running. since pthread_join
|
||||
// won't be called, it's safe to free the thread resources now.
|
||||
// POSIX says this could be reported as ESRCH but then our test
|
||||
// code would be less elegant in order for it to avoid flaking.
|
||||
_pthread_wait(pt);
|
||||
_pthread_free(pt);
|
||||
break;
|
||||
} else if (status == kPosixThreadJoinable) {
|
||||
if (atomic_compare_exchange_weak_explicit(
|
||||
&pt->status, &status, kPosixThreadDetached, memory_order_acquire,
|
||||
&pt->status, &status, kPosixThreadDetached, memory_order_release,
|
||||
memory_order_relaxed)) {
|
||||
_pthread_zombies_add(pt);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue