272
|
1
|
|
2 = processes / threads =
|
|
3
|
|
4 Processes are completely seperated and fully pre-emptive.
|
|
5 This means a process can be unscheduled at any moment.
|
|
6
|
|
7 Threads are co-operative. This means they yield control
|
|
8 voluntary. This means that mutexes and locks are not required.
|
|
9 This is done with the built-in language feature called tasks.
|
|
10
|
|
11 If some heavy duty task must be performed, either way spawn
|
|
12 a new process, or yield frequently from this hard labour.
|
|
13
|
|
14 = tasks =
|
|
15
|
|
16 Consider the following::
|
|
17
|
|
18 --
|
|
19 function int insanemath(int a)
|
|
20 {
|
|
21 while (a > 0)
|
|
22 {
|
|
23 a = a -1;
|
|
24 resume agent1;
|
|
25 }
|
|
26 return a - 1;
|
|
27 }
|
|
28
|
|
29 task agent1()
|
|
30 {
|
|
31 start agent2;
|
|
32 }
|
|
33
|
|
34 task agent2()
|
|
35 {
|
|
36 insanemath(55);
|
|
37 insanemath(44);
|
|
38 }
|
|
39
|
|
40 task main()
|
|
41 {
|
|
42 start agent1;
|
|
43 join agent1;
|
|
44 }
|
|
45 --
|
|
46
|
|
47 Say to tasks are running in concurrent / parallel.
|
|
48
|
|
49
|
|
50
|
|
51 Stack layout for tasks.
|
|
52 ||
|
|
53 ||
|
|
54 \/
|
|
55 +---------+
|
|
56 | return address
|
|
57 | locals
|
|
58 |
|
|
59 +------
|
|
60 | return address
|
|
61 | locals
|
|
62 |
|
|
63 +---
|
|
64
|
|
65 Assembly code for the functions above:
|
|
66
|
|
67 .code
|
|
68 insanemath:
|
|
69 L1:
|
|
70 load r0, sp - 4
|
|
71 cmp r0, 0
|
|
72 jl L2
|
|
73 dec r0
|
|
74 store r0, sp - 4
|
|
75 jmp L1
|
|
76 L2:
|
|
77 ret
|
|
78
|
|
79 agent1:
|
|
80 hlt?
|
|
81
|
|
82 agent2:
|
|
83 hlt?
|
|
84
|
|
85 main:
|
|
86 jmp agent1
|
|
87
|
|
88 .data
|
|
89 agent1_task:
|
|
90 dd 0
|
|
91 agent2_task:
|
|
92 dd 0
|
|
93
|