亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? kernel.c

?? 很好的TCP_IP協議源代碼分析,很適用很好
?? C
字號:
/* Non pre-empting synchronization kernel, machine-independent portion
 */
#if	defined(PROCLOG) || defined(PROCTRACE)
#include <stdio.h>
#endif
#include <dos.h>
#include <setjmp.h>
#include "global.h"
#include "mbuf.h"
#include "proc.h"
#include "timer.h"
#include "socket.h"
#include "daemon.h"
#include "hardware.h"
#include "display.h"

#ifdef	PROCLOG
FILE *proclog;
FILE *proctrace;
#endif
int Stkchk = 0;
struct proc *Curproc;		/* Currently running process */
struct proc *Rdytab;		/* Processes ready to run (not including curproc) */
struct proc *Waittab[PHASH];	/* Waiting process list */
struct proc *Susptab;		/* Suspended processes */
static struct mbuf *Killq;
struct ksig Ksig;
int Kdebug;		/* Control display of current task on screen */

static void addproc(struct proc *entry);
static void delproc(struct proc *entry);

static void ksig(void *event,int n);
static int procsigs(void);

/* Create a process descriptor for the main function. Must be actually
 * called from the main function, and must be called before any other
 * tasking functions are called!
 *
 * Note that standard I/O is NOT set up here.
 */
struct proc *
mainproc(char *name)
{
	register struct proc *pp;

	/* Create process descriptor */
	pp = (struct proc *)callocw(1,sizeof(struct proc));

	/* Create name */
	pp->name = strdup(name);
#ifndef	AMIGA
	pp->stksize = 0;
#else
	init_psetup(pp);
#endif
	/* Make current */
	pp->flags.suspend = pp->flags.waiting = 0;
	Curproc = pp;

#ifdef	PROCLOG
	proclog = fopen("proclog",APPEND_TEXT);
	proctrace = fopen("proctrace",APPEND_TEXT);
#endif
	return pp;
}
/* Create a new, ready process and return pointer to descriptor.
 * The general registers are not initialized, but optional args are pushed
 * on the stack so they can be seen by a C function.
 */
struct proc *
newproc(
char *name,		/* Arbitrary user-assigned name string */
unsigned int stksize,	/* Stack size in words to allocate */
void (*pc)(),		/* Initial execution address */
int iarg,		/* Integer argument (argc) */
void *parg1,		/* Generic pointer argument #1 (argv) */
void *parg2,		/* Generic pointer argument #2 (session ptr) */
int freeargs		/* If set, free arg list on parg1 at termination */
){
	register struct proc *pp;
	int i;

	if(Stkchk)
		chkstk();

	/* Create process descriptor */
	pp = (struct proc *)callocw(1,sizeof(struct proc));

	/* Create name */
	pp->name = strdup(name);

	/* Allocate stack */
#ifdef	AMIGA
	stksize += SIGQSIZE0;	/* DOS overhead */
#endif
	pp->stksize = stksize;
	if((pp->stack = (uint16 *)malloc(sizeof(uint16)*stksize)) == NULL){
		free(pp->name);
		free(pp);
		return NULL;
	}
	/* Initialize stack for high-water check */
	for(i=0;i<stksize;i++)
		pp->stack[i] = STACKPAT;

	/* Do machine-dependent initialization of stack */
	psetup(pp,iarg,parg1,parg2,pc);

	pp->flags.freeargs = freeargs;
	pp->iarg = iarg;
	pp->parg1 = parg1;
	pp->parg2 = parg2;
	
	/* Inherit creator's input and output sockets */
	pp->input = fdup(stdin);
	pp->output = fdup(stdout);

	/* Add to ready process table */
	pp->flags.suspend = pp->flags.waiting = 0;
	addproc(pp);
	return pp;
}

/* Free resources allocated to specified process. If a process wants to kill
 * itself, the reaper is called to do the dirty work. This avoids some
 * messy situations that would otherwise occur, like freeing your own stack.
 */
void
killproc(struct proc *pp)
{
	char **argv;

	if(pp == NULL)
		return;
	/* Don't check the stack here! Will cause infinite recursion if
	 * called from a stack error
	 */
	if(pp == Curproc)
		killself();	/* Doesn't return */
	fclose(pp->input);
	fclose(pp->output);

	/* Stop alarm clock in case it's running */
	stop_timer(&pp->alarm);

	/* Alert everyone waiting for this proc to die */
	ksignal(pp,0);

	/* Remove from appropriate table */
	delproc(pp);

#ifdef	PROCLOG
	fprintf(proclog,"id %p name %s stack %u/%u\n",pp,
		pp->name,stkutil(pp),pp->stksize);
	fclose(proclog);
	proclog = fopen("proclog",APPEND_TEXT);
	proctrace = fopen("proctrace",APPEND_TEXT);
#endif
	/* Free allocated memory resources */
	if(pp->flags.freeargs){
		argv = pp->parg1;
		while(pp->iarg-- != 0)
			free(*argv++);
		free(pp->parg1);
	}
	free(pp->name);
	free(pp->stack);
	free(pp);
}
/* Terminate current process by sending a request to the killer process.
 * Automatically called when a process function returns. Does not return.
 */
