r/kernel/main.c

387 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
main.c
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Forrest Yu, 2005
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
#include "type.h"
#include "const.h"
#include "protect.h"
#include "proto.h"
#include "string.h"
#include "global.h"
//TODO 所有要改动的超参数
//0读者优先1写者优先2读写公平
#define STRATEGY 2
#define READERS_ALLOWED 3
#define B_SLEEP_TIME 1
#define C_SLEEP_TIME 2
#define D_SLEEP_TIME 1
#define E_SLEEP_TIME 1
#define F_SLEEP_TIME 2
#define B_PROC_TIME 2
#define C_PROC_TIME 3
#define D_PROC_TIME 3
#define E_PROC_TIME 3
#define F_PROC_TIME 4
//TODO 声明
//每个进程的状态需要进程维护由A来输出0表示正在使用1表示等待使用2表示休眠
#define TIME_SEG (500) //时间片
int proc_state[5]={1,1,1,1,1};
int thread_sleep_time[5];
int thread_proc_time[5];
//两个信号量
SEMAPHORE w_mutex;
SEMAPHORE r_mutex;
//额外的信号量
SEMAPHORE S;
int readers_cnt;//目前在线的读者数量
int writers_cnt;//目前在线的写者数量
int mode;//模式
/*======================================================================*
TODO clearScreen
*======================================================================*/
void clearScreen(){
u8 *base=(u8 *)0xB8000;
for(int i=0;i<0x8000;i+=2){
base[i]=' ';
}
disp_pos=0;
}
/*======================================================================*
TODO init_semaphore
*======================================================================*/
void init_semaphore(SEMAPHORE *semaphore, int value)
{
semaphore->s=0;
semaphore->e=0;
semaphore->value=value;
}
/*======================================================================*
kernel_main
*======================================================================*/
PUBLIC int kernel_main()
{
disp_str("-----\"kernel_main\" begins-----\n");
TASK* p_task = task_table;
PROCESS* p_proc = proc_table;
char* p_task_stack = task_stack + STACK_SIZE_TOTAL;
u16 selector_ldt = SELECTOR_LDT_FIRST;
int i;
for (i = 0; i < NR_TASKS; i++) {
strcpy(p_proc->p_name, p_task->name); // name of the process
p_proc->pid = i; // pid
p_proc->ldt_sel = selector_ldt;
memcpy(&p_proc->ldts[0], &gdt[SELECTOR_KERNEL_CS >> 3],
sizeof(DESCRIPTOR));
p_proc->ldts[0].attr1 = DA_C | PRIVILEGE_TASK << 5;
memcpy(&p_proc->ldts[1], &gdt[SELECTOR_KERNEL_DS >> 3],
sizeof(DESCRIPTOR));
p_proc->ldts[1].attr1 = DA_DRW | PRIVILEGE_TASK << 5;
p_proc->regs.cs = ((8 * 0) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.ds = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.es = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.fs = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.ss = ((8 * 1) & SA_RPL_MASK & SA_TI_MASK)
| SA_TIL | RPL_TASK;
p_proc->regs.gs = (SELECTOR_KERNEL_GS & SA_RPL_MASK)
| RPL_TASK;
p_proc->regs.eip = (u32)p_task->initial_eip;
p_proc->regs.esp = (u32)p_task_stack;
p_proc->regs.eflags = 0x1202; /* IF=1, IOPL=1 */
p_task_stack -= p_task->stacksize;
p_proc++;
p_task++;
selector_ldt += 1 << 3;
}
proc_table[0].ticks = proc_table[0].priority = 15;
proc_table[1].ticks = proc_table[1].priority = 5;
proc_table[2].ticks = proc_table[2].priority = 3;
k_reenter = 0;
ticks = 0;
p_proc_ready = proc_table;
/* 初始化 8253 PIT */
out_byte(TIMER_MODE, RATE_GENERATOR);
out_byte(TIMER0, (u8) (TIMER_FREQ/HZ) );
out_byte(TIMER0, (u8) ((TIMER_FREQ/HZ) >> 8));
put_irq_handler(CLOCK_IRQ, clock_handler); /* 设定时钟中断处理程序 */
enable_irq(CLOCK_IRQ); /* 让8259A可以接收时钟中断 */
//TODO 初始化超参数
init_semaphore(&r_mutex, READERS_ALLOWED);
init_semaphore(&w_mutex, 1);
init_semaphore(&S, 1);
thread_sleep_time[0]=B_SLEEP_TIME*TIME_SEG;
thread_sleep_time[1]=C_SLEEP_TIME*TIME_SEG;
thread_sleep_time[2]=D_SLEEP_TIME*TIME_SEG;
thread_sleep_time[3]=E_SLEEP_TIME*TIME_SEG;
thread_sleep_time[4]=F_SLEEP_TIME*TIME_SEG;
thread_proc_time[0]=B_PROC_TIME*TIME_SEG;
thread_proc_time[1]=C_PROC_TIME*TIME_SEG;
thread_proc_time[2]=D_PROC_TIME*TIME_SEG;
thread_proc_time[3]=E_PROC_TIME*TIME_SEG;
thread_proc_time[4]=F_PROC_TIME*TIME_SEG;
readers_cnt=0;
writers_cnt=0;
mode=STRATEGY;
clearScreen();
restart();
while(1){}
}
/*======================================================================*
TestA
*======================================================================*/
// void TestA()
// {
// int i = 0;
// while (1) {
// disp_str("A.");
// milli_delay(10);
// }
// }
/*======================================================================*
TestB
*======================================================================*/
// void TestB()
// {
// int i = 0x1000;
// while(1){
// disp_str("B.");
// milli_delay(10);
// }
// }
/*======================================================================*
TestC
*======================================================================*/
// void TestC()
// {
// int i = 0x2000;
// while(1){
// disp_str("C.");
// milli_delay(10);
// }
// }
/*======================================================================*
A
*======================================================================*/
void A()
{
int i = 1;
while (1) {
if (i > 20) { while (1); }
char *str;
if (i < 10) {
str = " \0";
str[0] = (char) ('0' + i);
}
else {
str = " \0";
str[0] = (char) ('0' + i / 10);
str[1] = (char) ('0' + i % 10);
}
print_str(str);
for (int j = 0; j < 6; ++j) {
//每个进程的状态需要每个进程维护并且由A来输出 0-正在使用 1-等待使用 2-休眠
//int proc_state[5] = {-1, 0, 1, 2, -1};
if (j == 5) {
print_str("\n");
break;
}
if (proc_state[j] == -1) print_str("None ");
else if (proc_state[j] == 0) disp_color_str("O ", 0x0A);
else if (proc_state[j] == 1) disp_color_str("X ", 0x0C);
else if (proc_state[j] == 2) disp_color_str("Z ", 0x03);
}
i++;
milli_delay(TIME_SEG);
}
}
/*======================================================================*
READER_B
*======================================================================*/
void READER_B()
{
reader(0);
}
/*======================================================================*
READER_C
*======================================================================*/
void READER_C()
{
reader(1);
}
/*======================================================================*
READER_D
*======================================================================*/
void READER_D()
{
reader(2);
}
/*======================================================================*
WRITER_E
*======================================================================*/
void WRITER_E()
{
writer(3);
}
/*======================================================================*
WRITER_F
*======================================================================*/
void WRITER_F()
{
writer(4);
}
/*======================================================================*
writer
读者优先使用两个信号量一个用于管理写者w_mutex一个用于管理读者r_mutex
写者进行pv操作维护proc_state[]
读者先把写者锁死再进行pv再放开写者维护proc_state[]
写者优先使用三个信号量一个用于管理写者w_mutex一个用于管理读者r_mutex一个用于读者能不能读
写者要把读者锁死
读者要看有没有被锁死
读写公平使用三个信号量一个用于管理写者w_mutex一个用于管理读者r_mutex一个互斥信号量S
写者进行pv操作互斥信号量
读者进行pv操作互斥信号量
*======================================================================*/
void writer(int i)
{
if(mode ==0){
while(1){
p(&w_mutex);
proc_state[i]=0;
milli_delay(thread_proc_time[i]);
v(&w_mutex);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
else if(mode == 1){
while(1){
if(writers_cnt==0) p(&S);
writers_cnt++;
p(&w_mutex);
proc_state[i]=0;
milli_delay(thread_proc_time[i]);
writers_cnt--;
v(&w_mutex);
if(writers_cnt==0) v(&S);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
else if(mode == 2){
while(1){
p(&S);
p(&w_mutex);
proc_state[i]=0;
milli_delay(thread_proc_time[i]);
v(&w_mutex);
v(&S);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
}
/*======================================================================*
reader
*======================================================================*/
void reader(int i)
{
if(mode ==0){
while(1){
if(readers_cnt==0) p(&w_mutex);
readers_cnt++;
p(&r_mutex);
proc_state[i]=0;
milli_delay(thread_proc_time[i]);
v(&r_mutex);
readers_cnt--;
if(readers_cnt==0) v(&w_mutex);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
else if(mode ==1){
while(1){
p(&r_mutex);
p(&S);
v(&S);
if(readers_cnt==0) p(&w_mutex);
readers_cnt++;
proc_state[i]=0;
milli_delay(thread_proc_time[i]);
readers_cnt--;
if(readers_cnt==0) v(&w_mutex);
v(&r_mutex);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
else if(mode ==2){
while(1){
p(&S);
p(&r_mutex);
if(readers_cnt==0) p(&w_mutex);
readers_cnt++;
proc_state[i]=0;
v(&S);
milli_delay(thread_proc_time[i]);
readers_cnt--;
if(readers_cnt==0) v(&w_mutex);
v(&r_mutex);
proc_state[i]=2;
milli_delay(thread_sleep_time[i]);
proc_state[i]=1;
}
}
}