• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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