Exemplo n.º 1
0
//等待子进程调用exit,将子进程的退出状态保存到status指向的变量
//成功则返回子进程的pid,失败返回-1
pid_t sys_wait(int32_t* status){
	struct task_struct* parent_thread = running_thread();

	while(1){
		//优先处理已经是挂起状态的任务
		struct list_elem* child_elem = list_traversal(&thread_all_list,find_hanging_child,parent_thread->pid);
		//若有挂起的任务
		if(child_elem != NULL){
			struct task_struct* child_thread = elem2entry(struct task_struct,all_list_tag,child_elem);
			*status = child_thread->exit_status;

			//thread_exit之后,pcb会被回收,因此提前获取pid
			uint16_t child_pid = child_thread->pid;

			//从就绪队列和全部队列中删除进程表项
			thread_exit(child_thread,false);	//传入false,使thread_exit调用后回到此处
			//进程表项是进程或线程的最后保留的资源,至此该进程彻底消失了

			return child_pid;
		}
		
		//判断是否有子进程
		child_elem = list_traversal(&thread_all_list,find_child,parent_thread->pid);
		if(child_elem == NULL){	//若没有子进程则出错返回
			return -1;
		}else{
			//若子进程还未运行完,即还未调用exit,则将自己挂起,直到子进程在执行exit时将自己唤醒
			thread_block(TASK_WAITING);
		}
	}
}
Exemplo n.º 2
0
Arquivo: ide.c Projeto: YMChenLiye/os
//硬盘数据结构初始化
void ide_init(){
	printk("ide_init start\n");
	uint8_t hd_cnt = *((uint8_t*)(0x475));			//获取硬盘的数量
	ASSERT(hd_cnt > 0);
	list_init(&partition_list);
	channel_cnt = DIV_ROUND_UP(hd_cnt,2);			//一个ide通道上有两个硬盘,根据硬盘数量反推有几个ide通道
	struct ide_channel* channel;
	uint8_t channel_no = 0,dev_no = 0;

	//处理每个通道上的硬盘
	while(channel_no < channel_cnt){
		channel = &channels[channel_no];
		sprintf(channel->name,"ide%d",channel_no);

		//为每个ide通道初始化端口基址及中断向量
		switch(channel_no){
			case 0:
				channel->port_base = 0x1f0;			//ide0通道的起始端口号为0x1f0
				channel->irq_no = 0x20 + 14;		//从片8259a上倒数第二的中断引脚,也就是ide0通道的中断向量号
				break;
			case 1:
				channel->port_base = 0x170;			//ide1通道的起始端口号为0x170
				channel->irq_no = 0x20 + 15;		//从片8259a上最后一个引脚,我们用来响应ide1通道上的硬盘中断
				break;
		}

		channel->expecting_intr = false;			//为向硬盘写入指令时不期待硬盘的中断
		lock_init(&channel->lock);

		//初始化为0,目的是向硬盘控制器请求数据后,硬盘驱动sema_down此信号量会阻塞线程
		//直到硬盘完成后通过发中断,以后中断处理程序将此信号量sema_up,唤醒线程
		sema_init(&channel->disk_done,0);

		register_handler(channel->irq_no,intr_hd_handler);
		/* 分别获取两个硬盘的参数及分区信息 */
		while (dev_no < 2) {
			struct disk* hd = &channel->devices[dev_no];
			hd->my_channel = channel;
			hd->dev_no = dev_no;
			sprintf(hd->name, "sd%c", 'a' + channel_no * 2 + dev_no);
			identify_disk(hd);	 // 获取硬盘参数
			if (dev_no != 0) {	 // 内核本身的裸硬盘(hd60M.img)不处理
				partition_scan(hd, 0);  // 扫描该硬盘上的分区  
			}
			p_no = 0, l_no = 0;
			dev_no++; 
		}
		dev_no = 0;	

		channel_no++;								//下一个channel
	}

	printk("\n   all partition info\n");
	/* 打印所有分区信息 */
	list_traversal(&partition_list, partition_info, (int)NULL);
	printk("ide_init done\n");
}
Exemplo n.º 3
0
int main()
{
	List *L = list_create(&cmp);
	int num = 10;
	int i = 0;
	int *key = NULL;
	for (i = 0; i < num; i++) {
		key = malloc(sizeof(int));
		*key = i;
		list_insert(L, key);
	}
	list_traversal(L, visit);
	list_retraversal(L, visit);
	printf("\n");
	key = malloc(sizeof(int));
	*key = 2;
	key = list_delete(L, key);
	list_traversal(L, visit);
	printf("\n");

	return 0;
}
Exemplo n.º 4
0
//子进程用来结束自己时调用
void sys_exit(int32_t status){
	struct task_struct* child_thread = running_thread();
	child_thread->exit_status = status;
	if(child_thread->parent_pid == -1){
		PANIC("sys_exit: child_thread->parent_pid is -1\n");
	}

	//将进程child_thread的所有子进程都过继给init
	list_traversal(&thread_all_list,init_adopt_a_child,child_thread->pid);

	//回收进程child_thread的资源
	release_prog_resource(child_thread);

	//如果父进程正在等待子进程退出,将父进程唤醒
	struct task_struct* parent_thread = pid2thread(child_thread->parent_pid);
	if(parent_thread->status == TASK_WAITING){
		thread_unblock(parent_thread);
	}

	//将自己挂起,等待父进程获取其status,并回收其pcb
	thread_block(TASK_HANGING);
}
Exemplo n.º 5
0
/* 在磁盘上搜索文件系统,若没有则格式化分区创建文件系统 */
void filesys_init() {
   uint8_t channel_no = 0, dev_no, part_idx = 0;

   /* sb_buf用来存储从硬盘上读入的超级块 */
   struct super_block* sb_buf = (struct super_block*)sys_malloc(SECTOR_SIZE);

   if (sb_buf == NULL) {
      PANIC("alloc memory failed!");
   }
   printk("searching filesystem......\n");
   while (channel_no < channel_cnt) {
      dev_no = 0;
      while(dev_no < 2) {
	 if (dev_no == 0) {   // 跨过裸盘hd60M.img
	    dev_no++;
	    continue;
	 }
	 struct disk* hd = &channels[channel_no].devices[dev_no];
	 struct partition* part = hd->prim_parts;
	 while(part_idx < 12) {   // 4个主分区+8个逻辑
	    if (part_idx == 4) {  // 开始处理逻辑分区
	       part = hd->logic_parts;
	    }
	 
	 /* channels数组是全局变量,默认值为0,disk属于其嵌套结构,
	  * partition又为disk的嵌套结构,因此partition中的成员默认也为0.
	  * 若partition未初始化,则partition中的成员仍为0. 
	  * 下面处理存在的分区. */
	    if (part->sec_cnt != 0) {  // 如果分区存在
	       memset(sb_buf, 0, SECTOR_SIZE);

	       /* 读出分区的超级块,根据魔数是否正确来判断是否存在文件系统 */
	       ide_read(hd, part->start_lba + 1, sb_buf, 1);   

	       /* 只支持自己的文件系统.若磁盘上已经有文件系统就不再格式化了 */
	       if (sb_buf->magic == 0x19590318) {
		  printk("%s has filesystem\n", part->name);
	       } else {			  // 其它文件系统不支持,一律按无文件系统处理
		  printk("formatting %s`s partition %s......\n", hd->name, part->name);
		  partition_format(part);
	       }
	    }
	    part_idx++;
	    part++;	// 下一分区
	 }
	 dev_no++;	// 下一磁盘
      }
      channel_no++;	// 下一通道
   }
   sys_free(sb_buf);

   /* 确定默认操作的分区 */
   char default_part[8] = "sdb1";
   /* 挂载分区 */
   list_traversal(&partition_list, mount_partition, (int)default_part);

   /* 将当前分区的根目录打开 */
   open_root_dir(cur_part);

   /* 初始化文件表 */
   uint32_t fd_idx = 0;
   while (fd_idx < MAX_FILE_OPEN) {
      file_table[fd_idx++].fd_inode = NULL;
   }
}