trivial changes
[cdsspec-compiler.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         ASSERT(model);
23         return model->scheduler->get_current_thread();
24 }
25
26 /* This method just gets around makecontext not being 64-bit clean */
27
28 void thread_startup() {
29         Thread * curr_thread = thread_current();
30         curr_thread->start_routine(curr_thread->arg);
31 }
32
33 int Thread::create_context()
34 {
35         int ret;
36
37         ret = getcontext(&context);
38         if (ret)
39                 return ret;
40
41         /* Initialize new managed context */
42         stack = stack_allocate(STACK_SIZE);
43         context.uc_stack.ss_sp = stack;
44         context.uc_stack.ss_size = STACK_SIZE;
45         context.uc_stack.ss_flags = 0;
46         context.uc_link = model->get_system_context();
47         makecontext(&context, thread_startup, 0);
48
49         return 0;
50 }
51
52 int Thread::swap(Thread *t, ucontext_t *ctxt)
53 {
54         return swapcontext(&t->context, ctxt);
55 }
56
57 int Thread::swap(ucontext_t *ctxt, Thread *t)
58 {
59         return swapcontext(ctxt, &t->context);
60 }
61
62 void Thread::complete()
63 {
64         if (state != THREAD_COMPLETED) {
65                 DEBUG("completed thread %d\n", get_id());
66                 state = THREAD_COMPLETED;
67                 if (stack)
68                         stack_free(stack);
69         }
70 }
71
72 Thread::Thread(thrd_t *t, void (*func)(void *), void *a) {
73         int ret;
74
75         user_thread = t;
76         start_routine = func;
77         arg = a;
78
79         /* Initialize state */
80         ret = create_context();
81         if (ret)
82                 printf("Error in create_context\n");
83
84         state = THREAD_CREATED;
85         id = model->get_next_id();
86         *user_thread = id;
87         parent = thread_current();
88 }
89
90 Thread::~Thread()
91 {
92         complete();
93         model->remove_thread(this);
94 }
95
96 thread_id_t Thread::get_id()
97 {
98         return id;
99 }