Snail OS 0.03 的一些小的改进,然而又引入了新的问题,头痛啊!

最近在调试的过程中,发现进程或者线程的运行级别被改变。通过仔细研究进程调度程序还有相关阻塞(休眠)和唤醒函数,终于有了小小的发现。

同时在kernel.c中加入了新的信号量代码,从而简单地实现了线程的同步。

不过,系统调用却出现了问题,暂时真的不知道怎么处理。

void schedule(void) {
	ASSERT((intr_get_status() == INTR_OFF));
	struct task* cur = running_thread();
	if(cur->status == RUNNING) {
		ASSERT(!elem_find(thread_ready_list, &cur->general_tag));
        // 处理器上运行的当前线程将被加入到就绪队列,这里要根据线程的
        // 运行级别加入到相应的级别链表中
		thread_ready_list = &ready_list[cur->level];	
		list_append(thread_ready_list, &cur->general_tag);
		cur->ticks = cur->priority;
		cur->status = READY;
	} else {
		
	}
	int i;
	for(i = 0; i < 8; i++) {
		thread_ready_list = &ready_list[i];
		if(!list_empty(thread_ready_list)) {
			break;
		}
	}
	ASSERT(!list_empty(thread_ready_list));
	thread_tag = list_pop(thread_ready_list);
	struct task* next = elem2entry(struct task, general_tag, thread_tag);
	next->status = RUNNING;
	process_activate(next);
	switch_to(cur, next);
}




void thread_unblock(struct task* pthread) {
	enum intr_status old_status = intr_disable();
//	ASSERT(((pthread->status == BLOCKED) ||
//		    (pthread->status == HANDING) ||
//			(pthread->status == WAITING)));
	if(pthread->status != READY) {
		ASSERT(!(elem_find(thread_ready_list, &pthread->general_tag)));
		if(elem_find(thread_ready_list, &pthread->general_tag)) {
			PANIC("thread_unblock: blocked thread in ready_list\n");
		}
        // 这里也是有同样的问题
		thread_ready_list = &ready_list[pthread->level];
		list_push(thread_ready_list, &pthread->general_tag);
		pthread->status = READY;
	}
	intr_set_status(old_status);
}

void yield(void) {
	enum intr_status old_status = intr_disable();
	struct task* cur = running_thread();
	ASSERT(!elem_find(thread_ready_list, &cur->general_tag));
    // 还有这里
	thread_ready_list = &ready_list[cur->level];
	list_append(thread_ready_list, &cur->general_tag);
	cur->status = READY;
	schedule();
	intr_set_status(old_status);
}
// kernel.c

// 全局描述表的基地址是0x6000,大小为256 * 8 - 1。
// 中断描述符表的基地址是0x7000,大小为256 * 8 - 1。
// 内核页目录表的基地址是0x8000,占用1个页。
// 内核页表的基地址是0x9000,共占用8个页。

#include "x.h"
#include "string.h"
#include "multiboot2.h"
#include "gdt_idt_init.h"
#include "memory.h"
#include "intr.h"
#include "intr_status_op.h"
#include "debug.h"
#include "thread.h"
#include "sync.h"
#include "console.h"
#include "tss.h"
#include "process.h"
#include "syscall.h"
#include "sheet.h"
#include "mouse.h"
#include "ioqueue.h"
#include "timer.h"
#include "hd.h"
#include "fs.h"


struct event {
	void* msgptr;
	int count;
	unsigned int type;
	struct list waiters;
};

struct event event_array[256];
struct event* pevent_, * pevent_1;

void event_init(struct event* event_, void* msg, int cnt, int type);
void event_array_init(struct event* event_array_);
struct event* get_event(struct event* event_array_);
void sema_pend(struct event* pevent);
void sema_post(struct event* pevent);


unsigned int mk = 0;
void k_thread_a(void* arg);
void k_thread_b(void* arg);
void k_thread_c(void* arg);
void idle(void* arg);

unsigned int mua, mub;
void ua(void);
void ub(void);

struct semaphore fs_sema;

void init_all(unsigned int magic, unsigned int addr);

extern unsigned int ppp;

