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
#============================================================================
# Keep a pointer to the main scheduler context. This variable should be
# initialized to %rsp, which is done in the __sthread_start routine.
#
.data
.align 8
scheduler_context: .quad 0
#============================================================================
# __sthread_switch is the main entry point for the thread scheduler.
# It has three parts:
#
# 1. Save the context of the current thread on the stack.
# The context includes all of the integer registers and RFLAGS.
#
# 2. Call __sthread_scheduler (the C scheduler function), passing the
# context as an argument. The scheduler stack *must* be restored by
# setting %rsp to the scheduler_context before __sthread_scheduler is
# called.
#
# 3. __sthread_scheduler will return the context of a new thread.
# Restore the context, and return to the thread.
#
.text
.align 8
.globl __sthread_switch
__sthread_switch:
# Save the process state onto its stack
# TODO
# Call the high-level scheduler with the current context as an argument
movq %rsp, %rdi
movq scheduler_context(%rip), %rsp
call __sthread_scheduler
# The scheduler will return a context to start.
# Restore the context to resume the thread.
__sthread_restore:
# TODO
ret
#============================================================================
# Initialize a process context, given:
# 1. the stack for the process
# 2. the function to start
# 3. its argument
# The context should be consistent with that saved in the __sthread_switch
# routine.
#
# A pointer to the newly initialized context is returned to the caller.
# (This is the thread's stack-pointer after its context has been set up.)
#
# This function is described in more detail in sthread.c.
#
#
.align 8
.globl __sthread_initialize_context
__sthread_initialize_context:
# TODO
# TODO - Make sure you completely document every part of your
# thread context; what it is, and why you set each value
# to what you choose.
ret
#============================================================================
# The start routine initializes the scheduler_context variable, and calls
# the __sthread_scheduler with a NULL context.
#
# The scheduler will return a context to resume.
#
.align 8
.globl __sthread_start
__sthread_start:
# Remember the context
movq %rsp, scheduler_context(%rip)
# Call the scheduler with no context
movl $0, %edi # Also clears upper 4 bytes of %rdi
call __sthread_scheduler
# Restore the context returned by the scheduler
jmp __sthread_restore