-
Notifications
You must be signed in to change notification settings - Fork 0
/
machineprimitives.h
126 lines (105 loc) · 3.97 KB
/
machineprimitives.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
* This file provides an interface to the basic primitives that
* support the threads package, scheduler, and semaphore implementations.
* These primitives include those for allocating and manipulating stacks
* and for performing atomic operations. These portable interfaces to
* code written in assembler enable the threads package to be written
* in a high-level language.
*
* YOU SHOULD NOT [NEED TO] MODIFY THIS FILE.
*/
#ifndef __MINITHREAD_PUBLIC_H_
#define __MINITHREAD_PUBLIC_H_
#include "inttypes.h"
#include "defs.h"
typedef void *stack_pointer_t;
typedef int tas_lock_t; /* test-and-set locks. */
typedef int *arg_t; /* function argument */
typedef int (*proc_t)(arg_t); /* generic function pointer */
/*
* Allocate a fresh stack. Stacks are said to grow "down" (from higher
* memory locations towards lower ones) on the x86 architecture.
*
* The bottom of the stack is returned in *stackbase; the top of
* the stack is returned in *stacktop.
*
* -----------------
* | stacktop | <- next word pushed here
* | |
* | |
* | stackbase | <- bottom of stack.
* -----------------
*/
extern void minithread_allocate_stack(stack_pointer_t *stackbase,
stack_pointer_t *stacktop);
/*
* minithread_free_stack(stack_pointer_t stackbase)
*
* Frees the stack at stackbase. Care should be taken to ensure that the stack
* is not in use when it is freed.
*/
extern void minithread_free_stack(stack_pointer_t stackbase);
/*
* Initialize the stackframe pointed to by *stacktop so that
* the thread running off of *stacktop will invoke:
* body_proc(body_arg);
* final_proc(final_arg);
*
* The call to final_proc should be used for cleanup, since it is called
* when body_proc returns. final_proc should not return; doing so will
* lead to undefined behavior and likely cause your system to crash.
*
* body_proc and final_proc cannot be NULL. Passing invalid
* function pointers crashes the system.
*
* This procedure changes the value of *stacktop.
*
*/
extern void minithread_initialize_stack(stack_pointer_t *stacktop,
proc_t body_proc,
arg_t body_arg,
proc_t final_proc,
arg_t final_arg);
/* TODO: this needs to be documented */
extern void minithread_trampoline(proc_t interrupt, void * arg);
/* SYNCHRONIZATION PRIMITIVES */
/*
* Context switch primitive.
*
* This call will first save the caller's state (i.e. all of its registers) on
* the stack. It will then save the stack pointer in the location pointed to
* by old_thread_sp. It will replace the processor's stack pointer with the
* value pointed to by the new_thread_sp. Finally, it will reload the rest of
* the machine registers that were saved on the new thread's stack previously,
* and thus resume the new thread from where it left off.
*/
extern void minithread_switch(stack_pointer_t *old_thread_sp,
stack_pointer_t *new_thread_sp);
/* SYNCHRONIZATION PRIMITIVES */
/*
* Atomically test and set the value at l to 1. Return old value.
*/
extern int atomic_test_and_set(tas_lock_t *l);
/*
* Atomically set the value at l to 0.
*/
extern void atomic_clear(tas_lock_t *l);
/*
* Atomically set the value pointed to be x to be newval, and return
* the old value of x.
*/
extern int swap(int* x, int newval);
/*
* Atomic compare and swap.
* If the value pointed to by x is equal to oldval, then replace it with
* newval; regardless of the result of the comparison, return the original
* value of *x.
*/
extern int compare_and_swap(int* x, int oldval, int newval);
/*
* Returns the current time in milliseconds
* To be used only for timings - your OS should keep track of its
* own virtual time through clock interrupts.
*/
uint64_t currentTimeMillis();
#endif /*__MINITHREAD_PUBLIC_H_*/