void kernel_main(unsigned int magic, unsigned int addr) {
	int i;
	init_all(magic, addr);
	
	sema_init(&fs_sema, 0);
	
	event_array_init(event_array);
	pevent_ = get_event(event_array);
	event_init(pevent_, NULL, 0, 0);
	pevent_1 = get_event(event_array);
	event_init(pevent_1, NULL, 0, 0);	

	struct bmp_buf_info bbi;
	
	save_bmp((char*)&ppp, &bbi);

	unsigned int* v = (unsigned int*)(0xe0000000 + 1024 * 128 * 4);
	put_bmp_buf(v, 1024, 40, 40, &bbi);

	put_gb2312_buf(v, 1024, 300, 300, 0x00ffffff, "我爱你蜗牛系统!");

	
	
	struct SHEET* sht_back, * sht_mouse, *sht_win, *sht_win1;
	
	void* buf_back = get_kernel_pages(up_pgs(1024 * (768 - 128) * 4));
	memcpy_((void*)buf_back, (void*)v, 1024 * (768 - 128) * 4);
	fill_circle(buf_back, 1024,  200, 300, 80, 0x00ffff00);
	int* buf_win = get_kernel_pages(up_pgs(500 * 300 * sizeof(int)));

	int* buf_win1 = get_kernel_pages(up_pgs(300 * 250 * sizeof(int)));
	for(i = 0; i < 500 * 300; i++) {
		buf_win[i] = 0x00cccccc;
	}
	for(i = 0; i < 300 * 250; i++) {
		buf_win1[i] = 0x00cccccc;
	}
	put_bmp_buf(buf_win, 500, 10, 10, &bbi);
	put_bmp_buf(buf_win1, 300, 10, 10, &bbi);
	fill_rectangle(buf_win1, 300, 180, 10, 80, 80, 0x00ff0000);
	
	struct point a, b, c;
	a.x = 80 + 200;
	a.y = 5;
	b.x = 20 + 200;
	b.y = 200;
	c.x = 150 + 200;
	c.y = 210;
	
	fill_triangle(buf_win, 500, &a, &b, &c, 0x00ffffff);
	
	put_str_buf(buf_win, 500, 80, 80, 0x00ff0000,
	"Hello, SnailOS. Good luck!...");
	
	unsigned int buf_mouse[16 * 16];
	make_mouse_pointer(buf_mouse, 0x003098df);


	shtctl = shtctl_init(v, 1024, 768 - 128);

	sht_back = sheet_alloc(shtctl);
	sht_mouse = sheet_alloc(shtctl);
	sht_win = sheet_alloc(shtctl);
	sht_win1 = sheet_alloc(shtctl);
	sheet_setbuf(sht_back, buf_back, 1024, 768 - 128, -1);
	sheet_setbuf(sht_mouse, buf_mouse, 16, 16, 0x003098df);
	sheet_setbuf(sht_win, buf_win, 500, 300, -1);	
	sheet_setbuf(sht_win1, buf_win1, 300, 250, -1);
		
	sheet_slide(sht_back, 0, 0);
	sheet_slide(sht_win, 80, 200);
	sheet_slide(sht_mouse, 300, 300);
	sheet_slide(sht_win1, 2, 2);
	sheet_updown(sht_back, 0);
	sheet_updown(sht_mouse, 3);
	sheet_updown(sht_win, 1);
	sheet_updown(sht_win1, 2);

	timer_set(t_m, 100, &main_ioq, 0x10000);
	timer_set(t_m, 300, &main_ioq, 0x10001);

	
	thread_ready_list = &ready_list[0];

	
	out(0x21, 0xf8);
	out(0xa1, 0xae);	
	intr_enable();


	thread_start("k_thread_a", 10, k_thread_a, "argA ", 1);
	thread_start("k_thread_b", 1, k_thread_b, "argB ", 1);
	thread_start("k_thread_c", 2, k_thread_c, "argC ", 1);

	process_execute(ua, "UA", 1);
	process_execute(ub, "UB", 2);
	
	thread_start("Idle", 1, idle, "idle ", 7);

	int ioq_data, mx, my;
	struct mouse_dec mdec;
	int j, x, y, mmx = -1, mmy = -1;
	struct SHEET* sht = NULL;
	while(1) {
	printf_(" %d ", running_thread()->level);
		enum intr_status old_status = intr_disable();
		if(ioq_empty(&main_ioq)) {
			thread_block(BLOCKED);
//			intr_set_status(old_status);			
		} else {
			ioq_data = ioq_getint(&main_ioq);
			intr_set_status(old_status);
			if(mouse_decode(&mdec, ioq_data)) {				
				mx += mdec.x;
				my += mdec.y;
				if(mx < 0) {
					mx = 0;
				}
				if(my < 0) {
					my = 0;
				}				
				if(mx > 1024 - 1) {
					mx = 1024 - 1;
				}
				if(my > 768 - 1 - 128) {
					my = 768 - 1 - 128;
				}
				sheet_slide(sht_mouse, mx, my);
				int btn = mdec.btn;
				if(btn & 1) {
					if(mmx < 0) {
						for(j = shtctl->top - 1; j > 0; j--) {
							sht = shtctl->sheets[j];
							x = mx - sht->vx0;
							y = my - sht->vy0;
							if(0 <= x && x < sht->bxsize &&
							   0 <= y && y < sht->bysize)
							{
								if(sht->buf[y * sht->bxsize + x] 
								!= sht->col_inv) {
									sheet_updown(sht, shtctl->top - 1);
									mmx = mx;
									mmy = my;
								}
									break;
							}
						}
					} else {
						x = mx - mmx;
						y = my - mmy;
						sheet_slide(sht, sht->vx0 + x, sht->vy0 + y);
						mmx = mx;
						mmy = my;
					}	
				} else {
					mmx = -1;
				}
				if(btn & 2) {

				}
				if(btn & 4) {
			
				}
			} 
			
			
			
			if(ioq_data == 0x10000) {
				put_gb2312_buf((int*)buf_win, 500, 20, 60, 0x00ff0000, "你好蜗牛操作系统!");
				timer_set(t_m, 80, &main_ioq, 0x10001);
				sheet_refresh(sht_win, 20, 60, 20 + 9 * 16, 60 + 16);				
			}
			if(ioq_data == 0x10001) {
				put_gb2312_buf((int*)buf_win, 500, 20, 60, 0x0000ff00, "你好蜗牛操作系统!");
				timer_set(t_m, 90, &main_ioq, 0x10000);
				sheet_refresh(sht_win, 20, 60, 20 + 9 * 16, 60 + 16);				
			}
			if (ioq_data == 0x20000) {

			}
		}
	}
}

