summaryrefslogtreecommitdiffstats
path: root/pintos-progos/threads/switch.S
diff options
context:
space:
mode:
Diffstat (limited to 'pintos-progos/threads/switch.S')
-rw-r--r--pintos-progos/threads/switch.S65
1 files changed, 65 insertions, 0 deletions
diff --git a/pintos-progos/threads/switch.S b/pintos-progos/threads/switch.S
new file mode 100644
index 0000000..feca86c
--- /dev/null
+++ b/pintos-progos/threads/switch.S
@@ -0,0 +1,65 @@
1#include "threads/switch.h"
2
3#### struct thread *switch_threads (struct thread *cur, struct thread *next);
4####
5#### Switches from CUR, which must be the running thread, to NEXT,
6#### which must also be running switch_threads(), returning CUR in
7#### NEXT's context.
8####
9#### This function works by assuming that the thread we're switching
10#### into is also running switch_threads(). Thus, all it has to do is
11#### preserve a few registers on the stack, then switch stacks and
12#### restore the registers. As part of switching stacks we record the
13#### current stack pointer in CUR's thread structure.
14
15.globl switch_threads
16.func switch_threads
17switch_threads:
18 # Save caller's register state.
19 #
20 # Note that the SVR4 ABI allows us to destroy %eax, %ecx, %edx,
21 # but requires us to preserve %ebx, %ebp, %esi, %edi. See
22 # [SysV-ABI-386] pages 3-11 and 3-12 for details.
23 #
24 # This stack frame must match the one set up by thread_create()
25 # in size.
26 pushl %ebx
27 pushl %ebp
28 pushl %esi
29 pushl %edi
30
31 # Get offsetof (struct thread, stack).
32.globl thread_stack_ofs
33 mov thread_stack_ofs, %edx
34
35 # Save current stack pointer to old thread's stack, if any.
36 movl SWITCH_CUR(%esp), %eax
37 movl %esp, (%eax,%edx,1)
38
39 # Restore stack pointer from new thread's stack.
40 movl SWITCH_NEXT(%esp), %ecx
41 movl (%ecx,%edx,1), %esp
42
43 # Restore caller's register state.
44 popl %edi
45 popl %esi
46 popl %ebp
47 popl %ebx
48 ret
49.endfunc
50
51.globl switch_entry
52.func switch_entry
53switch_entry:
54 # Discard switch_threads() arguments.
55 addl $8, %esp
56
57 # Call thread_schedule_tail(prev).
58 pushl %eax
59.globl thread_schedule_tail
60 call thread_schedule_tail
61 addl $4, %esp
62
63 # Start thread proper.
64 ret
65.endfunc