void
killself(void)
{
	struct mbuf *bp = NULL;

	pushdown(&bp,&Curproc,sizeof(Curproc));
	enqueue(&Killq,&bp);

	/* "Wait for me; I will be merciful and quick." */
	for(;;)
		kwait(NULL);
}
/* Process used by processes that want to kill themselves */
void
killer(int i,void *v1,void *v2)
{
	struct proc *pp;
	struct mbuf *bp;

	for(;;){
		while(Killq == NULL)
			kwait(&Killq);
		bp = dequeue(&Killq);
		pullup(&bp,&pp,sizeof(pp));
		free_p(&bp);
		if(pp != Curproc)	/* We're immortal */
			killproc(pp);
	}						
}

/* Inhibit a process from running */
void
suspend(struct proc *pp)
{
	if(pp == NULL)
		return;
	if(pp != Curproc)
		delproc(pp);	/* Running process isn't on any list */
	pp->flags.suspend = 1;
	if(pp != Curproc)
		addproc(pp);	/* kwait will do it for us */
	else
		kwait(NULL);
}
/* Restart suspended process */
void
resume(struct proc *pp)
{
	if(pp == NULL)
		return;
	delproc(pp);	/* Can't be Curproc! */
	pp->flags.suspend = 0;
	addproc(pp);
}

/* Wakeup waiting process, regardless of event it's waiting for. The process
 * will see a return value of "val" from its kwait() call. Must not be
 * called from an interrupt handler.
 */
void
alert(struct proc *pp,int val)
{
	if(pp == NULL)
		return;
#ifdef	notdef
	if(pp->flags.waiting == 0)
		return;
#endif
#ifdef	PROCTRACE
	logmsg(-1,"alert(%p,%u) [%s]",pp,val,pp->name);
#endif
	if(pp != Curproc)
		delproc(pp);
	pp->flags.waiting = 0;
	pp->retval = val;
	pp->event = NULL;
	if(pp != Curproc)
		addproc(pp);
}

/* Post a wait on a specified event and give up the CPU until it happens. The
 * null event is special: it means "I don't want to block on an event, but let
 * somebody else run for a while". It can also mean that the present process
 * is terminating; in this case the wait never returns.
 *
 * Pwait() returns 0 if the event was signaled; otherwise it returns the
 * arg in an alert() call. Pwait must not be called from interrupt level.
 *
 * Before waiting and after giving up the CPU, kwait() processes the signal
 * queue containing events signaled when interrupts were off. This means
 * the process queues are no longer modified by interrupt handlers,
 * so it is no longer necessary to run with interrupts disabled here. This
 * greatly improves interrupt latencies.
 */
