ysyx-workbench/am-kernels/kernels/thread-os/thread-os.c
tracer-ysyx d08c2860da > compile NEMU
ysyx_22040000 李心杨
Linux calcite 6.6.19 #1-NixOS SMP PREEMPT_DYNAMIC Fri Mar  1 12:35:11 UTC 2024 x86_64 GNU/Linux
 16:26:21  up 4 days  3:32,  2 users,  load average: 0.85, 0.91, 0.95
2024-03-24 16:26:21 +08:00

70 lines
1.5 KiB
C

#include <am.h>
#include <klib.h>
#include <klib-macros.h>
#define MAX_CPU 8
typedef union task {
struct {
const char *name;
union task *next;
void (*entry)(void *);
Context *context;
};
uint8_t stack[4096 * 3];
} Task;
Task *currents[MAX_CPU];
#define current currents[cpu_current()]
// user-defined tasks
int locked = 0;
void lock() { while (atomic_xchg(&locked, 1)); }
void unlock() { atomic_xchg(&locked, 0); }
void func(void *arg) {
while (1) {
lock();
printf("Thread-%s on CPU #%d\n", arg, cpu_current());
unlock();
for (int volatile i = 0; i < 100000; i++) ;
}
}
Task tasks[] = {
{ .name = "A", .entry = func },
{ .name = "B", .entry = func },
{ .name = "C", .entry = func },
{ .name = "D", .entry = func },
{ .name = "E", .entry = func },
};
// ------------------
Context *on_interrupt(Event ev, Context *ctx) {
extern Task tasks[];
if (!current) current = &tasks[0];
else current->context = ctx;
do {
current = current->next;
} while ((current - tasks) % cpu_count() != cpu_current());
return current->context;
}
void mp_entry() {
iset(true);
yield();
}
int main() {
cte_init(on_interrupt);
for (int i = 0; i < LENGTH(tasks); i++) {
Task *task = &tasks[i];
Area stack = (Area) { &task->context + 1, task + 1 };
task->context = kcontext(stack, task->entry, (void *)task->name);
task->next = &tasks[(i + 1) % LENGTH(tasks)];
}
mpe_init(mp_entry);
}