Skip to content

Commit

Permalink
stack: allocate_stack implementation for task stack
Browse files Browse the repository at this point in the history
  • Loading branch information
roemvaar committed Oct 23, 2024
1 parent f1e624c commit 19b1f06
Show file tree
Hide file tree
Showing 8 changed files with 54 additions and 139 deletions.
1 change: 1 addition & 0 deletions include/demos/demo_1.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ void hello_name(char *array);
void display_ascii_art(void);
void task1(void);
void task_example(void);
void console(void);

#endif /* DEMOS_DEMO_1_H_ */
20 changes: 0 additions & 20 deletions include/mm.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,6 @@

#include <stddef.h> // TODO(roemvaar): DELETE THIS, create types.h and don't use stdlib

#include "sched.h"

#define MEM_BLOCK_SIZE 0x10000
#define BLOCK_COUNT NR_TASKS

// typedef struct mem_block {
// int address;
// struct mem_block *next;
// } MemBlock_t;

// typedef struct mem_block MemBlock_t;
typedef struct mem_block
{
unsigned long mem[MEM_BLOCK_SIZE];
} MemBlock_t;

void mem_init(void);
MemBlock_t *get_mem_by_tid(int tid);
void free_mem(MemBlock_t *block);

void *memset(void *s, int c, size_t n);
void *memcpy(void *restrict dest, const void *restrict src, size_t n);

Expand Down
56 changes: 14 additions & 42 deletions include/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,18 @@

#include "mm.h"

/* Scheduling - first iteration:
*
* After kernel startup `start_kernel` there is only one task running `init_task`
* Only one priority (0) is supported.
* The maximum number of tasks (max_num_tasks) will be one hundred.
* A fixed array of task descriptors, size of max_num_tasks.
* A fized array of process stacks. Each process will have an array.
* Use round robin algorithm (FIFO).
* Time slicing.
*/

// #define MAX_TASKS_PER_PRIORITY 10
// #define MAX_TASKS (PRIORITY_LEVELS * MAX_TASKS_PER_PRIORITY)
#define PRIORITY_LEVELS 5
#define NR_TASKS 64
#define MAX_TASKS 64

#define FIRST_TASK task[0]
#define LAST_TASK task[NR_TASKS-1]
#define LAST_TASK task[MAX_TASKS-1]

#define STACK_SIZE 1024

extern struct task_struct *task[NR_TASKS];
extern struct task_struct *task[MAX_TASKS];
extern struct task_struct *current;
extern int num_tasks;

typedef struct mem_block MemBlock_t;

//////////////////////////////////////////////////////////////////////////


void *allocate_stack(int tid);

//////////////////////////////////////////////////////////////////////////

/* TaskState_t
*
* A task is in one of the following run states:
Expand Down Expand Up @@ -98,35 +78,27 @@ struct task_struct
struct task_struct *next_task_send_queue; /* Pointer to TaskDescriptor of the next ready task (send queue) */
};

/* Queue_t

/*
* INIT_TASK
*/
typedef struct _queue
{
struct task_struct *front;
struct task_struct *rear;
} Queue_t;
#define INIT_TASK \
/* cpu_context */ { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
/* state etc */ 1, 0, 1, NULL, NULL, NULL \
}

void sched_init(void);
void schedule(void);
int get_num_tasks(void);
int get_new_tid(void);
struct task_struct *get_free_task_descriptor(void);
// void add_to_ready_queue(struct task_struct *task);
struct task_struct *get_current_task(void);
void stop_task(void);
void delete_task(void);
void switch_to(struct task_struct *next);
void *allocate_stack(int tid);

/*
* INIT_TASK
*/
#define INIT_TASK \
/* cpu_context */ { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \
/* state etc */ 1, 0, 1, NULL, NULL, NULL \
}

/* DEBUG */
// void print_priority_queue(void);
/* For debugging */
void print_task(void);

#endif /* SCHED_H_ */
19 changes: 19 additions & 0 deletions src/demo_1.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "arm/utils.h"
#include "peripherals/uart.h"
#include "peripherals/timer.h"
#include "sys.h"
#include "task.h"

Expand Down Expand Up @@ -125,3 +126,21 @@ void task_example(void)
schedule();
}

void console(void)
{
char input;
uint32_t count;

while (1) {
input = uart_getc(CONSOLE);

if (input == '$') {
count = sys_timer_get_count();
uart_printf(CONSOLE, "Timer count: %u\r\n", count);
} else if (input == '\n' || input == '\r') {
uart_printf(CONSOLE, "\r\n");
} else {
uart_putc(CONSOLE, input);
}
}
}
23 changes: 3 additions & 20 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,31 +71,14 @@ int kmain(void)
schedule();

#ifdef DEBUG
// print_priority_queue();
// int tid = sys_mytid();
// uart_printf(CONSOLE, "current: %d\r\n", tid);
// print_task();
int tid = sys_mytid();
uart_printf(CONSOLE, "current: %d\r\n", tid);
print_task();
#endif

// while (1) {
// schedule();
// }

// char input;
// uint32_t count;

// while (1) {
// input = uart_getc(CONSOLE);