void init_all(unsigned int magic, unsigned int addr) {
	pos = 0;
	ticks = 0;
	info_area_cls();
	screen_init();
//	multiboot2_info(magic, addr);
	gdt_init();
	page_init();
	idt_init();
	i8259_init();
	i8253_init();
	mem_init();
	thread_init();
	console_init();
	tss_init();
	syscall_init();
	keyboard_init();
	mouse_init();
	rtc_init();
	ioqueue_init(&main_ioq);
	timer_man_init();
	hd_init();
}


void k_thread_a(void* arg) {
	intr_enable();
	struct fat32_krn_p fat32_p;
	read_mbr_dbr(&fat32_p);
	fat32_krn = fat32_p;
	printf_("!!!%x %x %x!!!", fat32_krn.fat1_p, fat32_krn.root_dir_p,
	fat32_krn.root_dir_start_sector);
//	find_file(&fat32_p, "p.bmp");
	
//	find_file(&fat32_p, "kernel");
	
//	find_file(&fat32_p, "hello.txt");
	
//	= file_read(&fat32_p, "hello.txt");
	
//	console_put_str(s);

//	enum intr_status old_status = intr_disable();
//	ioq_putint(&main_ioq, 0x20000);
//	intr_set_status(old_status);
	
//	sema_up(&fs_sema);

	sema_post(pevent_);	
	sema_post(pevent_);

	while(1) {
		
//		console_put_int(mua);
		console_put_str("  Thread A  ");
		console_put_int(running_thread()->level);
//		console_put_str("  ");	
		mtime_sleep(1000);
	}
}

