#define WORD_SIZE sizeof(void*)
#define MAX_TASKS 1024
#define TASK_NONE ((TaskID_T)-1)
+#define DEFAULT_STACK_SIZE (32768)
#define WORD_ALIGN(x) \
(((x) + WORD_SIZE) & ~(WORD_SIZE))
} TaskState_T;
typedef struct Task_T {
- long* stack_top;
+ long* _Atomic stack_top;
long* heap_top;
long* memory;
struct Task_T* next;
{
if (next != TASK_NONE && prev != next)
{
- Task_T* ntask = &Tasks[next];
- assert(ntask);
-
- while (!atomic_load(&ntask->stack_top))
+ while (!atomic_load(&Tasks[next].stack_top))
{
}
}
WaitForTaskFree(prev, Running[CpuID].task);
SwapTask(prev_task, next_task);
+
if (Running[CpuID].dead != TASK_NONE)
{
- WaitForTaskFree(prev, Running[CpuID].dead);
+ WaitForTaskFree(TASK_NONE, Running[CpuID].dead);
+ AcquireLock();
free(Tasks[Running[CpuID].dead].memory);
+ Tasks[Running[CpuID].dead].memory = NULL;
+ ReleaseLock();
Running[CpuID].dead = TASK_NONE;
}
}
static TaskID_T AllocateTaskID(void)
{
- AcquireLock();
TaskID_T tid = TASK_NONE;
if (TaskCount < MAX_TASKS)
{
/* TODO: iterate over table to find free slot... */
assert(!"out of task IDs");
}
- ReleaseLock();
return tid;
}
/* allocate a new task. default memory size is used if 0 provided */
if (memsz == 0)
{
- memsz = 32768;
+ memsz = DEFAULT_STACK_SIZE;
}
memsz = WORD_ALIGN(memsz);
task->memory = calloc(1, WORD_ALIGN(memsz));
TaskID_T Kernel_Spawn(void (*task_fn)(void*), void* arg, long int argsz, long int memsz)
{
+ AcquireLock();
TaskID_T tid = AllocateTaskID();
if (tid != TASK_NONE)
{
InitializeTask(&Tasks[tid], task_fn, arg, argsz, memsz);
- AcquireLock();
Enter(tid);
- ReleaseLock();
}
+ ReleaseLock();
return tid;
}
int* val = arg;
for (int i = 0; i < 1000; i++)
{
+ (void)val;
printf("%d %d\n", *val, CpuID);
Kernel_Yield();
}