Skip to content

Commit 4425c5b

Browse files
committed
fix preemption logic and interrupt context restore
Standardized stack frame access using sp instead of t0 in tx_thread_context_restore.S. Fixed global pointer address loading using la for _tx_thread_current_ptr and others. Implemented dynamic mstatus recovery from stack to preserve FPU and interrupt states. Optimized register storage sequence in the preemption path for better atomicity. Adjusted thread priorities in demo_threadx.c to facilitate preemption verification.
1 parent a1b2457 commit 4425c5b

3 files changed

Lines changed: 58 additions & 65 deletions

File tree

ports/risc-v32/gnu/example_build/qemu_virt/demo_threadx.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ void tx_application_define(void *first_unused_memory)
112112

113113
tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,
114114
pointer, DEMO_STACK_SIZE,
115-
16, 16, 4, TX_AUTO_START);
115+
10, 10, 4, TX_AUTO_START);
116116

117117
/* Allocate the stack for thread 3. */
118118
tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);
@@ -201,7 +201,7 @@ UINT status;
201201
thread_0_counter++;
202202

203203
/* Sleep for 10 ticks. */
204-
tx_thread_sleep(10);
204+
tx_thread_sleep(1);
205205

206206
/* Set event flag 0 to wakeup thread 5. */
207207
status = tx_event_flags_set(&event_flags_0, 0x1, TX_OR);

ports/risc-v32/gnu/src/tx_thread_context_restore.S

Lines changed: 53 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ _tx_thread_context_restore:
8787

8888
/* Recover floating point registers. */
8989
#if defined(__riscv_flen)
90-
LOAD t1, TX_STACK_OFFSET_MSTATUS(t0) // Pickup thread's floating point state */
90+
LOAD t1, TX_STACK_OFFSET_MSTATUS(sp) // Pickup thread's floating point state */
9191
/* Check if floating point is enabled */
9292
srli t1, t1, 13
9393
andi t1, t1, 0x3
@@ -151,12 +151,8 @@ _tx_thread_skip_fp_restore:
151151

152152
LOAD t0, TX_STACK_OFFSET_MEPC(sp) // Recover mepc
153153
csrw mepc, t0 // Setup mepc
154-
li t0, 0x1880 // Prepare MPIP
155-
#if defined(__riscv_flen) && ((__riscv_flen == 32) || (__riscv_flen == 64))
156-
li t1, 1<<13
157-
or t0, t1, t0
158-
#endif
159-
csrw mstatus, t0 // Enable MPIP
154+
LOAD t0, TX_STACK_OFFSET_MSTATUS(sp) // Recover mstatus
155+
csrw mstatus, t0
160156

