More careful about memory allocations
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 25 Mar 2011 20:29:40 +0000 (13:29 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:01 +0000 (17:36 -0700)
Also note we could have been freeing the wrong size of stacks if someone
happened to use the attrs.

tests/Makefrag
tests/pthread_test.c
user/parlib/uthread.c
user/pthread/Makefile
user/pthread/pthread.c

index 4f1bbe8..de021c6 100644 (file)
@@ -2,7 +2,7 @@ TESTS_DIR = tests
 
 OBJDIRS += $(TESTS_DIR)
 
-TESTS_CFLAGS += $(USER_CFLAGS)
+TESTS_CFLAGS += $(USER_CFLAGS) -g
 
 ALL_TEST_FILES = $(shell ls $(TESTS_DIR)/*.c)
 
index 1f66856..878ddea 100644 (file)
@@ -3,6 +3,7 @@
 #include <stdlib.h>
 #include <parlib.h>
 #include <unistd.h>
+#include <vcore.h>
 
 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
 #define printf_safe(...) {}
@@ -11,70 +12,50 @@ pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
        printf(__VA_ARGS__); \
        pthread_mutex_unlock(&lock);
 
-pthread_t t1;
-pthread_t t2;
-pthread_t t3;
+#define MAX_NR_TEST_THREADS 100000
+int nr_yield_threads = 100;
+int nr_yield_loops = 100;
 
-#define NUM_TEST_THREADS 1000
-
-pthread_t my_threads[NUM_TEST_THREADS];
-void *my_retvals[NUM_TEST_THREADS];
+pthread_t my_threads[MAX_NR_TEST_THREADS];
+void *my_retvals[MAX_NR_TEST_THREADS];
 
 __thread int my_id;
 void *yield_thread(void* arg)
 {      
-       assert(!in_vcore_context());
-       for (int i = 0; i < 10; i++) {
-               printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
+       for (int i = 0; i < nr_yield_loops; i++) {
+               printf_safe("[A] pthread %d %p on vcore %d, itr: %d\n", pthread_self()->id,
+                      pthread_self(), vcore_id(), i);
                pthread_yield();
-               printf_safe("[A] pthread %d returned from yield on vcore %d\n",
-                           pthread_self()->id, vcore_id());
+               printf_safe("[A] pthread %p returned from yield on vcore %d, itr: %d\n",
+                           pthread_self(), vcore_id(), i);
        }
-       return (void*)(pthread_self()->id);
+       return (void*)(pthread_self());
 }
 
 void *hello_thread(void* arg)
 {      
-       printf_safe("[A] pthread %d on vcore %d\n", pthread_self()->id, vcore_id());
-       return (void*)(pthread_self()->id);
+       printf_safe("[A] pthread %p on vcore %d\n", pthread_self(), vcore_id());
+       return (void*)(pthread_self());
 }
 
 int main(int argc, char** argv) 
 {
-       void *retval1 = 0;
-       void *retval2 = 0;
-       void *retval3 = 0;
-
-       /* yield test */
-       printf_safe("[A] About to create thread 1\n");
-       pthread_create(&t1, NULL, &yield_thread, NULL);
-       printf_safe("[A] About to create thread 2\n");
-       pthread_create(&t2, NULL, &yield_thread, NULL);
-       printf_safe("[A] About to create thread 3\n");
-       pthread_create(&t3, NULL, &yield_thread, NULL);
-       /* join on them */
-       printf_safe("[A] About to join on thread 1\n");
-       pthread_join(t1, &retval1);
-       printf_safe("[A] Successfully joined on thread 1 (retval: %p)\n", retval1);
-       printf_safe("[A] About to join on thread 2\n");
-       pthread_join(t2, &retval2);
-       printf_safe("[A] Successfully joined on thread 2 (retval: %p)\n", retval2);
-       printf_safe("[A] About to join on thread 3\n");
-       pthread_join(t3, NULL);
-       printf_safe("[A] Successfully joined on thread 3 (retval: %p)\n", retval3);
-
-       /* create and join on hellos */
-       while (1) {
-               for (int i = 1; i < NUM_TEST_THREADS; i++) {
-                       printf_safe("[A] About to create thread %d\n", i);
-                       pthread_create(&my_threads[i], NULL, &hello_thread, NULL);
-               }
-               for (int i = 1; i < NUM_TEST_THREADS; i++) {
-                       printf_safe("[A] About to join on thread %d\n", i);
-                       pthread_join(my_threads[i], &my_retvals[i]);
-                       printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
-                                   my_retvals[i]);
-               }
-               break;
+       if (argc > 1)
+               nr_yield_threads = strtol(argv[1], 0, 10);
+       if (argc > 2)
+               nr_yield_loops = strtol(argv[2], 0, 10);
+       nr_yield_threads = MIN(nr_yield_threads, MAX_NR_TEST_THREADS);
+       printf("Making %d threads of %d loops each\n", nr_yield_threads, nr_yield_loops);
+       /* create and join on yield */
+       for (int i = 0; i < nr_yield_threads; i++) {
+               printf_safe("[A] About to create thread %d\n", i);
+               assert(!pthread_create(&my_threads[i], NULL, &yield_thread, NULL));
+       }
+       for (int i = 0; i < nr_yield_threads; i++) {
+               printf_safe("[A] About to join on thread %d(%p)\n", i, my_threads[i]);
+               pthread_join(my_threads[i], &my_retvals[i]);
+               printf_safe("[A] Successfully joined on thread %d (retval: %p)\n", i,
+                           my_retvals[i]);
        }
+       printf("Exiting cleanly!\n");
 } 
index a20cfd0..189e1df 100644 (file)
@@ -25,6 +25,7 @@ static int uthread_init(void)
        assert(sched_ops->sched_init);
        /* Get thread 0's thread struct (2LS allocs it) */
        struct uthread *uthread = sched_ops->sched_init();
+       assert(uthread);
        /* Save a pointer to thread0's tls region (the glibc one) into its tcb */
        uthread->tls_desc = get_tls_desc(0);
        /* Save a pointer to the uthread in its own TLS */
@@ -86,6 +87,7 @@ struct uthread *uthread_create(void (*func)(void), void *udata)
        assert(!in_vcore_context());
        assert(sched_ops->thread_create);
        struct uthread *new_thread = sched_ops->thread_create(func, udata);
+       assert(new_thread);
        new_thread->state = UT_CREATED;
        /* They should have zero'd the uthread.  Let's check critical things: */
        assert(!new_thread->flags && !new_thread->sysc);
index 9f24e4e..72e43d0 100644 (file)
@@ -1,5 +1,5 @@
 TARGET_ARCH ?= i686
-CFLAGS = -O2 -std=gnu99 -static -fomit-frame-pointer 
+CFLAGS = -O2 -std=gnu99 -static -fomit-frame-pointer -g
 LIBNAME = pthread
 V ?= @
 
index d181832..74097f6 100644 (file)
@@ -91,6 +91,7 @@ struct uthread *pth_init(void)
        }
        /* Create a pthread_tcb for the main thread */
        pthread_t t = (pthread_t)calloc(1, sizeof(struct pthread_tcb));
+       assert(t);
        t->id = get_next_pid();
        assert(t->id == 0);
 
@@ -161,6 +162,7 @@ struct uthread *pth_thread_create(void (*func)(void), void *udata)
        struct pthread_tcb *pthread;
        pthread_attr_t *attr = (pthread_attr_t*)udata;
        pthread = (pthread_t)calloc(1, sizeof(struct pthread_tcb));
+       assert(pthread);
        pthread->stacksize = PTHREAD_STACK_SIZE;        /* default */
        pthread->id = get_next_pid();
        pthread->detached = FALSE;                              /* default */
@@ -324,7 +326,7 @@ int pthread_attr_destroy(pthread_attr_t *a)
 
 static void __pthread_free_stack(struct pthread_tcb *pt)
 {
-       assert(!munmap(pt->stacktop - PTHREAD_STACK_SIZE, PTHREAD_STACK_SIZE));
+       assert(!munmap(pt->stacktop - pt->stacksize, pt->stacksize));
 }
 
 static int __pthread_allocate_stack(struct pthread_tcb *pt)