int
kwait(void *event)
{
	register struct proc *oldproc;
	int tmp;
	int i_state;

	if(!istate()){
		stktrace();
	}
	Ksig.kwaits++;
	if(intcontext() == 1){
		/* Pwait must not be called from interrupt context */
		Ksig.kwaitints++;
		return 0;
	}
	/* Enable interrupts, after saving the current state.
	 * This minimizes interrupt latency since we may have a lot
	 * of work to do. This seems safe, since care has been taken
	 * here to ensure that signals from interrupt level are not lost, e.g.,
	 * if we're waiting on an event, we post it before we scan the
	 * signal queue.
	 */
	i_state = istate();
	enable();
	if(Stkchk)
		chkstk();
	
	if(event != NULL){
		/* Post a wait for the specified event */
		Curproc->event = event;
		Curproc->flags.waiting = 1;
		addproc(Curproc);	/* Put us on the wait list */
	}
	/* If the signal queue contains a signal for the event that we're
	 * waiting for, this will wake us back up
	 */
	procsigs();
	if(event == NULL){
		/* We remain runnable */
		if(Rdytab == NULL){
			/* Nothing else is ready, so just return */
			Ksig.kwaitnops++;
			restore(i_state);
			return 0;
		}
		addproc(Curproc); /* Put us on the end of the ready list */
	}
	/* Look for a ready process and run it. If there are none,
	 * loop or halt until an interrupt makes something ready.
	 */
	while(Rdytab == NULL){
		/* Give system back to upper-level multitasker, if any.
		 * Note that this function enables interrupts internally
		 * to prevent deadlock, but it restores our state
		 * before returning.
		 */
		if(Kdebug)
			debug("              ");

		giveup();
		/* Process signals that occurred during the giveup() */
		procsigs();
	}
	/* Remove first entry from ready list */
	oldproc = Curproc;
	Curproc = Rdytab;
	delproc(Curproc);

	if(Kdebug)
		debug(Curproc->name);

	/* Now do the context switch.
	 * This technique was inspired by Rob, PE1CHL, and is a bit tricky.
	 *
	 * First save the current process's state. Then if
	 * this is still the old process, load the new environment. Since the
	 * new task will "think" it's returning from the setjmp() with a return
	 * value of 1, the comparison with 0 will bypass the longjmp(), which
	 * would otherwise cause an infinite loop.
	 */
#ifdef	PROCTRACE
	if(strcmp(oldproc->name,Curproc->name) != 0){
		logmsg(-1,"-> %s(%d)",Curproc->name,Curproc->flags.istate);
	}
#endif
	/* Save old state */
	oldproc->flags.istate = 0;
	if(i_state)
		oldproc->flags.istate = 1;
	if(setjmp(oldproc->env) == 0){
		/* We're still running in the old task; load new task context.
		 * The interrupt state is restored here in case longjmp
		 * doesn't do it (e.g., systems other than Turbo-C).
		 */
		restore(Curproc->flags.istate);
		longjmp(Curproc->env,1);
	}
	/* At this point, we're running in the newly dispatched task */
	tmp = Curproc->retval;
	Curproc->retval = 0;

	/* Also restore the true interrupt state here, in case the longjmp
	 * DOES restore the interrupt state saved at the time of the setjmp().
	 * This is the case with Turbo-C's setjmp/longjmp.
	 */
	restore(Curproc->flags.istate);

	/* If an exception signal was sent and we're prepared, take it */
	if((Curproc->flags.sset) && tmp == Curproc->signo)
		longjmp(Curproc->sig,1);

	/* Otherwise return normally to the new task */
	return tmp;
}

void
ksignal(void *event,int n)
{
	static void *lastevent;

	if(istate()){
		/* Interrupts are on, just call ksig directly after
		 * processing the previously queued signals
		 */
		procsigs();
		ksig(event,n);
		return;
	}
	/* Interrupts are off, so quickly queue event */
	Ksig.ksigsqueued++;

 	/* Ignore duplicate signals to protect against a mad device driver
	 * overflowing the signal queue
	 */
	if(event == lastevent && Ksig.nentries != 0){
		Ksig.duksigs++;
		return; 
	}
	if(Ksig.nentries == SIGQSIZE){
		/* It's hard to handle this gracefully */
		Ksig.lostsigs++;
		return;
	}
	lastevent = Ksig.wp->event = event;
	Ksig.wp->n = n;
	if(++Ksig.wp >= &Ksig.entry[SIGQSIZE])
		Ksig.wp = Ksig.entry;
	Ksig.nentries++;
}
static int
procsigs(void)
{
	int cnt = 0;
	int tmp;
	int i_state;

	for(;;){
		/* Atomic read and decrement of entry count */
		i_state = dirps();
		tmp = Ksig.nentries;
		if(tmp != 0)
			Ksig.nentries--;
		restore(i_state);
		if(tmp == 0)
			break;
		ksig(Ksig.rp->event,Ksig.rp->n);
		if(++Ksig.rp >= &Ksig.entry[SIGQSIZE])
			Ksig.rp = Ksig.entry;
		cnt++;
	}
	if(cnt > Ksig.maxentries)
		Ksig.maxentries = cnt;	/* Record high water mark */
	return cnt;
}
/* Make ready the first 'n' processes waiting for a given event. The ready
 * processes will see a return value of 0 from kwait().  Note that they don't
 * actually get control until we explicitly give up the CPU ourselves through
 * a kwait(). ksig is now called from pwait, which is never called at
 * interrupt time, so it is no longer necessary to protect the proc queues
 * against interrupts. This also helps interrupt latencies considerably.
 */