// if (input == '$') {
// count = sys_timer_get_count();
// uart_printf(CONSOLE, "Timer count: %u\r\n", count);
// } else if (input == '\n' || input == '\r') {
// uart_printf(CONSOLE, "\r\n");
// } else {
// uart_putc(CONSOLE, input);
// }
// }

return 0;
}
29 changes: 0 additions & 29 deletions src/mm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,6 @@

#include "peripherals/uart.h" // TODO(roemvaar): Delete this - don't print from here

// static MemBlock_t stacks[BLOCK_COUNT];

// static unsigned short mem_map[BLOCK_COUNT];

// void mem_init(void)
// {
// for (int i = 0; i < BLOCK_COUNT; i++) {
// stacks[i].mem[0] = i * 2;
// }

// for (int i = 0; i < BLOCK_COUNT; i++) {
// uart_printf(CONSOLE, "stack %i: mem[0] = %d\r\n", (int)i, stacks[i].mem[0]);
// }

// return;
// }

// MemBlock_t *get_mem_by_tid(int tid)
// {
// return &stacks[tid];
// }

void free_mem(MemBlock_t *block)
{
(void)block;

return;
}

/* Define our own memset to avoid SIMD instructions emitted from the compiler */
void *memset(void *s, int c, size_t n)
{
Expand Down
44 changes: 17 additions & 27 deletions src/sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,27 @@
#include <stddef.h> // TODO(roemvaar): DELETE THIS - don't use stdlib

#include "arm/utils.h"
#include "peripherals/uart.h" // TODO(roemvaar): Delete this - don't print from here
#include "peripherals/uart.h"
#include "mm.h"
#include "task.h"

// Pre-allocated task descriptor array (static memory)
static struct task_struct task_structs[NR_TASKS];
/* Pre-allocated task descriptor array (static memory) */
static struct task_struct task_structs[MAX_TASKS];

static struct task_struct init_task = INIT_TASK;
struct task_struct *current = &(init_task);

// Array of pointers to task_structs
struct task_struct *task[NR_TASKS] = {&(init_task), };
/* Array of pointers to task_structs */
struct task_struct *task[MAX_TASKS] = {&(init_task), };

// Track how many tasks have been created
/* Track how many tasks have been created */
int num_tasks = 1;

// Pointer to the idle task
/* Pointer to the idle task */
struct task_struct *idle_task;

#define DEBUG

/////////////////////////////////////////////////////////
#define STACK_SIZE 1024
#define MAX_TASKS 100

char stacks[MAX_TASKS][STACK_SIZE];
int stack_top[MAX_TASKS] = {0};

Expand All @@ -43,7 +39,6 @@ void *allocate_stack(int tid)
*/
return (void *)(stacks[tid] + STACK_SIZE);
}
/////////////////////////////////////////////////////////

/* get_free_task_descriptor
*
Expand All @@ -53,15 +48,16 @@ void *allocate_stack(int tid)
*/
struct task_struct *get_free_task_descriptor(void)
{
for (int i = 0; i < NR_TASKS; i++) {
for (int i = 0; i < MAX_TASKS; i++) {
if (task[i] == NULL) {
task[i] = &task_structs[i]; // Use a pre-allocated task from the static pool
task[i] = &task_structs[i]; /* Use a pre-allocated task from the static pool */
num_tasks++;
return task[i];
}
}

return NULL; // No free task descriptor found
/* No free task descriptor found */
return NULL;
}

void idle(void)
Expand Down Expand Up @@ -121,18 +117,16 @@ void schedule(void)
}

if (next_task == NULL) {
/* No runnable task found, switch to the idle task */
uart_printf(CONSOLE, "[sched]: No task to run, switching to idle task\r\n");
switch_to(idle_task);
switch_to(idle_task); /* task[0] is the idle task */
} else {
/* No runnable task found, switch to the idle task */
switch_to(next_task); /* task[0] is the idle task */
switch_to(next_task);
}
}

void switch_to(struct task_struct *next)
{
uart_printf(CONSOLE, "Current task tid: %d\r\n", current->tid);

if (current == next) {
return; /* No need to switch if it's the same task */
}
Expand All @@ -141,16 +135,12 @@ void switch_to(struct task_struct *next)
current = next;

#ifdef DEBUG
uart_printf(CONSOLE, "Switching to task with tid: %d\r\n", next->tid);
uart_printf(CONSOLE, "Current task tid: %d\r\n", current->tid);
uart_printf(CONSOLE, "Switching to task tid: %d\r\n", next->tid);
#endif

/* Perform the context switch */
if (next->state == READY) {
cpu_switch_to(prev, next);
} else {
// cpu_switch_to(prev, idle);
uart_printf(CONSOLE, "[sched]: Task with tid %d is not READY!\r\n", next->tid);
}
cpu_switch_to(prev, next);
}

int sys_mytid(void)
Expand Down
1 change: 0 additions & 1 deletion src/task.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ int task_create(int priority, void (*task_code)(void))
new_task->state = READY;
new_task->next_task_ready_queue = NULL;
new_task->next_task_send_queue = NULL;
// new_task->mem = get_mem_by_tid(new_task->tid);

/* Add new task into ready_queue */
// add_to_ready_queue(new_task);
Expand Down

0 comments on commit 19b1f06

Please sign in to comment.