void k_thread_b(void* arg) {
//	void* mkb = (void*)malloc_(1);	
//	hd_read(&hds[0], 0, (void*)mkb, 1);
//	unsigned int* boot_sector_magic = (unsigned int*)
//										((unsigned int)mkb);
//	console_put_int(*boot_sector_magic);

//	sema_down(&fs_sema);


	sema_pend(pevent_);
///*
	char* s = file_read("p.bmp");	
	struct bmp_buf_info bbi;	
	save_bmp((char*)s, &bbi);	
	unsigned int* v = (unsigned int*)(0xe0000000 + 1024 * 128 * 4);
	put_bmp_buf(v, 1024, 700, 400, &bbi);
//*/
	while(1) {	
//		out(0x1f7, 0xec);
//		const char* s = "kernel";
//		console_put_str(format_filename(s));
//		console_put_int(mub);		
		console_put_str("  Thread B  ");
		console_put_int(running_thread()->level);
//		console_put_int(free_((void*)mk));
//		console_put_str("  ");
		mtime_sleep(1000);		
	}
}


void k_thread_c(void* arg) {
//	void* mkb = (void*)malloc_(1);	
//	hd_read(&hds[0], 0, (void*)mkb, 1);
//	unsigned int* boot_sector_magic = (unsigned int*)
//										((unsigned int)mkb);
//	console_put_int(*boot_sector_magic);

//	sema_down(&fs_sema);


	sema_pend(pevent_);
///*
	char* s = file_read("p.bmp");	
	struct bmp_buf_info bbi;	
	save_bmp((char*)s, &bbi);	
	unsigned int* v = (unsigned int*)(0xe0000000 + 1024 * 128 * 4);
	put_bmp_buf(v, 1024, 500, 400, &bbi);
//*/
	while(1) {	
//		out(0x1f7, 0xec);
//		const char* s = "kernel";
//		console_put_str(format_filename(s));
//		console_put_int(mub);		
		console_put_str("  Thread C  ");
		console_put_int(running_thread()->level);
//		console_put_int(free_((void*)mk));
//		console_put_str("  ");
		mtime_sleep(1000);		
	}
}

void ua(void) {
	while(1) {	
		write("   UA   ");
//		mua = malloc_(1);
//		msleep(3000);
	}
}

void ub(void) {
	while(1) {
		write("   UB   ");
//		mub  = malloc_(1);
//		msleep(3000);	
	}
}

void idle(void* arg) {
	unsigned char* s = arg;
	console_put_str(s);
	while(1) {
		__asm__ __volatile__ ("sti; hlt;");
	}
}


// event start

void event_init(struct event* event_, void* msg, int cnt, int type) {
	enum intr_status old_status = intr_disable();
	event_->msgptr = msg;
	event_->count = cnt;
	event_->type = type;
	list_init(&event_->waiters);
	intr_set_status(old_status);
}

void event_array_init(struct event* event_array_) {
	int i;
	for(i = 0; i < 256; i++) {
		event_init(&event_array_[i], NULL, 0, -1);
	}
}

struct event* get_event(struct event* event_array_) {
	int i;
	enum intr_status old_status = intr_disable();
	for(i = 0; i < 256; i++) {
		if(event_array[i].type == -1) {
			break;
		}
	}
	intr_set_status(old_status);
	return &event_array_[i];
}

void sema_pend(struct event* pevent) {
	struct task* cur;
	enum intr_status old_status = intr_disable();	
	if(pevent->count == 0) {
		cur = running_thread();
		list_append(&pevent->waiters, &cur->general_tag);
		cur->status = WAITING;
		schedule();
		intr_set_status(old_status);
	} else {
		pevent->count--;
		intr_set_status(old_status);
	}
}

void sema_post(struct event* pevent) {
	struct list_elem* waiter;
	enum intr_status old_status = intr_disable();
	if(!list_empty(&pevent->waiters)) {
		waiter = list_pop(&pevent->waiters);
		struct task* next = elem2entry(struct task, general_tag, waiter);
		thread_ready_list = &ready_list[next->level];
		list_append(thread_ready_list, waiter);
		intr_set_status(old_status);
	} else {
		pevent->count++;
		intr_set_status(old_status);
	}
}


// event end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_39410618

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值