161157
LOAD x1, TX_STACK_OFFSET_X1(sp) // Recover RA
162158
LOAD x5, TX_STACK_OFFSET_X5(sp) // Recover t0
@@ -190,13 +186,16 @@ _tx_thread_not_nested_restore:
190186
|| (_tx_thread_preempt_disable))
191187
{ */
192188

193-
LOAD t1, _tx_thread_current_ptr // Pickup current thread pointer
189+
la t0, _tx_thread_current_ptr
190+
LOAD t1, 0(t0) // Pickup current thread pointer
194191
beqz t1, _tx_thread_idle_system_restore // If NULL, idle system restore
195192

196-
LOAD t2, _tx_thread_preempt_disable // Pickup preempt disable flag
193+
la t0, _tx_thread_preempt_disable
194+
LOAD t2, 0(t0) // Pickup preempt disable flag
197195
bgtz t2, _tx_thread_no_preempt_restore // If set, restore interrupted thread
198196

199-
LOAD t2, _tx_thread_execute_ptr // Pickup thread execute pointer
197+
la t0, _tx_thread_execute_ptr
198+
LOAD t2, 0(t0) // Pickup thread execute pointer
200199
bne t1, t2, _tx_thread_preempt_restore // If higher-priority thread is ready, preempt
201200

202201

@@ -210,7 +209,7 @@ _tx_thread_no_preempt_restore:
210209

211210
/* Recover floating point registers. */
212211
#if defined(__riscv_flen)
213-
LOAD t1, TX_STACK_OFFSET_MSTATUS(t0) // Pickup thread's floating point state */
212+
LOAD t1, TX_STACK_OFFSET_MSTATUS(sp) // Pickup thread's floating point state */
214213
/* Check if floating point is enabled */
215214
srli t1, t1, 13
216215
andi t1, t1, 0x3
@@ -273,12 +272,8 @@ _tx_thread_no_preempt_skip_fp_restore:
273272

274273
LOAD t0, TX_STACK_OFFSET_MEPC(sp) // Recover mepc
275274
csrw mepc, t0 // Setup mepc
276-
li t0, 0x1880 // Prepare MPIP
277-
#if defined(__riscv_flen)
278-
li t1, 1<<13
279-
or t0, t1, t0
280-
#endif
281-
csrw mstatus, t0 // Enable MPIP
275+
LOAD t0, TX_STACK_OFFSET_MSTATUS(sp) // Recover mstatus
276+
csrw mstatus, t0
282277

283278
LOAD x1, TX_STACK_OFFSET_X1(sp) // Recover RA
284279
LOAD x5, TX_STACK_OFFSET_X5(sp) // Recover t0
@@ -312,62 +307,61 @@ _tx_thread_preempt_restore:
312307
/* Instead of directly activating the thread again, ensure we save the
313308
entire stack frame by saving the remaining registers. */
314309

315-
LOAD t0, TX_THREAD_STACK_PTR(t1) // Pickup thread's stack pointer
310+
LOAD sp, TX_THREAD_STACK_PTR(t1)
316311
ori t3, x0, 1 // Build interrupt stack type
317-
STORE t3, 0(t0) // Store stack type
318-
312+
STORE t3, 0(sp) // Store stack type
319313
/* Store floating point preserved registers. */
320314
#if defined(__riscv_flen)
321-
LOAD t2, TX_STACK_OFFSET_MSTATUS(t0) // Pickup thread's floating point state */
315+
LOAD t2, TX_STACK_OFFSET_MSTATUS(sp) // Pickup thread's floating point state */
322316
/* Check if floating point is enabled */
323317
srli t2, t2, 13
324318
andi t2, t2, 0x3
325319
beqz t2, _tx_thread_preempt_skip_fp_restore // Skip floating point restore FS is Off
326320
#if __riscv_flen == 32
327-
fsw f8, TX_STACK_OFFSET_F8(t0) // Store fs0
328-
fsw f9, TX_STACK_OFFSET_F9(t0) // Store fs1
329-
fsw f18, TX_STACK_OFFSET_F18(t0) // Store fs2
330-
fsw f19, TX_STACK_OFFSET_F19(t0) // Store fs3
331-
fsw f20, TX_STACK_OFFSET_F20(t0) // Store fs4
332-
fsw f21, TX_STACK_OFFSET_F21(t0) // Store fs5
333-
fsw f22, TX_STACK_OFFSET_F22(t0) // Store fs6
334-
fsw f23, TX_STACK_OFFSET_F23(t0) // Store fs7
335-
fsw f24, TX_STACK_OFFSET_F24(t0) // Store fs8
336-
fsw f25, TX_STACK_OFFSET_F25(t0) // Store fs9
337-
fsw f26, TX_STACK_OFFSET_F26(t0) // Store fs10
338-
fsw f27, TX_STACK_OFFSET_F27(t0) // Store fs11
321+
fsw f8, TX_STACK_OFFSET_F8(sp) // Store fs0
322+
fsw f9, TX_STACK_OFFSET_F9(sp) // Store fs1
323+
fsw f18, TX_STACK_OFFSET_F18(sp) // Store fs2
324+
fsw f19, TX_STACK_OFFSET_F19(sp) // Store fs3
325+
fsw f20, TX_STACK_OFFSET_F20(sp) // Store fs4
326+
fsw f21, TX_STACK_OFFSET_F21(sp) // Store fs5
327+
fsw f22, TX_STACK_OFFSET_F22(sp) // Store fs6
328+
fsw f23, TX_STACK_OFFSET_F23(sp) // Store fs7
329+
fsw f24, TX_STACK_OFFSET_F24(sp) // Store fs8
330+
fsw f25, TX_STACK_OFFSET_F25(sp) // Store fs9
331+
fsw f26, TX_STACK_OFFSET_F26(sp) // Store fs10
332+
fsw f27, TX_STACK_OFFSET_F27(sp) // Store fs11
339333
#elif __riscv_flen == 64
340-
fsd f8, TX_STACK_OFFSET_F8(t0) // Store fs0
341-
fsd f9, TX_STACK_OFFSET_F9(t0) // Store fs1
342-
fsd f18, TX_STACK_OFFSET_F18(t0) // Store fs2
343-
fsd f19, TX_STACK_OFFSET_F19(t0) // Store fs3
344-
fsd f20, TX_STACK_OFFSET_F20(t0) // Store fs4
345-
fsd f21, TX_STACK_OFFSET_F21(t0) // Store fs5
346-
fsd f22, TX_STACK_OFFSET_F22(t0) // Store fs6
347-
fsd f23, TX_STACK_OFFSET_F23(t0) // Store fs7
348-
fsd f24, TX_STACK_OFFSET_F24(t0) // Store fs8
349-
fsd f25, TX_STACK_OFFSET_F25(t0) // Store fs9
350-
fsd f26, TX_STACK_OFFSET_F26(t0) // Store fs10
351-
fsd f27, TX_STACK_OFFSET_F27(t0) // Store fs11
334+
fsd f8, TX_STACK_OFFSET_F8(sp) // Store fs0
335+
fsd f9, TX_STACK_OFFSET_F9(sp) // Store fs1
336+
fsd f18, TX_STACK_OFFSET_F18(sp) // Store fs2
337+
fsd f19, TX_STACK_OFFSET_F19(sp) // Store fs3
338+
fsd f20, TX_STACK_OFFSET_F20(sp) // Store fs4
339+
fsd f21, TX_STACK_OFFSET_F21(sp) // Store fs5
340+
fsd f22, TX_STACK_OFFSET_F22(sp) // Store fs6
341+
fsd f23, TX_STACK_OFFSET_F23(sp) // Store fs7
342+
fsd f24, TX_STACK_OFFSET_F24(sp) // Store fs8
343+
fsd f25, TX_STACK_OFFSET_F25(sp) // Store fs9
344+
fsd f26, TX_STACK_OFFSET_F26(sp) // Store fs10
345+
fsd f27, TX_STACK_OFFSET_F27(sp) // Store fs11
352346
#endif
353347
_tx_thread_preempt_skip_fp_restore:
354348
#endif
355349

356350
/* Store standard preserved registers. */
357351

358-
STORE x9, TX_STACK_OFFSET_X9(t0) // Store s1
359-
STORE x18, TX_STACK_OFFSET_X18(t0) // Store s2
360-
STORE x19, TX_STACK_OFFSET_X19(t0) // Store s3
361-
STORE x20, TX_STACK_OFFSET_X20(t0) // Store s4
362-
STORE x21, TX_STACK_OFFSET_X21(t0) // Store s5
363-
STORE x22, TX_STACK_OFFSET_X22(t0) // Store s6
364-
STORE x23, TX_STACK_OFFSET_X23(t0) // Store s7
365-
STORE x24, TX_STACK_OFFSET_X24(t0) // Store s8
366-
STORE x25, TX_STACK_OFFSET_X25(t0) // Store s9
367-
STORE x26, TX_STACK_OFFSET_X26(t0) // Store s10
368-
STORE x27, TX_STACK_OFFSET_X27(t0) // Store s11
352+
STORE x9, TX_STACK_OFFSET_X9(sp) // Store s1
353+
STORE x18, TX_STACK_OFFSET_X18(sp) // Store s2
354+
STORE x19, TX_STACK_OFFSET_X19(sp) // Store s3
355+
STORE x20, TX_STACK_OFFSET_X20(sp) // Store s4
356+
STORE x21, TX_STACK_OFFSET_X21(sp) // Store s5
357+
STORE x22, TX_STACK_OFFSET_X22(sp) // Store s6
358+
STORE x23, TX_STACK_OFFSET_X23(sp) // Store s7
359+
STORE x24, TX_STACK_OFFSET_X24(sp) // Store s8
360+
STORE x25, TX_STACK_OFFSET_X25(sp) // Store s9
361+
STORE x26, TX_STACK_OFFSET_X26(sp) // Store s10
362+
STORE x27, TX_STACK_OFFSET_X27(sp) // Store s11
369363
// Note: s0 is already stored!
370-
364+
STORE sp, TX_THREAD_STACK_PTR(t1)
371365
/* Save the remaining time-slice and disable it. */
372366
/* if (_tx_timer_time_slice)
373367
{ */
@@ -391,7 +385,8 @@ _tx_thread_dont_save_ts:
391385
/* Return to the scheduler. */
392386
/* _tx_thread_schedule(); */
393387

394-
STORE x0, _tx_thread_current_ptr, t0 // Clear current thread pointer*/
388+
la t0, _tx_thread_current_ptr
389+
STORE x0, 0(t0) // Clear current thread pointer*/
395390
/* } */
396391

397392
_tx_thread_idle_system_restore:

test/ports/azrtos_test_tx_gnu_riscv32_qemu.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ def run_qemu_test(elf_path, qemu_bin, gdb_bin):
156156
end
157157
158158
# Verify Preemption Logic (Thread Priority)
159-
break tx_thread_context_restore.S:320
159+
break _tx_thread_preempt_restore
160160
161161
set $max_loops = 5
162162
set $loop_cnt = 0
@@ -165,18 +165,16 @@ def run_qemu_test(elf_path, qemu_bin, gdb_bin):
165165
while $loop_cnt < $max_loops
166166
continue
167167
set $loop_cnt = $loop_cnt + 1
168-
169-
print "Hit Preemption Restore Path"
168+
170169
171170
set $curr_ptr = _tx_thread_current_ptr
172171
set $exec_ptr = _tx_thread_execute_ptr
173172
174173
if $curr_ptr != 0 && $exec_ptr != 0
174+
print "Preemption Check: Current Prio=%d, Exec Prio=%d", $curr_ptr->tx_thread_priority, $exec_ptr->tx_thread_priority
175175
set $curr_prio = $curr_ptr->tx_thread_priority
176176
set $exec_prio = $exec_ptr->tx_thread_priority
177177
178-
print $curr_prio
179-
print $exec_prio
180178
181179
if $exec_prio < $curr_prio
182180
print "SUCCESS: Thread Preemption Verified."

0 commit comments

Comments
 (0)