[haiku-commits] r33967 - in haiku/trunk: headers/private/libroot headers/private/system src/system/libroot/os src/system/libroot/posix/pthread

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 9 Nov 2009 22:33:35 +0100 (CET)

Author: axeld
Date: 2009-11-09 22:33:35 +0100 (Mon, 09 Nov 2009)
New Revision: 33967
Changeset: http://dev.haiku-os.org/changeset/33967/haiku

Added:
   haiku/trunk/headers/private/libroot/pthread_private.h
Removed:
   haiku/trunk/src/system/libroot/posix/pthread/pthread_private.h
Modified:
   haiku/trunk/headers/private/system/tls.h
   haiku/trunk/src/system/libroot/os/thread.c
   haiku/trunk/src/system/libroot/posix/pthread/pthread.c
Log:
* The pthread_thread structure is now allocated for all threads.
* Therefore, all pthread functions should now work fine on all threads.


Copied: haiku/trunk/headers/private/libroot/pthread_private.h (from rev 33960, 
haiku/trunk/src/system/libroot/posix/pthread/pthread_private.h)
===================================================================
--- haiku/trunk/headers/private/libroot/pthread_private.h                       
        (rev 0)
+++ haiku/trunk/headers/private/libroot/pthread_private.h       2009-11-09 
21:33:35 UTC (rev 33967)
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2003-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Copyright 2007, Ryan Leavengood, leavengood@xxxxxxxxxx
+ * All rights reserved. Distributed under the terms of the MIT License.
+ */
+#ifndef _PTHREAD_PRIVATE_H_
+#define _PTHREAD_PRIVATE_H_
+
+
+#include <pthread.h>
+
+#include <OS.h>
+
+// The public *_t types are only pointers to these structures
+// This way, we are completely free to change them, which might be
+// necessary in the future (not only due to the incomplete implementation
+// at this point).
+
+typedef struct _pthread_condattr {
+       bool            process_shared;
+} pthread_condattr;
+
+typedef struct _pthread_mutexattr {
+       int32           type;
+       bool            process_shared;
+} pthread_mutexattr;
+
+typedef struct _pthread_attr {
+       int32           detach_state;
+       int32           sched_priority;
+       size_t          stack_size;
+} pthread_attr;
+
+typedef struct _pthread_rwlockattr {
+       uint32_t        flags;
+} pthread_rwlockattr;
+
+typedef void (*pthread_key_destructor)(void *data);
+
+struct pthread_key {
+       vint32          sequence;
+       pthread_key_destructor destructor;
+};
+
+struct pthread_key_data {
+       vint32          sequence;
+       void            *value;
+};
+
+#define PTHREAD_UNUSED_SEQUENCE        0
+
+typedef struct _pthread_thread {
+       thread_id       id;
+       int32           flags;
+       void            *(*entry)(void*);
+       void            *entry_argument;
+       void            *exit_value;
+       int                     cancel_state;
+       int                     cancel_type;
+       bool            cancelled;
+       struct pthread_key_data specific[PTHREAD_KEYS_MAX];
+       struct __pthread_cleanup_handler *cleanup_handlers;
+} pthread_thread;
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void __pthread_key_call_destructors(pthread_thread *thread);
+void __pthread_destroy_thread(void);
+pthread_thread *__allocate_pthread(void *data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _PTHREAD_PRIVATE_H_ */

Modified: haiku/trunk/headers/private/system/tls.h
===================================================================
--- haiku/trunk/headers/private/system/tls.h    2009-11-09 21:26:24 UTC (rev 
33966)
+++ haiku/trunk/headers/private/system/tls.h    2009-11-09 21:33:35 UTC (rev 
33967)
@@ -1,10 +1,11 @@
-/* 
-** Copyright 2003, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights reserved.
-** Distributed under the terms of the OpenBeOS License.
-*/
+/*
+ * Copyright 2003-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
 #ifndef _KERNEL_TLS_H
 #define _KERNEL_TLS_H
 
+
 #include <support/TLS.h>
 
 
@@ -18,6 +19,7 @@
        TLS_ERRNO_SLOT,
        TLS_ON_EXIT_THREAD_SLOT,
        TLS_USER_THREAD_SLOT,
+       TLS_PTHREAD_SLOT,
 
        // Note: these entries can safely be changed between
        // releases; 3rd party code always calls tls_allocate()

Modified: haiku/trunk/src/system/libroot/os/thread.c
===================================================================
--- haiku/trunk/src/system/libroot/os/thread.c  2009-11-09 21:26:24 UTC (rev 
33966)
+++ haiku/trunk/src/system/libroot/os/thread.c  2009-11-09 21:33:35 UTC (rev 
33967)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2005, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx All rights 
reserved.
+ * Copyright 2002-2009, Axel Dörfler, axeld@xxxxxxxxxxxxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
@@ -10,6 +10,7 @@
 #include <stdio.h>
 
 #include <libroot_private.h>
+#include <pthread_private.h>
 #include <thread_defs.h>
 #include <tls.h>
 #include <syscalls.h>
@@ -29,22 +30,56 @@
 void _thread_do_exit_notification(void);
 
 
-static int32
-thread_entry(thread_func entry, void *data)
+static status_t
+thread_entry(thread_func entry, void* _thread)
 {
-       int32 returnCode = entry(data);
+       pthread_thread* thread = (pthread_thread*)_thread;
+       status_t returnCode;
 
+       *tls_address(TLS_PTHREAD_SLOT) = thread;
+
+       returnCode = entry(thread->entry_argument);
+
        _thread_do_exit_notification();
 
        return returnCode;
 }
 
 
+void
+_thread_do_exit_notification(void)
+{
+       callback_node *node = tls_get(TLS_ON_EXIT_THREAD_SLOT);
+       callback_node *next;
+
+       while (node != NULL) {
+               next = node->next;
+
+               node->function(node->argument);
+               free(node);
+
+               node = next;
+       }
+
+       tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL);
+
+       __pthread_destroy_thread();
+}
+
+
+// #pragma mark -
+
+
 thread_id
 spawn_thread(thread_func entry, const char *name, int32 priority, void *data)
 {
        struct thread_creation_attributes attributes;
+       pthread_thread* thread;
 
+       thread = __allocate_pthread(data);
+       if (thread == NULL)
+               return B_NO_MEMORY;
+
        _single_threaded = false;
                // used for I/O locking - BeOS compatibility issue
 
@@ -52,7 +87,7 @@
        attributes.name = name;
        attributes.priority = priority;
        attributes.args1 = entry;
-       attributes.args2 = data;
+       attributes.args2 = thread;
        attributes.stack_address = NULL;
        attributes.stack_size = 0;
 
@@ -110,25 +145,6 @@
 }
 
 
-void
-_thread_do_exit_notification(void)
-{
-       callback_node *node = tls_get(TLS_ON_EXIT_THREAD_SLOT);
-       callback_node *next;
-
-       while (node != NULL) {
-               next = node->next;
-
-               node->function(node->argument);
-               free(node);
-
-               node = next;
-       }
-
-       tls_set(TLS_ON_EXIT_THREAD_SLOT, NULL);
-}
-
-
 status_t
 on_exit_thread(void (*callback)(void *), void *data)
 {

Modified: haiku/trunk/src/system/libroot/posix/pthread/pthread.c
===================================================================
--- haiku/trunk/src/system/libroot/posix/pthread/pthread.c      2009-11-09 
21:26:24 UTC (rev 33966)
+++ haiku/trunk/src/system/libroot/posix/pthread/pthread.c      2009-11-09 
21:33:35 UTC (rev 33967)
@@ -14,6 +14,7 @@
 
 #include <syscalls.h>
 #include <thread_defs.h>
+#include <tls.h>
 
 
 #define THREAD_DETACHED        0x01
@@ -28,13 +29,28 @@
 
 
 static pthread_thread sMainThread;
-static int32 sPthreadSlot = -1;
 static int sConcurrencyLevel;
 
 
-static void
-pthread_destroy_thread(void* data)
+static status_t
+pthread_thread_entry(thread_func _unused, void* _thread)
 {
+       pthread_thread* thread = (pthread_thread*)_thread;
+
+       // store thread data in TLS
+       *tls_address(TLS_PTHREAD_SLOT) = thread;
+
+       pthread_exit(thread->entry(thread->entry_argument));
+       return 0;
+}
+
+
+// #pragma mark - private API
+
+
+void
+__pthread_destroy_thread(void)
+{
        pthread_thread* thread = pthread_self();
 
        // call cleanup handlers
@@ -54,18 +70,23 @@
 }
 
 
-static int32
-pthread_thread_entry(thread_func _unused, void* _thread)
+pthread_thread*
+__allocate_pthread(void *data)
 {
-       pthread_thread* thread = (pthread_thread*)_thread;
+       pthread_thread* thread = 
(pthread_thread*)malloc(sizeof(pthread_thread));
+       if (thread == NULL)
+               return NULL;
 
-       // store thread data in TLS
-       *tls_address(sPthreadSlot) = thread;
+       thread->entry = NULL;
+       thread->entry_argument = data;
+       thread->exit_value = NULL;
+       thread->cancel_state = PTHREAD_CANCEL_ENABLE;
+       thread->cancel_type = PTHREAD_CANCEL_DEFERRED;
+       thread->cancelled = false;
+       thread->cleanup_handlers = NULL;
+       thread->flags = 0;
 
-       on_exit_thread(pthread_destroy_thread, NULL);
-
-       pthread_exit(thread->entry(thread->entry_argument));
-       return 0;
+       return thread;
 }
 
 
@@ -91,27 +112,15 @@
                        return EINVAL;
        }
 
-       thread = (pthread_thread*)malloc(sizeof(pthread_thread));
+       thread = __allocate_pthread(arg);
        if (thread == NULL)
                return EAGAIN;
 
        thread->entry = startRoutine;
-       thread->entry_argument = arg;
-       thread->exit_value = NULL;
-       thread->cancel_state = PTHREAD_CANCEL_ENABLE;
-       thread->cancel_type = PTHREAD_CANCEL_DEFERRED;
-       thread->cancelled = false;
-       thread->cleanup_handlers = NULL;
-       thread->flags = 0;
 
        if (attr->detach_state == PTHREAD_CREATE_DETACHED)
                thread->flags |= THREAD_DETACHED;
 
-       if (sPthreadSlot == -1) {
-               // In a clean pthread environment, this is even thread-safe!
-               sPthreadSlot = tls_allocate();
-       }
-
        attributes.entry = pthread_thread_entry;
        attributes.name = "pthread func";
        attributes.priority = attr->sched_priority;
@@ -139,10 +148,7 @@
 {
        pthread_thread* thread;
 
-       if (sPthreadSlot == -1)
-               return &sMainThread;
-
-       thread = (pthread_thread*)tls_get(sPthreadSlot);
+       thread = (pthread_thread*)tls_get(TLS_PTHREAD_SLOT);
        if (thread == NULL)
                return &sMainThread;
 


Other related posts:

  • » [haiku-commits] r33967 - in haiku/trunk: headers/private/libroot headers/private/system src/system/libroot/os src/system/libroot/posix/pthread - axeld