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