Adding pthread support for stacksize options and detached threads.
authorDavid Zhu <yuzhu@cs.berkeley.edu>
Fri, 28 Jan 2011 22:41:23 +0000 (14:41 -0800)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:57 +0000 (17:35 -0700)
Mainly done to support Redis compilation, but should be useful for others.

user/include/pthread.h
user/parlib/pthread.c

index 185fe9e..b10f068 100644 (file)
@@ -19,6 +19,7 @@ struct pthread_tcb {
        struct ancillary_state as;
        void *tls_desc;
        void *stacktop;
+       uint32_t stacksize;
        uint32_t id;
 
        int finished;
@@ -32,15 +33,6 @@ struct pthread_tcb {
 typedef struct pthread_tcb* pthread_t;
 TAILQ_HEAD(pthread_queue, pthread_tcb);
 
-/* For compatibility with the existing pthread library */
-enum
-{
-  PTHREAD_CREATE_JOINABLE,
-#define PTHREAD_CREATE_JOINABLE        PTHREAD_CREATE_JOINABLE
-  PTHREAD_CREATE_DETACHED
-#define PTHREAD_CREATE_DETACHED        PTHREAD_CREATE_DETACHED
-};
-
 #define PTHREAD_ONCE_INIT 0
 #define PTHREAD_BARRIER_SERIAL_THREAD 12345
 #define PTHREAD_MUTEX_INITIALIZER {0}
@@ -79,6 +71,21 @@ typedef struct
 #define WAITER_WAITING 1
 #define SLOT_FREE 0
 #define SLOT_IN_USE 1
+
+/* Detach state.  */
+enum
+{
+  PTHREAD_CREATE_JOINABLE,
+#define PTHREAD_CREATE_JOINABLE        PTHREAD_CREATE_JOINABLE
+  PTHREAD_CREATE_DETACHED
+#define PTHREAD_CREATE_DETACHED        PTHREAD_CREATE_DETACHED
+};
+
+// TODO: how big do we want these?  ideally, we want to be able to guard and map
+// more space if we go too far.
+#define PTHREAD_STACK_PAGES 4
+#define PTHREAD_STACK_SIZE (PTHREAD_STACK_PAGES*PGSIZE)
+
 typedef struct
 {
   int pshared;
@@ -92,8 +99,11 @@ typedef struct
   int in_use[MAX_PTHREADS];
   int next_waiter; //start the search for an available waiter at this spot
 } pthread_cond_t;
-
-typedef int pthread_attr_t;
+typedef struct 
+{
+       size_t stacksize;
+       int detached;
+} pthread_attr_t;
 typedef int pthread_barrierattr_t;
 typedef int pthread_once_t;
 typedef void** pthread_key_t;
@@ -150,6 +160,12 @@ int pthread_barrier_init(pthread_barrier_t* b, const pthread_barrierattr_t* a, i
 int pthread_barrier_wait(pthread_barrier_t* b);
 int pthread_barrier_destroy(pthread_barrier_t* b);
 
+//added for redis compile
+int pthread_detach (pthread_t __th);
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize);
+int pthread_attr_getstacksize(const pthread_attr_t *attr, 
+    size_t *stacksize);
+
 #ifdef __cplusplus
   }
 #endif
index 08679df..2364879 100644 (file)
@@ -141,12 +141,17 @@ void __attribute__((noreturn)) vcore_entry()
 
 int pthread_attr_init(pthread_attr_t *a)
 {
-  return 0;
+       a = malloc(sizeof (pthread_attr_t));
+       if (!a) return -1;
+       a->stacksize = PTHREAD_STACK_SIZE;
+       a->detached = PTHREAD_CREATE_JOINABLE;
+       return 0;
 }
 
 int pthread_attr_destroy(pthread_attr_t *a)
 {
-  return 0;
+       free(a);
+       return 0;
 }
 
 /* TODO: probably don't want to dealloc.  Considering caching */
@@ -170,10 +175,6 @@ static int __pthread_allocate_tls(struct pthread_tcb *pt)
        return 0;
 }
 
-// TODO: how big do we want these?  ideally, we want to be able to guard and map
-// more space if we go too far.
-#define PTHREAD_STACK_PAGES 4
-#define PTHREAD_STACK_SIZE (PTHREAD_STACK_PAGES*PGSIZE)
 
 static void __pthread_free_stack(struct pthread_tcb *pt)
 {
@@ -182,12 +183,12 @@ static void __pthread_free_stack(struct pthread_tcb *pt)
 
 static int __pthread_allocate_stack(struct pthread_tcb *pt)
 {
-       void* stackbot = mmap(0, PTHREAD_STACK_SIZE,
+       void* stackbot = mmap(0, pt->stacksize,
                              PROT_READ|PROT_WRITE|PROT_EXEC,
                              MAP_POPULATE|MAP_ANONYMOUS, -1, 0);
        if (stackbot == MAP_FAILED)
                return -1; // errno set by mmap
-       pt->stacktop = stackbot + PTHREAD_STACK_SIZE;
+       pt->stacktop = stackbot + pt->stacksize;
        return 0;
 }
 
@@ -204,6 +205,17 @@ static int get_next_pid(void)
        return next_pid++;
 }
 
+
+int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
+{
+       attr->stacksize = stacksize;
+}
+int pthread_attr_getstacksize(const pthread_attr_t *attr, 
+    size_t *stacksize)
+{
+       *stacksize = attr->stacksize;
+}
+
 int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
                    void *(*start_routine)(void *), void* arg)
 {
@@ -220,6 +232,15 @@ int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
        (*thread)->start_routine = start_routine;
        (*thread)->arg = arg;
        (*thread)->id = get_next_pid();
+       /* Respect the attributes*/
+       if (attr){
+               if (attr->stacksize)
+                       (*thread)->stacksize = attr->stacksize;
+               else 
+                       (*thread)->stacksize = PTHREAD_STACK_SIZE;
+               (*thread)->detached = attr->detached;
+       }
+
        if (__pthread_allocate_stack(*thread) ||  __pthread_allocate_tls(*thread))
                printf("We're fucked\n");
        /* Save the ptr to the new pthread in that pthread's TLS */
@@ -341,8 +362,7 @@ int pthread_mutexattr_destroy(pthread_mutexattr_t* attr)
 
 
 int pthread_attr_setdetachstate(pthread_attr_t *__attr,int __detachstate) {
-       *__attr = __detachstate;
-       // TODO: the right thing
+       __attr->detached = __detachstate;
        return 0;
 }
 
@@ -605,3 +625,7 @@ int pthread_barrier_destroy(pthread_barrier_t* b)
   pthread_mutex_destroy(&b->pmutex);
   return 0;
 }
+
+int pthread_detach (pthread_t thread){
+       thread->detached = 1;
+}