387 lines
10 KiB
C
387 lines
10 KiB
C
|
||
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||
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;
|
||
}
|
||
}
|
||
} |