threads: use constructor initializer list
[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         start_routine(func),
74         arg(a),
75         user_thread(t),
76         state(THREAD_CREATED),
77         last_action_val(VALUE_NONE)
78 {
79         int ret;
80
81         /* Initialize state */
82         ret = create_context();
83         if (ret)
84                 printf("Error in create_context\n");
85
86         id = model->get_next_id();
87         *user_thread = id;
88         parent = thread_current();
89 }
90
91 Thread::~Thread()
92 {
93         complete();
94         model->remove_thread(this);
95 }
96
97 thread_id_t Thread::get_id()
98 {
99         return id;
100 }