Skip to content

Commit b27a13a

Browse files
committed
Fix concurrent long calls: move state to per-slot storage
- Add longcall_target and longcall_remaining fields to waitlist slots - Remove global static variables that caused race conditions - Each long call now maintains independent continuation state - Multiple concurrent long-delay operations work correctly - Proper cleanup of longcall state when slots are reused or completed
1 parent b0a9e9e commit b27a13a

2 files changed

Lines changed: 42 additions & 15 deletions

File tree

Comanche055-C89/waitlist.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,13 @@ agc_waitlist_slot_t agc_waitlist[NUM_WAITLIST_TASKS];
2424

2525
void waitlist_init(void)
2626
{
27-
memset(agc_waitlist, 0, sizeof(agc_waitlist));
27+
int i;
28+
for (i = 0; i < NUM_WAITLIST_TASKS; i++) {
29+
agc_waitlist[i].delta_t = 0;
30+
agc_waitlist[i].task = NULL;
31+
agc_waitlist[i].longcall_target = NULL;
32+
agc_waitlist[i].longcall_remaining = 0;
33+
}
2834
}
2935

3036
/* ----------------------------------------------------------------
@@ -41,6 +47,9 @@ int waitlist_add(int dt_centisecs, agc_taskfunc_t task)
4147
if (agc_waitlist[i].task == NULL) {
4248
agc_waitlist[i].delta_t = dt_centisecs;
4349
agc_waitlist[i].task = task;
50+
/* Clear any leftover longcall state */
51+
agc_waitlist[i].longcall_target = NULL;
52+
agc_waitlist[i].longcall_remaining = 0;
4453
return i;
4554
}
4655
}
@@ -60,30 +69,42 @@ int waitlist_fixdelay(int dt_centisecs, agc_taskfunc_t task)
6069
* Long call: for delays > 16383 centiseconds
6170
* ---------------------------------------------------------------- */
6271

63-
static void longcall_continue(void);
64-
static agc_taskfunc_t longcall_target;
65-
static int longcall_remaining;
66-
6772
static void longcall_continue(void)
6873
{
69-
if (longcall_remaining > 16383) {
70-
longcall_remaining -= 16383;
71-
waitlist_add(16383, longcall_continue);
72-
} else if (longcall_remaining > 0) {
73-
int dt = longcall_remaining;
74-
longcall_remaining = 0;
75-
waitlist_add(dt, longcall_target);
74+
int i;
75+
/* Find the slot that called this continuation */
76+
for (i = 0; i < NUM_WAITLIST_TASKS; i++) {
77+
if (agc_waitlist[i].task == longcall_continue) {
78+
if (agc_waitlist[i].longcall_remaining > 16383) {
79+
agc_waitlist[i].longcall_remaining -= 16383;
80+
waitlist_add(16383, longcall_continue);
81+
} else if (agc_waitlist[i].longcall_remaining > 0) {
82+
int dt = agc_waitlist[i].longcall_remaining;
83+
agc_taskfunc_t target = agc_waitlist[i].longcall_target;
84+
agc_waitlist[i].longcall_remaining = 0;
85+
agc_waitlist[i].longcall_target = NULL;
86+
waitlist_add(dt, target);
87+
}
88+
break;
89+
}
7690
}
7791
}
7892

7993
int waitlist_longcall(int dt_centisecs, agc_taskfunc_t task)
8094
{
95+
int slot;
8196
if (dt_centisecs <= 16383) {
8297
return waitlist_add(dt_centisecs, task);
8398
}
84-
longcall_target = task;
85-
longcall_remaining = dt_centisecs - 16383;
86-
return waitlist_add(16383, longcall_continue);
99+
100+
/* Find a free slot for the initial chunk */
101+
slot = waitlist_add(16383, longcall_continue);
102+
if (slot >= 0) {
103+
/* Store longcall state in the same slot */
104+
agc_waitlist[slot].longcall_target = task;
105+
agc_waitlist[slot].longcall_remaining = dt_centisecs - 16383;
106+
}
107+
return slot;
87108
}
88109

89110
/* ----------------------------------------------------------------
@@ -103,6 +124,9 @@ void waitlist_t3rupt(void)
103124
agc_taskfunc_t task = agc_waitlist[i].task;
104125
agc_waitlist[i].task = NULL;
105126
agc_waitlist[i].delta_t = 0;
127+
/* Clear longcall state when task completes */
128+
agc_waitlist[i].longcall_target = NULL;
129+
agc_waitlist[i].longcall_remaining = 0;
106130
task();
107131
}
108132
}

Comanche055-C89/waitlist.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
typedef struct {
1818
int delta_t; /* Centiseconds until fire (0 = empty) */
1919
agc_taskfunc_t task; /* Task function to call */
20+
/* Longcall state for delays > 16383 centiseconds */
21+
agc_taskfunc_t longcall_target; /* Final target task */
22+
int longcall_remaining; /* Remaining time after current chunk */
2023
} agc_waitlist_slot_t;
2124

2225
/* Task slots: LST1 holds delta-times, LST2 holds task addresses */

0 commit comments

Comments
 (0)