Add scheduler (non preemptif) with context switch + add close primitive to the VFS
This commit is contained in:
parent
fc7a6e04ea
commit
223f92b6b2
|
@ -79,6 +79,9 @@ struct dentry
|
|||
// Internal inode
|
||||
void *inode;
|
||||
|
||||
// Internal counter used by opne() and close()
|
||||
uint32_t counter;
|
||||
|
||||
// Internal file informations
|
||||
mode_t mode;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@
|
|||
#include <kernel/types.h>
|
||||
|
||||
#define PROCESS_NB_OPEN_FILE (4)
|
||||
#define PROCESS_USER_STACK_SIZE (15 * 1024)
|
||||
#define PROCESS_USER_STACK_SIZE (2 * 1024)
|
||||
#define PROCESS_KERNEL_STACK_SIZE (512)
|
||||
#define PROCESS_NAME_LENGHT (16)
|
||||
#define PROCESS_MAX (3)
|
||||
#define PROCESS_MAX (4)
|
||||
|
||||
#define PROC_IDLE (0)
|
||||
|
||||
|
@ -26,12 +26,12 @@ struct process
|
|||
uint32_t user;
|
||||
} stack;
|
||||
|
||||
// Process name.
|
||||
char name[PROCESS_NAME_LENGHT];
|
||||
|
||||
// Context management
|
||||
common_context_t context;
|
||||
|
||||
// Process name.
|
||||
char name[PROCESS_NAME_LENGHT];
|
||||
|
||||
// Open file management
|
||||
struct {
|
||||
enum {
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
#ifndef __KERNEL_SHEDULER_H__
|
||||
# define __KERNEL_SHEDULER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <kernel/process.h>
|
||||
|
||||
// Define the number of task
|
||||
#define SCHED_TASK_NB_MAX PROCESS_MAX
|
||||
#define SCHED_QUANTUM_TICKS (4)
|
||||
|
||||
// Internal struct used by the sheduler
|
||||
struct sched_task
|
||||
{
|
||||
// Process informations
|
||||
struct process *process;
|
||||
|
||||
// Internal scheduler part
|
||||
// @note: defined here to facilite the
|
||||
// management in assembly
|
||||
struct sched_task *next;
|
||||
|
||||
|
||||
// Task status
|
||||
enum {
|
||||
SCHED_RUNNING,
|
||||
SCHED_SLEEPING,
|
||||
SCHED_DOWN,
|
||||
SCHED_STOPPED,
|
||||
SCHED_ZOMBIE
|
||||
} status;
|
||||
|
||||
// Preemptif part
|
||||
struct {
|
||||
uint8_t _static;
|
||||
int8_t _dynamic;
|
||||
} priority;
|
||||
|
||||
};
|
||||
|
||||
//---
|
||||
// Internal function
|
||||
//---
|
||||
/*
|
||||
** Initialize scheduler cache
|
||||
** @note: only called once by the kernel.
|
||||
*/
|
||||
extern void sched_initialize(void);
|
||||
|
||||
/*
|
||||
** Add new process to sheduler
|
||||
*/
|
||||
extern int sched_add_task(struct process *process);
|
||||
|
||||
/*
|
||||
** Start shedluler (in theory, this function is called only
|
||||
** time by the kernel during "bootstrap" part).
|
||||
*/
|
||||
extern void sched_start(void);
|
||||
|
||||
/*
|
||||
** Save current context of the current task and run the
|
||||
** next one based on internal task priority.
|
||||
*/
|
||||
extern void sched_schedule(void);
|
||||
|
||||
/*
|
||||
** Internal function wich will switch current process
|
||||
** context with the next context
|
||||
*/
|
||||
extern void sched_context_switch(common_context_t *current, common_context_t *next);
|
||||
|
||||
#endif /*__KERNEL_SHEDULER_H__*/
|
|
@ -1,47 +0,0 @@
|
|||
#ifndef __KERNEL_SHEDULER_H__
|
||||
# define __KERNEL_SHEDULER_H__
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
// Internal struct used by the sheduler
|
||||
struct shed_task
|
||||
{
|
||||
// Task status
|
||||
enum {
|
||||
RUNNING,
|
||||
SLEEPING,
|
||||
DOWN,
|
||||
STOPPED,
|
||||
ZOMBIE
|
||||
} status;
|
||||
|
||||
// Process informations
|
||||
struct process_s process;
|
||||
|
||||
// Preemptif part
|
||||
int8_t priority;
|
||||
};
|
||||
|
||||
//---
|
||||
// Internal function
|
||||
//---
|
||||
|
||||
/*
|
||||
** Add new process to sheduler
|
||||
*/
|
||||
extern int shed_add_task(struct process_s *process);
|
||||
|
||||
/*
|
||||
** Start shedluler (in theory, this function is called only
|
||||
** time by the kernel during "bootstrap" part).
|
||||
*/
|
||||
extern void shed_start(void);
|
||||
|
||||
/*
|
||||
** Save current context of the current task and run the
|
||||
** next one based on internal task priority.
|
||||
*/
|
||||
extern void shed_shedule(void);
|
||||
|
||||
#endif /*__KERNEL_SHEDULER_H__*/
|
|
@ -1,54 +0,0 @@
|
|||
.text
|
||||
|
||||
.global _kernel_switch
|
||||
.type _kernel_switch, @function
|
||||
|
||||
.align 2
|
||||
_kernel_switch:
|
||||
! Save process context into unbakable register
|
||||
mov r4, r8
|
||||
|
||||
! Update SR register to block
|
||||
! interrupt / exception and
|
||||
! switch register bank to simalate
|
||||
! system call.
|
||||
mov.l .sr_msk, r1 ! get mask for SR.BL = 1, SR.RB = 1 and SR.IMASK = 0b1111
|
||||
stc sr, r0 ! get SR register
|
||||
or r1, r0 ! set mask for BL and IMASK
|
||||
ldc r0, sr ! update SR regsiter
|
||||
|
||||
! set process context into bankable register
|
||||
! because unbankable register will be over-written.
|
||||
mov r8, r0
|
||||
|
||||
! Load first process
|
||||
ldc.l @r0+, R0_BANK ! set "process" r0 regsiter
|
||||
ldc.l @r0+, R1_BANK ! set "process" r1 regsiter
|
||||
ldc.l @r0+, R2_BANK ! set "process" r2 regsiter
|
||||
ldc.l @r0+, R3_BANK ! set "process" r3 regsiter
|
||||
ldc.l @r0+, R4_BANK ! set "process" r4 regsiter
|
||||
ldc.l @r0+, R5_BANK ! set "process" r5 regsiter
|
||||
ldc.l @r0+, R6_BANK ! set "process" r6 regsiter
|
||||
ldc.l @r0+, R7_BANK ! set "process" r7 regsiter
|
||||
mov.l @r0+, r8 ! set r8 regsiter
|
||||
mov.l @r0+, r9 ! set r9 regsiter
|
||||
mov.l @r0+, r10 ! set r10 regsiter
|
||||
mov.l @r0+, r11 ! set r11 regsiter
|
||||
mov.l @r0+, r12 ! set r12 regsiter
|
||||
mov.l @r0+, r13 ! set r13 regsiter
|
||||
mov.l @r0+, r14 ! set r14 regsiter
|
||||
mov.l @r0+, r15 ! set r15 register
|
||||
ldc.l @r0+, gbr ! set gbr regsiter
|
||||
lds.l @r0+, macl ! set macl regsiter
|
||||
lds.l @r0+, mach ! set mach regsiter
|
||||
ldc.l @r0+, ssr ! set ssr regsiter
|
||||
ldc.l @r0+, spc ! set spc regsiter
|
||||
lds.l @r0+, pr ! set pr regsiter
|
||||
|
||||
! Process switch
|
||||
rte
|
||||
nop
|
||||
|
||||
.align 4
|
||||
.sr_msk: .long 0x700000f0
|
||||
.end
|
|
@ -1,10 +1,11 @@
|
|||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/context.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <kernel/types.h>
|
||||
#include <kernel/process.h>
|
||||
#include <kernel/syscall.h>
|
||||
#include <kernel/scheduler.h>
|
||||
#include <kernel/util.h>
|
||||
#include <kernel/fs/vfs.h>
|
||||
#include <kernel/fs/stat.h>
|
||||
|
@ -161,26 +162,12 @@ int start(void)
|
|||
|
||||
|
||||
// Test mode !
|
||||
extern void kernel_test(void);
|
||||
//extern void kernel_test(void);
|
||||
//kernel_test();
|
||||
|
||||
//---
|
||||
// Start first process !
|
||||
//---
|
||||
//TODO: initialize sheduler !!
|
||||
|
||||
atomic_start();
|
||||
|
||||
// Test process switch
|
||||
/*__asm__ volatile (
|
||||
"ldc %0, ssr;"
|
||||
"ldc %1, spc;"
|
||||
"rte;"
|
||||
"nop;"
|
||||
:
|
||||
: "r"(0x50000000), "r"(&kernel_test)
|
||||
:
|
||||
);*/
|
||||
|
||||
// Create first process: Vhex.
|
||||
struct process *vhex_process = process_create("Vhex");
|
||||
|
@ -194,9 +181,6 @@ int start(void)
|
|||
while (1) { __asm__ volatile ("sleep"); }
|
||||
}
|
||||
|
||||
// Initialize CPU configuration for the process.
|
||||
vhex_process->context.ssr = 0x40000000;
|
||||
|
||||
// Load programe.
|
||||
//vhex_process->context.spc = (uint32_t)&kernel_test;
|
||||
vhex_process->context.spc = (uint32_t)loader("/mnt/smemfs/VHEX/shell.elf", vhex_process);
|
||||
|
@ -227,31 +211,19 @@ int start(void)
|
|||
}
|
||||
}
|
||||
|
||||
// Test context
|
||||
/*__asm__ volatile (
|
||||
"ldc %0, ssr;"
|
||||
"ldc %1, spc;"
|
||||
"mov %2, r15;"
|
||||
"rte;"
|
||||
"nop;"
|
||||
:
|
||||
: "r"(vhex_process->context.ssr),
|
||||
"r"(&kernel_test),
|
||||
"r"(vhex_process->context.reg[15])
|
||||
:
|
||||
);*/
|
||||
|
||||
// DEBUG !
|
||||
kvram_clear();
|
||||
printk(0, 0, "Initialize scheduler !");
|
||||
printk(0, 1, "Try to start sceduler...");
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
// Set the first process
|
||||
// TODO: send the process to the sheduler !!
|
||||
extern struct process *process_current;
|
||||
process_current = vhex_process;
|
||||
// Initialize sheduler !!
|
||||
sched_initialize();
|
||||
sched_add_task(vhex_process);
|
||||
sched_start();
|
||||
|
||||
// Switch to first process.
|
||||
kernel_switch(&vhex_process->context);
|
||||
|
||||
// normally the kernel SHOULD not
|
||||
// arrive here.
|
||||
// normally the kernel SHOULD / CAN not arrive here.
|
||||
kvram_clear();
|
||||
kvram_print(0, 0, "Kernel job fini !");
|
||||
kvram_display();
|
||||
|
|
|
@ -3,6 +3,12 @@
|
|||
|
||||
int sys_close(int fd)
|
||||
{
|
||||
//TODO !!!!
|
||||
return (-1);
|
||||
extern struct process *process_current;
|
||||
|
||||
// Check fd
|
||||
if (fd < 0 || fd >= PROCESS_NB_OPEN_FILE)
|
||||
return (-1);
|
||||
|
||||
// call VFS close primitive
|
||||
return (vfs_close(&process_current->opfile[fd].file));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
#include <kernel/fs/vfs.h>
|
||||
|
||||
int vfs_close(FILE *file)
|
||||
{
|
||||
// Check error
|
||||
if (file == NULL)
|
||||
return (-1);
|
||||
|
||||
//TODO: call close primitive for device !
|
||||
|
||||
// Update internal dentry counter
|
||||
((struct dentry*)file->private)->counter += 1;
|
||||
return (0);
|
||||
}
|
|
@ -29,7 +29,7 @@ int vfs_open(FILE *file, char const *pathname, int flags)
|
|||
return (-2);
|
||||
}
|
||||
|
||||
// debug
|
||||
// Debug
|
||||
kvram_clear();
|
||||
printk(0, 0, "vfs_open(): inode found !");
|
||||
printk(0, 1, "path: %s", pathname);
|
||||
|
@ -39,10 +39,11 @@ int vfs_open(FILE *file, char const *pathname, int flags)
|
|||
kvram_display();
|
||||
DBG_WAIT;
|
||||
|
||||
//TODO: update interne dentry counter !!
|
||||
// Update interne dentry counter
|
||||
dentry->counter = dentry->counter + 1;
|
||||
|
||||
// Initialize new file.
|
||||
file->private = dentry->inode;
|
||||
file->private = dentry;
|
||||
file->permission = dentry->mode & (~__S_IFMT);
|
||||
file->file_op = dentry->dentry_op.file_op;
|
||||
file->cursor = 0;
|
||||
|
|
|
@ -17,7 +17,7 @@ ssize_t vfs_read(FILE *file, void *buf, size_t count)
|
|||
|
||||
// Read with FS specifique primitive and return the numbe of reading bytes.
|
||||
memset(buf, 0x00, count);
|
||||
ssize_t read = file->file_op->read(file->private, buf, count, file->cursor);
|
||||
ssize_t read = file->file_op->read(((struct dentry*)file->private)->inode, buf, count, file->cursor);
|
||||
if (read != -1)
|
||||
file->cursor = file->cursor + read;
|
||||
return (read);
|
||||
|
|
|
@ -16,7 +16,7 @@ ssize_t vfs_write(FILE *file, const void *buf, size_t count)
|
|||
return (-1);
|
||||
|
||||
// Writa with FS specifique primitive and return the numbe of reading bytes.
|
||||
ssize_t write = file->file_op->write(file->private, buf, count, file->cursor);
|
||||
ssize_t write = file->file_op->write(((struct dentry*)file->private)->inode, buf, count, file->cursor);
|
||||
if (write != -1)
|
||||
file->cursor = file->cursor + write;
|
||||
return (write);
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/atomic.h>
|
||||
|
||||
static struct sched_task *sched_alloc(void)
|
||||
{
|
||||
extern struct sched_task sched_task_cache[SCHED_TASK_NB_MAX];
|
||||
int i;
|
||||
|
||||
i = SCHED_TASK_NB_MAX;
|
||||
while (--i >= 0)
|
||||
{
|
||||
if (sched_task_cache[i].process == NULL)
|
||||
return (&sched_task_cache[i]);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int sched_add_task(struct process *process)
|
||||
{
|
||||
extern struct sched_task *sched_task_queue;
|
||||
struct sched_task *sched_slot;
|
||||
|
||||
// Check error
|
||||
if (process == NULL)
|
||||
return (-1);
|
||||
|
||||
// Start atomic operations
|
||||
atomic_start();
|
||||
|
||||
// Try to find free slot
|
||||
sched_slot = sched_alloc();
|
||||
if (sched_slot == NULL)
|
||||
{
|
||||
atomic_stop();
|
||||
return (-2);
|
||||
}
|
||||
|
||||
// Initialize new task
|
||||
// TODO: update quantum ticks management
|
||||
sched_slot->priority._static = SCHED_QUANTUM_TICKS;
|
||||
sched_slot->priority._dynamic = 0;
|
||||
sched_slot->process = process;
|
||||
sched_slot->status = SCHED_RUNNING;
|
||||
|
||||
// Register task into scheduler task queue
|
||||
sched_slot->next = sched_task_queue;
|
||||
sched_task_queue = sched_slot;
|
||||
|
||||
// Stop atomic operation
|
||||
atomic_stop();
|
||||
return (0);
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
.text
|
||||
|
||||
.global _sched_context_switch
|
||||
.type _sched_context_switch, @function
|
||||
|
||||
.align 2
|
||||
/*
|
||||
** void sched_context_switch(common_context_t *current, common_context_t *next);
|
||||
**
|
||||
** @note:
|
||||
** r4 - current scheduler task
|
||||
** r5 - next task
|
||||
** r0 - tmp
|
||||
*/
|
||||
_sched_context_switch:
|
||||
! Save contexts arg
|
||||
mov.l r8, @-r15 ! save r8
|
||||
mov.l r9, @-r15 ! save r9
|
||||
mov r4, r8 ! save current context into unbankable reg
|
||||
mov r5, r9 ! save next context into unbankable reg
|
||||
|
||||
|
||||
! Update SR register to block interrupt / exception and
|
||||
! switch register bank to simalate system call.
|
||||
! @note:
|
||||
! Normaly this is the TMU0 interrupt so the interrupt
|
||||
! and register banck is already switchted BUT durring the
|
||||
! bootstrap part, the kernel call this function in "user"
|
||||
! context. This is why we force update CPU configuration.
|
||||
mov.l .sr_msk, r1 ! get mask for SR.BL = 1, SR.RB = 1 and SR.IMASK = 0b1111
|
||||
stc sr, r0 ! get SR register
|
||||
or r1, r0 ! set mask for BL, RB and IMASK
|
||||
ldc r0, sr ! update SR regsiter
|
||||
|
||||
|
||||
! Restore context arg
|
||||
mov r8, r4 ! restore current context
|
||||
mov r9, r5 ! restore next context
|
||||
mov.l @r15+, r9 ! restore r9
|
||||
mov.l @r15+, r8 ! restore r8
|
||||
|
||||
save_current_context:
|
||||
! Check current process
|
||||
! @note: current process can be NULL !
|
||||
tst r4, r4 ! if current task == NULL...
|
||||
bt context_load ! ...if yes, jump at <context_switch>
|
||||
add #88, r4 ! get &process->context (end)
|
||||
|
||||
! save current context
|
||||
sts.l pr, @-r4 ! get pr regsiter
|
||||
stc.l spc, @-r4 ! get spc regsiter
|
||||
stc.l ssr, @-r4 ! get ssr regsiter
|
||||
sts.l mach, @-r4 ! get mach regsiter
|
||||
sts.l macl, @-r4 ! get macl regsiter
|
||||
stc.l gbr, @-r4 ! get gbr regsiter
|
||||
mov.l r15, @-r4 ! get r15 register
|
||||
mov.l r14, @-r4 ! get r14 regsiter
|
||||
mov.l r13, @-r4 ! get r13 regsiter
|
||||
mov.l r12, @-r4 ! get r12 regsiter
|
||||
mov.l r11, @-r4 ! get r11 regsiter
|
||||
mov.l r10, @-r4 ! get r10 regsiter
|
||||
mov.l r9, @-r4 ! get r9 regsiter
|
||||
mov.l r8, @-r4 ! get r8 regsiter
|
||||
stc.l R7_BANK, @-r4 ! get "process" r7 regsiter
|
||||
stc.l R6_BANK, @-r4 ! get "process" r6 regsiter
|
||||
stc.l R5_BANK, @-r4 ! get "process" r5 regsiter
|
||||
stc.l R4_BANK, @-r4 ! get "process" r4 regsiter
|
||||
stc.l R3_BANK, @-r4 ! get "process" r3 regsiter
|
||||
stc.l R2_BANK, @-r4 ! get "process" r2 regsiter
|
||||
stc.l R1_BANK, @-r4 ! get "process" r1 regsiter
|
||||
stc.l R0_BANK, @-r4 ! get "process" r0 regsiter
|
||||
|
||||
|
||||
context_load:
|
||||
! Load next process
|
||||
! @note: next process can not be NULL !
|
||||
ldc.l @r5+, R0_BANK ! set "process" r0 regsiter
|
||||
ldc.l @r5+, R1_BANK ! set "process" r1 regsiter
|
||||
ldc.l @r5+, R2_BANK ! set "process" r2 regsiter
|
||||
ldc.l @r5+, R3_BANK ! set "process" r3 regsiter
|
||||
ldc.l @r5+, R4_BANK ! set "process" r4 regsiter
|
||||
ldc.l @r5+, R5_BANK ! set "process" r5 regsiter
|
||||
ldc.l @r5+, R6_BANK ! set "process" r6 regsiter
|
||||
ldc.l @r5+, R7_BANK ! set "process" r7 regsiter
|
||||
mov.l @r5+, r8 ! set r8 regsiter
|
||||
mov.l @r5+, r9 ! set r9 regsiter
|
||||
mov.l @r5+, r10 ! set r10 regsiter
|
||||
mov.l @r5+, r11 ! set r11 regsiter
|
||||
mov.l @r5+, r12 ! set r12 regsiter
|
||||
mov.l @r5+, r13 ! set r13 regsiter
|
||||
mov.l @r5+, r14 ! set r14 regsiter
|
||||
mov.l @r5+, r15 ! set r15 register
|
||||
ldc.l @r5+, gbr ! set gbr regsiter
|
||||
lds.l @r5+, macl ! set macl regsiter
|
||||
lds.l @r5+, mach ! set mach regsiter
|
||||
ldc.l @r5+, ssr ! set ssr regsiter
|
||||
ldc.l @r5+, spc ! set spc regsiter
|
||||
lds.l @r5+, pr ! set pr regsiter
|
||||
|
||||
|
||||
! Process switch
|
||||
rte ! use RTE to switch process
|
||||
nop ! (db) nop
|
||||
|
||||
.align 4
|
||||
.sr_msk: .long 0x700000f0
|
||||
.end
|
|
@ -0,0 +1,32 @@
|
|||
#include <kernel/scheduler.h>
|
||||
|
||||
// Internal task queue
|
||||
struct sched_task sched_task_cache[SCHED_TASK_NB_MAX];
|
||||
struct sched_task *sched_task_current;
|
||||
struct sched_task *sched_task_queue;
|
||||
struct process *process_current;
|
||||
|
||||
void sched_initialize(void)
|
||||
{
|
||||
// Initialize internal scheduler cache
|
||||
for (int i = 0 ; i < SCHED_TASK_NB_MAX ; i = i + 1)
|
||||
{
|
||||
sched_task_queue[i].status = SCHED_DOWN;
|
||||
sched_task_queue[i].process = NULL;
|
||||
sched_task_queue[i].priority._static = 0;
|
||||
sched_task_queue[i].priority._dynamic = 0;
|
||||
sched_task_queue[i].next = NULL;
|
||||
}
|
||||
|
||||
// Initialize internal process informations
|
||||
// @note:
|
||||
// * process_sched_current Used by the kernel to handle
|
||||
// interrupt / exception
|
||||
// * process_user_current Used by the kernel to allow
|
||||
// interaction with the Video RAM
|
||||
// and the screen driver.
|
||||
// TODO: use internal vram for each processus ?
|
||||
sched_task_current = NULL;
|
||||
sched_task_queue = NULL;
|
||||
process_current = NULL;
|
||||
}
|
|
@ -5,8 +5,8 @@
|
|||
|
||||
struct process *process_create(const char *name)
|
||||
{
|
||||
extern struct dentry *vfs_root_node;
|
||||
extern struct process *process_current;
|
||||
extern struct dentry *vfs_root_node;
|
||||
struct process *process;
|
||||
pid_t process_pid;
|
||||
|
||||
|
@ -83,7 +83,7 @@ struct process *process_create(const char *name)
|
|||
process->context.gbr = 0x00000000;
|
||||
process->context.macl = 0x00000000;
|
||||
process->context.mach = 0x00000000;
|
||||
process->context.ssr = 0x00000000;
|
||||
process->context.ssr = 0x40000000; // <- force privilegied mode !
|
||||
process->context.spc = 0x00000000;
|
||||
|
||||
// Initialise file cache
|
|
@ -3,7 +3,6 @@
|
|||
// Create all internal global
|
||||
// used to handle process.
|
||||
struct process_stack process_stack[PROCESS_MAX];
|
||||
struct process *process_current;
|
||||
|
||||
__attribute__((constructor))
|
||||
void process_constructor(void)
|
||||
|
@ -13,7 +12,4 @@ void process_constructor(void)
|
|||
{
|
||||
process_stack[i].status = PROC_IDLE;
|
||||
}
|
||||
|
||||
// No process is currently running.
|
||||
process_current = NULL;
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include <kernel/scheduler.h>
|
||||
#include <kernel/atomic.h>
|
||||
#include <kernel/util.h>
|
||||
|
||||
//TODO: assembly !
|
||||
void sched_schedule(void)
|
||||
{
|
||||
extern struct sched_task *sched_task_current;
|
||||
extern struct sched_task *sched_task_queue;
|
||||
struct sched_task *task_current;
|
||||
struct sched_task *task_next;
|
||||
common_context_t *context_current;
|
||||
common_context_t *context_next;
|
||||
|
||||
// Start atomic operation
|
||||
atomic_start();
|
||||
|
||||
// Check current task
|
||||
if (sched_task_current == NULL)
|
||||
{
|
||||
task_current = NULL;
|
||||
task_next = (sched_task_queue != NULL)
|
||||
? sched_task_queue
|
||||
: NULL;
|
||||
|
||||
} else {
|
||||
task_current = sched_task_current;
|
||||
task_next = (sched_task_current->next != NULL)
|
||||
? sched_task_current->next
|
||||
: sched_task_queue;
|
||||
}
|
||||
|
||||
// Check potantial error
|
||||
if (task_next == NULL || task_next == sched_task_current)
|
||||
{
|
||||
atomic_stop();
|
||||
return;
|
||||
}
|
||||
|
||||
//TODO: check process status !!!
|
||||
|
||||
// Update internal scheduler task cursor
|
||||
sched_task_current = task_next;
|
||||
|
||||
|
||||
// Get context
|
||||
context_current =
|
||||
(task_current != NULL)
|
||||
? &task_current->process->context
|
||||
: NULL;
|
||||
context_next =
|
||||
(task_next != NULL)
|
||||
? &task_next->process->context
|
||||
: NULL;
|
||||
|
||||
// DEBUG !
|
||||
kvram_clear();
|
||||
printk(0, 0, "Scheduler_schudele !");
|
||||
printk(0, 1, "task current = %p", task_current);
|
||||
printk(0, 2, "task next = %p", task_next);
|
||||
printk(0, 3, "context current = %p", context_current);
|
||||
printk(0, 4, "context next = %p", context_next);
|
||||
kvram_display();
|
||||
DBG_WAIT;
|
||||
printk(0, 5, "context switch !");
|
||||
kvram_display();
|
||||
|
||||
// Context switch
|
||||
sched_context_switch(context_current, context_next);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
#include <kernel/scheduler.h>
|
||||
|
||||
void sched_start(void)
|
||||
{
|
||||
extern struct sched_task *sched_task_queue;
|
||||
extern struct process *process_current;
|
||||
|
||||
//TODO: get CPU frequency !
|
||||
//TODO: setup TMU0 interrupt !
|
||||
process_current = sched_task_queue->process;
|
||||
sched_schedule();
|
||||
}
|
|
@ -27,6 +27,11 @@ SECTIONS
|
|||
.rodata : {
|
||||
*(.rodata);
|
||||
*(.rodata.*);
|
||||
|
||||
/* Builtin */
|
||||
_bbuiltin_section = ALIGN(4) ;
|
||||
*(.builtin);
|
||||
_ebuiltin_section = . ;
|
||||
}
|
||||
|
||||
.data ALIGN(4) : {
|
||||
|
|
|
@ -52,11 +52,11 @@ int main(void)
|
|||
input[cmd_size - 1] = '\0';
|
||||
|
||||
// Check buit-in.
|
||||
//if (check_builtin(input) != 0)
|
||||
//{
|
||||
if (check_builtin(input) != 0)
|
||||
{
|
||||
write(fd, input, cmd_size - 1);
|
||||
write(fd, ": command not found\n", 20);
|
||||
//}
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*#include "util.h"
|
||||
#include "util.h"
|
||||
#include "builtin.h"
|
||||
#include <lib/string.h>
|
||||
|
||||
|
@ -18,7 +18,12 @@ int check_builtin(char *cmd)
|
|||
{
|
||||
if (strcmp(list[i].name, cmd) != 0)
|
||||
continue;
|
||||
|
||||
|
||||
// Execute builtin
|
||||
list[i].entry(0, NULL);
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
// Create subprocess
|
||||
//pid = fork();
|
||||
//if (pid < 0)
|
||||
|
@ -27,19 +32,17 @@ int check_builtin(char *cmd)
|
|||
// If we are the child execute
|
||||
// the builtins.
|
||||
//if (pid == 0)
|
||||
//{
|
||||
dclear();
|
||||
dprint(0, 0, "Child process !!");
|
||||
dprint(0, 1, "PID = %d", getpid());
|
||||
dprint(0, 2, "PPID = %d", getppid());
|
||||
dupdate();
|
||||
// //{
|
||||
// dclear();
|
||||
// dprint(0, 0, "Child process !!");
|
||||
// dprint(0, 1, "PID = %d", getpid());
|
||||
// dprint(0, 2, "PPID = %d", getppid());
|
||||
// dupdate();
|
||||
|
||||
// list[i].entry(0, NULL);
|
||||
return (0);
|
||||
// } else {
|
||||
// waitpid(pid, &wstatus, WCONTINUED);
|
||||
//TODO: signal handling.
|
||||
// }
|
||||
// }
|
||||
// return (1);
|
||||
}*/
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue