Archive for September, 2014

进程状态&&父子信号分析

September 9th, 2014

接着http://www.lizhaozhong.info/archives/596写。

在操作系统原理里面,我们只学了进程有三个主要状态:阻塞态,就绪态,运行态。
在linux下,我们拓展出了 O,S,R,I,Z,T,B,D。我们可以使用top命令查看S位。

O:进程正在处理器运行,这个状态从来木见过.
S:休眠状态(sleeping)
R:等待运行(runable)R Running or runnable (on run queue) 进程处于运行或就绪状态
I:空闲状态(idle)
Z:僵尸状态(zombie)   
T:跟踪状态(Traced)
B:进程正在等待更多的内存页
D:不可中断的深度睡眠,一般由IO引起,同步IO在做读或写操作时,cpu不能做其它事情,只能等待,这时进程处于这种状态,如果程序采用异步IO,这种状态应该就很少见到了

» Read more: 进程状态&&父子信号分析

list 实际应用

September 3rd, 2014

一个head头包含两个不同的链表,每个链表会有交叉,在高级的场景下使用,例如多cgroup 与多css_set关系!

#include "list.h"
#define MAX_LEN 256

struct task_struct{
	list_head priority_list;
	list_head timer_list;
	int priority;
	int timeout;
	char name[MAX_LEN];
};

struct task_struct* init_task(int priority,int timeout,char *name,int str_len)
{
	struct task_struct *T = (struct task_struct * )malloc(sizeof(struct task_struct));
	T->priority = priority;
	T->timeout = timeout;
	strncpy(T->name,name,str_len);
	return T;

}

struct list_head* p_add_task(list_head *head,struct task_struct *task)
{
	struct list_head *pos;
	struct task_struct *p;
	if(list_empty(head))
	{
		list_add(&task->priority_list,head);
		return head;
	}
	list_for_each(pos,head)//big->little
	{
		p=list_entry(pos, struct task_struct, priority_list);
		if( p->priority  < task->priority)//insert node > current node
		{
			list_add(&task->priority_list,pos->prev);
			return head;
		}
	}
	list_add_tail(&task->priority_list,head);
	return head;
}
struct list_head* t_add_task(list_head *head,struct task_struct *task)
{
	struct list_head *pos;
	struct task_struct *p;
	if(list_empty(head))
	{
		list_add(&task->timer_list,head);
		return head;
	}
	list_for_each(pos,head)//little ->big
	{
		p=list_entry(pos, struct task_struct, timer_list);
		if( p->timeout  > task->timeout)//insert node > current node
		{
			list_add(&task->timer_list,pos->prev);
			return head;
		}
	}
	list_add_tail(&task->timer_list,head);
	return head;
}

struct task_struct* p_del_task(list_head *head,struct task_struct *task)
{
	list_del(&task->priority_list);
	return task;
}
struct task_struct* t_del_task(list_head *head,struct task_struct *task)
{
	list_del(&task->timer_list);
	return task;
}

int Print_priority_list(struct task_struct *task)
{
	struct list_head *pos;
	struct task_struct *p;
	printf("P\tT\tN\n");
	list_for_each(pos,&task->priority_list)
	{
		p=list_entry(pos, struct task_struct, priority_list);
		printf("%d\t%d\t%s\n", p->priority,p->timeout,p->name);
	}
}

int Print_timer_list(struct task_struct *task)
{
	struct list_head *pos;
	struct task_struct *p;
	printf("P\tT\tN\n");
	list_for_each(pos,&task->timer_list)
	{
		p=list_entry(pos, struct task_struct, timer_list);
		printf("%d\t%d\t%s\n", p->priority,p->timeout,p->name);
	}
}

int main()
{
	struct task_struct head={
		.priority_list = LIST_HEAD_INIT(head.priority_list),
		.timer_list = LIST_HEAD_INIT(head.timer_list),
 		.priority = -1,
		.timeout = -1,
		.name = NULL
	};

	char temp1[MAX_LEN] = "T1";
	char temp2[MAX_LEN] = "T2";
	char temp3[MAX_LEN] = "T3";
	struct task_struct *T1,*T2,*T3;
	T1 = init_task(1,10,temp1,strlen(temp1));
	T2 = init_task(3,5,temp2,strlen(temp2));
	T3 = init_task(2,2,temp3,strlen(temp3));
	
	p_add_task(&head.priority_list,T2);
	p_add_task(&head.priority_list,T3);
	p_add_task(&head.priority_list,T1);

	t_add_task(&head.timer_list,T3);
	t_add_task(&head.timer_list,T2);	
	t_add_task(&head.timer_list,T1);
	


	Print_priority_list(&head);
	printf("\n");
	Print_timer_list(&head);

	p_del_task(&head.priority_list,T2);
	p_del_task(&head.priority_list,T3);
	p_del_task(&head.priority_list,T1);

	t_del_task(&head.timer_list,T3);
	t_del_task(&head.timer_list,T2);
	t_del_task(&head.timer_list,T1);
	return 0;
}

http://www.lizhaozhong.info/archives/951

list.h解析与应用

September 3rd, 2014

双链表的应用在内核中随处可见,list.h头文件集中定义了双链表(struct list_head结构体)的相关操作。

关于list.h的分析,网上资料很多,这里只是记录我在分析list.h中遇到的问题。

struct list_head结构体:
struct list_head
{
struct list_head *next;
struct list_head *prev;
};

这个结构经常作为成员与其他数据类型一起组成一个新的结构体(后文若无特别提示,“新结构体”均指类似下面举例的嵌套型结构体),比如: » Read more: list.h解析与应用

OS的分页分段(笔记)

September 2nd, 2014

我们从80386处理器入手。首先,到了80386时代,CPU有了四种运行模式,即实模式、保护模式、虚拟8086模式和SMM模式。

实模式其大致包括实模式1MB的线性地址空间、内存寻址方法、寄存器、端口读写以及中断处理方法等内容。到了80386时代,引进了一种沿用至今的CPU运行机制——保护模式(Protected Mode)。保护模式有一些新的特色,用来增强系统稳定度,比如内存保护,分页系统,以及硬件支持的虚拟内存等。

对CPU来讲,系统中的所有储存器中的储存单元都处于一个统一的逻辑储存器中,它的容量受CPU寻址能力的限制。

这个逻辑储存器就是我们所说的线性地址空间。8086有20位地址线,拥有1MB的线性地址空间。而80386有32位地址线,拥有4GB的线性地
址空间。但是80386依旧保留了8086采用的地址分段的方式,只是增加了一个折中的方案,即只分一个段,段基址0×00000000,段长0xFFFFFFFF(4GB),这样的话整个线性空间可以看作就一个段,这就是所谓的平坦模型(Flat Mode)» Read more: OS的分页分段(笔记)