README.md
1`pincputest` shall verify that a peer thread being pinned to a new cpu is
2rescheduled properly; particular attention shall be given to situations
3where the thread can be rescheduled right away.
4
5In order to cover all cases, the test shall ensure that the peer thread
6rescheduling happens:
71. in any possible state of the peer thread (running, ready, blocked, sleeping),
82. whether the newly pinned cpu is the current cpu or another cpu
93. whether the thread from which the peer thread is pinned is a higher
10 or lower priority than the peer thread
114. and finally whether the involved threads are standard or real-time threads.
12
13Note: the real-time threads are not collaboratively time-sliced with other threads
14on their current cpu. This implies that a real-time thread will have to become
15BLOCKED or SLEEPING before it can be interrupted.
16
17In order to be able to set the peer thread in a given state, we need to use
18a control thread with same or higher priority than the peer thread.
19This control thread will be the `unittest thread`. The thread responsible
20for pinning the `peer` thread is called the `main` thread.
21
22Below sections illustrates the interactions between the `unittest` thread, the `main` thread and the `peer` thread to reach the expected `peer` thread state in the various
23cases described above.
24
25## Testing `thread_set_pinned_cpu` on a `[RUNNING]` peer
26
27```mermaid
28
29sequenceDiagram
30 participant U as unitest thread (priority peer+1)
31 participant M as main thread (priority peer+/-1)
32 participant P as peer thread (priority peer)
33 Note over U, P: Testing thread_set_pinned_cpu on a [RUNNING] peer
34 Note over M: main [BLOCKED]
35 Note over P: peer [BLOCKED]
36 U->>U:thread_set_pinned_cpu(get_current_thread(), p)
37 U->>P:thread_set_pinned_cpu(peer.thread, p)
38 U->>M:thread_set_pinned_cpu(peer.thread, p+1 or p+2)
39 Note over M: main is pinned to another or same cpu than peer will be<br/> allowing to test cases where<br/> 1) either current cpu needs to be rescheduled<br/> or 2) another cpu than current
40 U->>U: spin_lock(&peer.lock)
41 U->>+P: event_signal(&peer.ev_req)
42 P->>P: spin_lock(&peer.lock)
43 Note over P: peer [READY] until unittest in [BLOCKED]
44 U->>+M: event_signal(&main.ev_req)
45 U->>+U: event_wait(&main.ev_resp)
46 Note over U: unittest [BLOCKED]
47 U-->>P: peer thread scheduled on cpu p
48 Note over P: peer [RUNNING]
49 M->>M: loop until peer is [RUNNING]
50 M->>P: thread_set_pinned_cpu(p+1 or p+2)
51 M-->>P: peer thread scheduled on p+1 or p+2
52 Note over P: peer in [RUNNING] on the spin_lock
53 M->>U: event_signal(&main.ev_resp)
54 M-->>U: unitest unblocked by main
55 Note over U: unittest [RUNNING]
56 U->>U: spin_unlock(&peer.lock)
57 U-->>P: peer is unlocked by unittest
58 Note over P: peer is [RUNNING] unlocked from spin
59 U->>U: wait(&peer.ev_resp)
60 Note over U: unittest [BLOCKED]
61 P->>P: set actual_cpu
62 P->>U: event_signal(&peer.ev_resp)
63 P->>P: ev_wait(peer.ev_req)
64 P-->>U: unittest unblocked by peer
65 Note over P: peer [BLOCKED]
66 M->>M: ev_wait(peer.ev_req)
67 Note over M: main [BLOCKED]
68 U->>U: check actual_cpu == p+1 or p+2
69```
70
71## Testing `thread_set_pinned_cpu` on a `[READY]` peer
72
73```mermaid
74
75sequenceDiagram
76 participant U as unitest thread (priority peer+1)
77 participant M as main thread (priority peer+/-1)
78 participant P as peer thread (priority peer)
79 Note over U, P: Testing thread_set_pinned_cpu on a [READY] peer
80 Note over M: main [BLOCKED]
81 Note over P: peer [BLOCKED]
82 U->>U:thread_set_pinned_cpu(get_current_thread(), p)
83 U->>P:thread_set_pinned_cpu(peer.thread, p)
84 U->>M:thread_set_pinned_cpu(peer.thread, p+1 or p+2)
85 Note over M: main is pinned to another or same cpu than peer will be<br/> allowing to test cases where<br/> 1) either current cpu needs to be rescheduled<br/> or 2) another cpu than current
86 U->>U: spin_lock(&peer.lock)
87 U->>+P: event_signal(&peer.ev_req)
88 P->>P: spin_lock(&peer.lock)
89 Note over P: peer [READY] until unittest in [BLOCKED]
90 U->>+M: event_signal(&main.ev_req)
91 U->>+U: event_wait(&main.ev_resp)
92 Note over U: unittest [BLOCKED]
93 U-->>P: peer thread scheduled on cpu p
94 Note over P: peer [RUNNING]
95 M->>M: spin_lock(&main.lock)
96 M->>-U: event_signal(&main.ev_resp)
97 M->>M: loop until peer is [READY]
98 Note over U: unittest [RUNNING]
99 U-->>P: peer thread scheduled out of cpu p
100 Note over P: peer [READY]
101 U->>U: spin_lock(&main.lock)
102 Note over U: unittest [RUNNING] in busy loop due to locked lock
103 M->>P: thread_set_pinned_cpu(p+1)
104 Note over P: peer thread still spin locked in [READY]
105 M->>M: spin_unlock(&main.lock)
106 M-->>U: unittest unlocked
107 U->>P: spin_unlock(&peer.lock)
108 Note over P: peer thread [RUNNING] but still locked on spin_lock
109 U->>U: event_wait(&peer_ev_resp)
110 U-->>P: peer thread unlocked
111 Note over P: peer thread [RUNNING]
112 M-->>P: peer thread scheduled on p+1
113 P->>P: set actual_cpu
114 P->>U: event_signal(&peer.ev_resp)
115 P->>P: ev_wait(peer.ev_req)
116 Note over P: peer [BLOCKED]
117
118 M->>M: ev_wait(peer.ev_req)
119 Note over M: main [BLOCKED]
120 U->>U: check actual_cpu == p+1
121
122```
123
124## Testing `thread_set_pinned_cpu` on a `[BLOCKED]` peer
125
126```mermaid
127
128sequenceDiagram
129 participant U as unitest thread (priority peer+1)
130 participant M as main thread (priority peer+/-1)
131 participant P as peer thread (priority peer)
132 Note over U, P: Testing thread_set_pinned_cpu on a [BLOCKED] peer
133 Note over M: main [BLOCKED]
134 Note over P: peer [BLOCKED]
135 U->>U:thread_set_pinned_cpu(get_current_thread(), p)
136 U->>P:thread_set_pinned_cpu(peer.thread, p)
137 U->>M:thread_set_pinned_cpu(peer.thread, p+1 or p+2)
138 Note over M: main is pinned to another or same cpu than peer will be<br/> allowing to test cases where<br/> 1) either current cpu needs to be rescheduled<br/> or 2) another cpu than current
139 U->>+P: event_signal(&peer.ev_req)
140 P->>P: event_wait(&peer.blocked_ev)
141 Note over P: peer [BLOCKED]
142 U->>+M: event_signal(&main.ev_req)
143 U->>+U: event_wait(&main.ev_resp)
144 Note over U: unittest [BLOCKED]
145 M->>M: loop until peer is [BLOCKED]
146 M->>P: thread_set_pinned_cpu(p+1 or p+2)
147 M->>U: event_signal(&main.ev_resp)
148 M-->>U: unittest unblocked by main
149 Note over U: unittest [RUNNING]
150 U->>P: event_signal(&peer.blocked_ev)
151 U-->>P: peer unblocked by unittest
152 M-->>P: peer thread scheduled on p+1 or p+2
153 Note over P: peer [RUNNING]
154 P->>P: set actual_cpu
155 P->>U: event_signal(&peer.ev_resp)
156 P->>P: ev_wait(peer.ev_req)
157 Note over P: peer [BLOCKED]
158 M->>M: ev_wait(peer.ev_req)
159 Note over M: main [BLOCKED]
160 U->>U: wait(&peer.ev_resp)
161 U->>U: check actual_cpu == p+1 or p+2
162
163```
164
165## Testing `thread_set_pinned_cpu` on a `[SLEEPING]` peer
166
167```mermaid
168
169sequenceDiagram
170 participant U as unitest thread (priority peer+1)
171 participant M as main thread (priority peer+/-1)
172 participant P as peer thread (priority peer)
173 Note over U, P: Testing thread_set_pinned_cpu on a [SLEEPING] peer
174 Note over M: main [BLOCKED]
175 Note over P: peer [BLOCKED]
176 U->>U:thread_set_pinned_cpu(get_current_thread(), p)
177 U->>P:thread_set_pinned_cpu(peer.thread, p)
178 U->>M:thread_set_pinned_cpu(peer.thread, p+1 or p+2)
179 Note over M: main is pinned to another or same cpu than peer will be<br/> allowing to test cases where<br/> 1) either current cpu needs to be rescheduled<br/> or 2) another cpu than current
180 U->>+P: event_signal(&peer.ev_req)
181 P->>P: thread_sleep_ns(100ms)
182 Note over P: peer [SLEEPING]
183 U->>+M: event_signal(&main.ev_req)
184 U->>+U: event_wait(&main.ev_resp)
185 Note over U: unittest [BLOCKED]
186 M->>M: loop until peer is [SLEEPING]
187 M->>P: thread_set_pinned_cpu(p+1 or p+2)
188 M->>U: event_signal(&main.ev_resp)
189 M-->>U: unittest unblocked by main
190 Note over U: unittest [RUNNING]
191 M->>M: ev_wait(peer.ev_req)
192 Note over M: main [BLOCKED]
193 U->>U: wait(&peer.ev_resp)
194 Note over U: unittest [BLOCKING]
195 P-->>P: timer interrupt: waking-up peer
196 M-->>P: peer thread scheduled on p+1 or p+2
197 Note over P: peer [RUNNING]
198 P->>P: set actual_cpu
199 P->>U: event_signal(&peer.ev_resp)
200 P->>P: ev_wait(peer.ev_req)
201 Note over P: peer [BLOCKED]
202 P-->>U: unittest unblocked by peer
203 U->>U: check actual_cpu == p+1 or p+2
204```
205