fix code to be 64 bit clean
[c11tester.git] / threads.cc
1 /* -*- Mode: C; indent-tabs-mode: t -*- */
2
3 #include "libthreads.h"
4 #include "common.h"
5 #include "threads.h"
6
7 /* global "model" object */
8 #include "model.h"
9
10 #define STACK_SIZE (1024 * 1024)
11
12 static void * stack_allocate(size_t size)
13 {
14         return userMalloc(size);
15 }
16
17 static void stack_free(void *stack)
18 {
19         userFree(stack);
20 }
21
22 Thread * thread_current(void)
23 {
24         return model->scheduler->get_current_thread();
25 }
26
27 /* This method just gets around makecontext not being 64-bit clean */
28
29 void thread_startup() {
30         Thread * curr_thread=thread_current();
31         curr_thread->start_routine(curr_thread->arg);
32 }
33
34 int Thread::create_context()
35 {
36         int ret;
37
38         ret = getcontext(&context);
39         if (ret)
40                 return ret;
41
42         /* Initialize new managed context */
43         stack = stack_allocate(STACK_SIZE);
44         context.uc_stack.ss_sp = stack;
45         context.uc_stack.ss_size = STACK_SIZE;
46         context.uc_stack.ss_flags = 0;
47         context.uc_link = model->get_system_context();
48         makecontext(&context, start_routine, 1);
49
50         return 0;
51 }
52
53 int Thread::swap(Thread *t, ucontext_t *ctxt)
54 {
55         return swapcontext(&t->context, ctxt);
56 }
57
58 int Thread::swap(ucontext_t *ctxt, Thread *t)
59 {
60         return swapcontext(ctxt, &t->context);
61 }
62
63 void Thread::complete()
64 {
65         if (state != THREAD_COMPLETED) {
66                 DEBUG("completed thread %d\n", get_id());
67                 state = THREAD_COMPLETED;
68                 if (stack)
69                         stack_free(stack);
70         }
71 }
72
73 Thread::Thread(thrd_t *t, void (*func)(), void *a) {
74         int ret;
75
76         user_thread = t;
77         start_routine = func;
78         arg = a;
79
80         /* Initialize state */
81         ret = create_context();
82         if (ret)
83                 printf("Error in create_context\n");
84
85         state = THREAD_CREATED;
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 }