static void
ksig(
void *event,	/* Event to signal */
int n		/* Max number of processes to wake up */
){
	register struct proc *pp;
	struct proc *pnext;
	unsigned int hashval;
	int cnt = 0;

	Ksig.ksigs++;
	if(Stkchk)
		chkstk();

	if(event == NULL){
		Ksig.ksignops++;
		return;		/* Null events are invalid */
	}
	/* n == 0 means "signal everybody waiting for this event" */
	if(n == 0)
		n = 65535;

	hashval = phash(event);
	for(pp = Waittab[hashval];n != 0 && pp != NULL;pp = pnext){
		pnext = pp->next;
		if(pp->event == event){
#ifdef	PROCTRACE
				logmsg(-1,"ksignal(%p,%u) wake %p [%s]",event,n,
				 pp,pp->name);
#endif
			delproc(pp);
			pp->flags.waiting = 0;
			pp->retval = 0;
			pp->event = NULL;
			addproc(pp);
			n--;
			cnt++;
		}
	}
	for(pp = Susptab;n != 0 && pp != NULL;pp = pnext){
		pnext = pp->next;
		if(pp->event == event){
#ifdef	PROCTRACE
				logmsg(-1,"ksignal(%p,%u) wake %p [%s]",event,n,
				 pp,pp->name);
#endif /* PROCTRACE */
			delproc(pp);
			pp->flags.waiting = 0;
			pp->event = 0;
			pp->retval = 0;
			addproc(pp);
			n--;
			cnt++;
		}
	}
	if(cnt == 0)
		Ksig.ksignops++;
	else
		Ksig.ksigwakes += cnt;
}

