⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sched.c

📁 早期freebsd实现
💻 C
字号:
/* * Copyright (c) 1990 Jan-Simon Pendry * Copyright (c) 1990 Imperial College of Science, Technology & Medicine * Copyright (c) 1990, 1993 *	The Regents of the University of California.  All rights reserved. * * This code is derived from software contributed to Berkeley by * Jan-Simon Pendry at Imperial College, London. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *	This product includes software developed by the University of *	California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors *    may be used to endorse or promote products derived from this software *    without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * *	@(#)sched.c	8.1 (Berkeley) 6/6/93 * * $Id: sched.c,v 5.2.2.1 1992/02/09 15:09:02 jsp beta $ * *//* * Process scheduler */#include "am.h"#include <sys/signal.h>#include WAIT#include <setjmp.h>extern jmp_buf select_intr;extern int select_intr_valid;typedef struct pjob pjob;struct pjob {	qelem hdr;			/* Linked list */	int pid;			/* Process ID of job */	cb_fun cb_fun;			/* Callback function */	voidp cb_closure;		/* Closure for callback */	union wait w;			/* Status filled in by sigchld */	voidp wchan;			/* Wait channel */};extern qelem proc_list_head;qelem proc_list_head = { &proc_list_head, &proc_list_head };extern qelem proc_wait_list;qelem proc_wait_list = { &proc_wait_list, &proc_wait_list };int task_notify_todo;void ins_que(elem, pred)qelem *elem, *pred;{	qelem *p = pred->q_forw;	elem->q_back = pred;	elem->q_forw = p;	pred->q_forw = elem;	p->q_back = elem;}void rem_que(elem)qelem *elem;{	qelem *p = elem->q_forw;	qelem *p2 = elem->q_back;	p2->q_forw = p;	p->q_back = p2;}static pjob *sched_job(cf, ca)cb_fun cf;voidp ca;{	pjob *p = ALLOC(pjob);	p->cb_fun = cf;	p->cb_closure = ca;	/*	 * Now place on wait queue	 */	ins_que(&p->hdr, &proc_wait_list);	return p;}void run_task(tf, ta, cf, ca)task_fun tf;voidp ta;cb_fun cf;voidp ca;{	pjob *p = sched_job(cf, ca);	int mask;	p->wchan = (voidp) p;	mask = sigblock(sigmask(SIGCHLD));	if (p->pid = background()) {		sigsetmask(mask);		return;	}	exit((*tf)(ta));	/* firewall... */	abort();}/* * Schedule a task to be run when woken up */void sched_task(cf, ca, wchan)cb_fun cf;voidp ca;voidp wchan;{	/*	 * Allocate a new task	 */	pjob *p = sched_job(cf, ca);#ifdef DEBUG_SLEEP	dlog("SLEEP on %#x", wchan);#endif	p->wchan = wchan;	p->pid = 0;	bzero((voidp) &p->w, sizeof(p->w));}static void wakeupjob(p)pjob *p;{	rem_que(&p->hdr);	ins_que(&p->hdr, &proc_list_head);	task_notify_todo++;}void wakeup(wchan)voidp wchan;{	pjob *p, *p2;#ifdef DEBUG_SLEEP	int done = 0;#endif	if (!foreground)		return;#ifdef DEBUG_SLEEP	/*dlog("wakeup(%#x)", wchan);*/#endif	/*	 * Can't user ITER() here because	 * wakeupjob() juggles the list.	 */	for (p = FIRST(pjob, &proc_wait_list);			p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);			p = p2) {		if (p->wchan == wchan) {#ifdef DEBUG_SLEEP			done = 1;#endif			wakeupjob(p);		}	}#ifdef DEBUG_SLEEP	if (!done)		dlog("Nothing SLEEPing on %#x", wchan);#endif}void wakeup_task(rc, term, cl)int rc;int term;voidp cl;{	wakeup(cl);}/*ARGSUSED*/void sigchld(sig)int sig;{	union wait w;	int pid;#ifdef SYS5_SIGNALS	if ((pid = wait(&w)) > 0) {#else	while ((pid = wait3((int *) &w, WNOHANG, (struct rusage *) 0)) > 0) {#endif /* SYS5_SIGNALS */		pjob *p, *p2;		if (WIFSIGNALED(w))			plog(XLOG_ERROR, "Process %d exited with signal %d",				pid, w.w_termsig);#ifdef DEBUG		else			dlog("Process %d exited with status %d",				pid, w.w_retcode);#endif /* DEBUG */		for (p = FIRST(pjob, &proc_wait_list);				p2 = NEXT(pjob, p), p != HEAD(pjob, &proc_wait_list);				p = p2) {			if (p->pid == pid) {				p->w = w;				wakeupjob(p);				break;			}		}#ifdef DEBUG		if (p) ; else dlog("can't locate task block for pid %d", pid);#endif /* DEBUG */	}#ifdef SYS5_SIGNALS	signal(sig, sigchld);#endif /* SYS5_SIGNALS */	if (select_intr_valid)		longjmp(select_intr, sig);}/* * Run any pending tasks. * This must be called with SIGCHLD disabled */void do_task_notify(P_void){	/*	 * Keep taking the first item off the list and processing it.	 *	 * Done this way because the the callback can, quite reasonably,	 * queue a new task, so no local reference into the list can be	 * held here.	 */	while (FIRST(pjob, &proc_list_head) != HEAD(pjob, &proc_list_head)) {		pjob *p = FIRST(pjob, &proc_list_head);		rem_que(&p->hdr);		/*		 * This job has completed		 */		--task_notify_todo;		/*		 * Do callback if it exists		 */		if (p->cb_fun)			(*p->cb_fun)(p->w.w_retcode,				p->w.w_termsig, p->cb_closure);		free((voidp) p);	}}#ifdef HAS_SVR3_SIGNALS/* * 4.2 signal library based on svr3 (4.1+ bsd) interface * From Stephen C. Pope <scp@acl.lanl.gov). */static int current_mask = 0;int sigblock(mask)int mask;{    int sig;    int m;    int oldmask;    oldmask = current_mask;    for ( sig = 1, m = 1; sig <= MAXSIG; sig++, m <<= 1 ) {        if (mask & m)  {	    sighold(sig);            current_mask |= m;        }    }    return oldmask;}int sigsetmask(mask)int mask;{    int sig;    int m;    int oldmask;    oldmask = current_mask;    for ( sig = 1, m = 1; sig <= MAXSIG; sig++, m <<= 1 ) {        if (mask & m)  {            sighold(sig);            current_mask |= m;        }        else  {            sigrelse(sig);            current_mask &= ~m;        }    }    return oldmask;}#endif /* HAS_SVR3_SIGNALS */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -