Changes needed to run on OS X... Example runs on my laptop now. No need to push...
[c11tester.git] / threads.cc
1 #include "libthreads.h"
2 #include "common.h"
3 #include "threads.h"
4
5 /* global "model" object */
6 #include "model.h"
7
8 #define STACK_SIZE (1024 * 1024)
9
10 static void * stack_allocate(size_t size)
11 {
12         return malloc(size);
13 }
14
15 static void stack_free(void *stack)
16 {
17         free(stack);
18 }
19
20 Thread * thread_current(void)
21 {
22         return model->scheduler->get_current_thread();
23 }
24
25 /* This method just gets around makecontext not being 64-bit clean */
26
27 void thread_startup() {
28         Thread * curr_thread = thread_current();
29         curr_thread->start_routine(curr_thread->arg);
30 }
31
32 int Thread::create_context()
33 {
34         int ret;
35
36         ret = getcontext(&context);
37         if (ret)
38                 return ret;
39
40         /* Initialize new managed context */
41         stack = stack_allocate(STACK_SIZE);
42         context.uc_stack.ss_sp = stack;
43         context.uc_stack.ss_size = STACK_SIZE;
44         context.uc_stack.ss_flags = 0;
45         context.uc_link = model->get_system_context();
46         makecontext(&context, thread_startup, 0);
47
48         return 0;
49 }
50
51 int Thread::swap(Thread *t, ucontext_t *ctxt)
52 {
53         return swapcontext(&t->context, ctxt);
54 }
55
56 int Thread::swap(ucontext_t *ctxt, Thread *t)
57 {
58         return swapcontext(ctxt, &t->context);
59 }
60
61 void Thread::complete()
62 {
63         if (state != THREAD_COMPLETED) {
64                 DEBUG("completed thread %d\n", get_id());
65                 state = THREAD_COMPLETED;
66                 if (stack)
67                         stack_free(stack);
68         }
69 }
70
71 Thread::Thread(thrd_t *t, void (*func)(void *), void *a) {
72         int ret;
73
74         user_thread = t;
75         start_routine = func;
76         arg = a;
77
78         /* Initialize state */
79         ret = create_context();
80         if (ret)
81                 printf("Error in create_context\n");
82
83         state = THREAD_CREATED;
84         id = model->get_next_id();
85         *user_thread = id;
86         parent = thread_current();
87 }
88
89 Thread::~Thread()
90 {
91         complete();
92         model->remove_thread(this);
93 }
94
95 thread_id_t Thread::get_id()
96 {
97         return id;
98 }