/* Rename a process */
void
chname(struct proc *pp,char *newname)
{
	free(pp->name);
	pp->name = strdup(newname);
}
/* Remove a process entry from the appropriate table */
static void
delproc(struct proc *entry)	/* Pointer to entry */
{
	if(entry == NULL)
		return;

	if(entry->next != NULL)
		entry->next->prev = entry->prev;
	if(entry->prev != NULL){
		entry->prev->next = entry->next;
	} else {
		if(entry->flags.suspend){
			Susptab = entry->next;
		} else if(entry->flags.waiting){
			Waittab[phash(entry->event)] = entry->next;
		} else {	/* Ready */
			Rdytab = entry->next;
		}
	}
}
/* Append proc entry to end of appropriate list */
static void
addproc(struct proc *entry)	/* Pointer to entry */
{
	register struct proc *pp;
	struct proc **head;

	if(entry == NULL)
		return;

	if(entry->flags.suspend){
		head = &Susptab;
	} else if(entry->flags.waiting){
		head = &Waittab[phash(entry->event)];
	} else {	/* Ready */
		head = &Rdytab;
	}
	entry->next = NULL;
	if(*head == NULL){
		/* Empty list, stick at beginning */
		entry->prev = NULL;
		*head = entry;
	} else {
		/* Find last entry on list */
		for(pp = *head;pp->next != NULL;pp = pp->next)
			;
		pp->next = entry;
		entry->prev = pp;
	}
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日本二三区不卡| 亚洲一区二区在线观看视频| 亚洲蜜臀av乱码久久精品蜜桃| 日韩精品三区四区| 99久久99久久综合| 久久久亚洲精华液精华液精华液| 一区二区在线看| 成人一区二区在线观看| 欧美成人女星排行榜| 亚洲在线观看免费视频| 99久久亚洲一区二区三区青草| 久久人人97超碰com| 青青草国产精品97视觉盛宴| 日本高清免费不卡视频| 亚洲丝袜自拍清纯另类| 国产高清不卡二三区| 日韩女优电影在线观看| 日日噜噜夜夜狠狠视频欧美人 | 色婷婷av一区二区| 国产精品免费视频观看| 国产一区亚洲一区| 日韩欧美国产午夜精品| 另类欧美日韩国产在线| 欧美成人免费网站| 久久成人羞羞网站| 欧美电影免费观看高清完整版在线 | 欧美日韩一本到| 一级精品视频在线观看宜春院 | 久久先锋影音av鲁色资源 | 亚洲综合精品久久| 在线观看www91| 亚洲一二三四在线| 欧美色偷偷大香| 日本欧美肥老太交大片| 欧美一级生活片| 免费看黄色91| 国产夜色精品一区二区av| 国产 日韩 欧美大片| 欧美国产一区在线| 91免费视频大全| 亚洲国产人成综合网站| 欧美精品一级二级三级| 美女国产一区二区| 久久色视频免费观看| 丰满白嫩尤物一区二区| 亚洲色欲色欲www在线观看| 91美女蜜桃在线| 日日摸夜夜添夜夜添精品视频| 欧美一区二区三区日韩视频| 紧缚奴在线一区二区三区| 国产欧美精品区一区二区三区| 99久久婷婷国产精品综合| 亚洲va天堂va国产va久| 日韩美女一区二区三区四区| 国产91在线看| 亚洲成人免费在线观看| 精品福利二区三区| 成人av午夜电影| 日韩国产一二三区| 国产精品欧美一区二区三区| 在线观看免费亚洲| 黄一区二区三区| 亚洲精选免费视频| 精品卡一卡二卡三卡四在线| 99久久99久久精品免费观看| 蜜臀精品久久久久久蜜臀| 国产精品久久网站| 91麻豆精品国产91| 99re这里都是精品| 精品一区二区三区在线播放 | 色综合一区二区| 日韩av中文字幕一区二区三区| 国产免费久久精品| 8x8x8国产精品| 99久久久久免费精品国产 | 久久久久久久久蜜桃| 欧美私模裸体表演在线观看| 国产成人8x视频一区二区| 日精品一区二区三区| 亚洲人一二三区| 久久久久久99精品| 欧美日韩美少妇| 99久久99久久久精品齐齐| 国产美女精品人人做人人爽| 亚洲成av人影院| 亚洲乱码中文字幕| 国产精品女上位| 精品日韩99亚洲| 91精品婷婷国产综合久久性色 | 日韩美女天天操| 欧美女孩性生活视频| 91一区在线观看| 高清国产午夜精品久久久久久| 免费高清在线一区| 亚洲成在线观看| 亚洲伦理在线精品| 中文字幕一区在线| 欧美国产一区在线| 国产亚洲欧美一级| 久久久国产综合精品女国产盗摄| 欧美一区二区视频网站| 欧美日韩美少妇| 欧美日韩五月天| 欧美激情一区二区三区蜜桃视频| 日韩无一区二区| 欧美精品久久久久久久多人混战| 欧美在线视频日韩| 色综合亚洲欧洲| av资源网一区| 91亚洲精品乱码久久久久久蜜桃 | 乱一区二区av| 美女视频网站黄色亚洲| 欧美羞羞免费网站| 色欧美日韩亚洲| 在线欧美一区二区| 欧美美女喷水视频| 欧美一区二区三区系列电影| 欧美一级欧美三级| 欧美成人精品高清在线播放| 精品成人免费观看| 国产丝袜美腿一区二区三区| 国产女主播视频一区二区| 中文字幕在线免费不卡| 中文字幕在线观看一区| 亚洲伦理在线精品| 天堂资源在线中文精品| 日韩av在线播放中文字幕| 久久国产精品72免费观看| 国产在线麻豆精品观看| 福利电影一区二区| 一本一道久久a久久精品综合蜜臀| 91麻豆福利精品推荐| 欧美二区在线观看| 久久久亚洲午夜电影| 中文字幕一区在线观看视频| 亚洲成人综合在线| 国产制服丝袜一区| 一本色道久久综合精品竹菊| 91精品国产免费久久综合| 国产日韩欧美麻豆| 一区二区三区精品| 精品一区二区综合| 91香蕉视频污| 精品国产一区二区精华| 一区在线观看免费| 日韩电影在线一区二区三区| 国产盗摄视频一区二区三区| 色8久久精品久久久久久蜜| 欧美成人一区二区三区| 亚洲三级电影网站| 日韩激情视频在线观看| 成人免费精品视频| 欧美一区二区三区日韩| 亚洲视频一二三| 九九热在线视频观看这里只有精品| 成人app软件下载大全免费| 欧美伦理视频网站| 1区2区3区国产精品| 日本成人超碰在线观看| 成人黄色免费短视频| 欧美一级片免费看| 一区二区三区欧美视频| 国产主播一区二区| 欧美疯狂性受xxxxx喷水图片| 国产精品美女一区二区三区| 日韩高清电影一区| 91视频国产资源| 国产视频一区二区在线| 日本美女视频一区二区| 91丨九色丨蝌蚪富婆spa| 久久综合给合久久狠狠狠97色69| 亚洲在线视频一区| 99re成人精品视频| 久久九九全国免费| 韩国三级在线一区| 欧美精品自拍偷拍动漫精品| 一区二区三区资源| 大美女一区二区三区| 精品不卡在线视频| 日本欧美在线看| 日本一区二区成人| 另类成人小视频在线| 欧美日韩成人在线| 亚洲一级二级在线| 欧美伊人精品成人久久综合97| 亚洲视频一区在线观看| 成人午夜视频在线观看| 久久久久国产精品麻豆ai换脸 | 亚洲第一在线综合网站| 97精品国产露脸对白| 国产精品亲子乱子伦xxxx裸| 国产精品一区二区三区四区| 精品区一区二区| 狠狠色综合播放一区二区| 日韩午夜激情视频| 激情欧美一区二区| 久久精品视频一区二区三区| 国产成人欧美日韩在线电影| 久久精品一区八戒影视| 高清在线不卡av|