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

📄 prcmgr.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel / Standard Extension * *    Copyright (C) 2006 by Ken Sakamura. All rights reserved. *    T-Kernel / Standard Extension is distributed  *      under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * *    Version:   1.00.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* *	prcmgr.c (proc) * *	Process/task manager */#include "prcmgr.h"#include <longlong.h>#include <sys/imalloc.h>#include <sys/commarea.h>#include <tm/tmonitor.h>#include <sys/syslog.h>#include <extension/sys/tkse_ssid.h>#include <extension/sys/svc/ifproctask.h>#include <sys/memdef.h>#include <sys/bdm.h>#define TSD_GSS_VAL_1000	1000#define TSD_GPP_VAL_M1		(-1)#define TSD_TPI_MSK_0XFFFF0000	0xffff0000U#define TSD_TWF_VAL_0X00000001	0x00000001U#define TSD_TCB_VAL_2		2#define TSD_KTK_VAL_M1		(-1)#define TSD_CSR_VAL_2		2#define TSD_PTM_MST_8		8#define TSD_PTM_SSS_32768	32768#define TSD_NPI_MSK_0X7FFF	0x7fffU#define TSD_TSM_VAL_M1		(-1)#define MIN_ABSGRP_PRI		0#define MAX_ABSGRP_PRI		127#define MIN_RRGRP1_PRI		(MAX_ABSGRP_PRI + 1)#define MAX_RRGRP1_PRI		191#define MIN_RRGRP2_PRI		(MAX_RRGRP1_PRI + 1)#define MAX_RRGRP2_PRI		255#define PRI_ADJVAL		8				/* Priority adjustment value (TK <> TK/SE) */#define MAX_ABSGRP_TSKPRI	(MAX_ABSGRP_PRI + PRI_ADJVAL)	/* Absolute priority group(task priorty) */#define RRGRP1_TSKPRI		138				/* Round robin group 1(task priorty) */#define RRGRP2_TSKPRI		139				/* Round robin group 2(task priorty) */#define ABSGRP_STIME		10#define TSD_KSP_RTN_128		128#define TSD_KTK_TID_M1		(-1)#define TSD_CPS_VAL_M1		(-1)#define TSD_CPS_MSK_2		2#define TSD_KPS_VAL_50		50#define TSD_KPS_TDT_10		10#define TSD_KPS_VAL_40		40#define TSD_KPS_TDT_50		50Inline PINFO* SearchPinfo( ID pid );Inline W CLAMP(W val, W minv, W maxv);LOCAL ID NewProcID( void );LOCAL ER _GetPidToPinfo(W pid, PINFO **ppi);LOCAL PINFO* _GetPinfo(ID taskid);LOCAL UW _GetLSID(PINFO *pinfo);LOCAL VP _GetUATB(UW lsid);LOCAL void sendEmg( PINFO *pi );LOCAL WER chgEmgEntry( PINFO *pi, W pid, W t_mask );LOCAL WER _tkse_req_emg( ID pid, W t_mask );LOCAL void CallStartUp(PINFO *pi);LOCAL void CallCleanUp(PINFO *pi);LOCAL PRI SE_K__Pri(W pri, W *slt);LOCAL W K_SE_Pri(PRI pri, W slt);LOCAL ER CheckPri(W old_pri, W new_pri);LOCAL ER RefTask(ID tid, T_RTSK *rtsk);LOCAL W GetPri(ID tskid);LOCAL ER ChangePri(ID tid, W pri);LOCAL UW GetSysSec( void );LOCAL void FinishProc(PINFO *pi);LOCAL void ExitTask(PINFO *pi, ID tskid);LOCAL void KillTasks(PINFO *pi, ID mytid, W exit_kind, W exit_code);LOCAL void TermChild(PINFO *parpi, ID mytid);LOCAL ER CreateTask(PINFO *pi, FP entry, W pri, VP caller_gp);LOCAL WER CreateProcess(POBJ_HDR* pohdr, W pri, MESSAGE *msg, UW mode);LOCAL WER _tkse_cre_prc2(LINK* lnk, PRI pri, MESSAGE *msg);LOCAL WER _tkse_cre_sysprc(LINK* lnk, PRI pri, MESSAGE *msg);LOCAL WER _tkse_cre_prc(T_CPRC *pk_cprc, MESSAGE *msg);LOCAL void _tkse_ext_prc(W exit_code);LOCAL ER _tkse_ter_prc(ID pid, W abort_code, W opt);LOCAL WER chg_pri_task( W tid, W new_pri, W opt );LOCAL WER chg_pri_proc( W pid, W new_pri, W opt );LOCAL WER _tkse_chg_pri(ID id, PRI new_pri, W opt);LOCAL WER _tkse_prc_sts(ID pid, P_STATE *buff, TC *path);LOCAL ER _tkse_get_inf(ID pid, P_INFO *buff);LOCAL WER _tkse_cre_dbg(LINK *lnk, ID pri, MESSAGE *msg);LOCAL WER _tkse_set_dbg(ID pid, W mode);LOCAL WER pi_link( PINFO *pi, W item, LINK *buf, W len );LOCAL WER pi_cinf( PINFO *pi, W item, P_CREINF *buf, W len );LOCAL WER pi_task( PINFO *pi, W item, VP buf, W len );LOCAL WER _tkse_prc_inf( ID pid, W item, VP buf, W len );LOCAL WER _tkse_crs_tsk(FP entry, PRI pri, W arg, VP caller_gp);LOCAL WER _tkse_cre_tsk(FP entry, PRI pri, VP caller_gp);LOCAL WER _tkse_sta_tsk(ID id, W arg);LOCAL void _tkse_ext_tsk(void);LOCAL ER _tkse_ter_tsk(ID tid);LOCAL ER _tkse_dly_tsk(RELTIM dlytim);LOCAL ER _tkse_slp_tsk(TMO tmout);LOCAL ER _tkse_wup_tsk(ID tid);LOCAL WER _tkse_can_wup(ID tid);LOCAL WER _tkse_get_tid(void);LOCAL ER _tkse_wai_fflock( void );LOCAL ER _tkse_wup_fflock( ID tid );LOCAL WER _tkse_lod_mod2( LINK *lnk, P_DYNLDINF *info );LOCAL WER _tkse_lod_mod( T_LMOD *pk_mod, P_DYNLDINF *info );LOCAL ER _tkse_unl_mod( ID loadid );LOCAL WER ProcSVCentry(VP para, W fn, VP caller_gp);LOCAL void ProcStartUp( ID resid, W pid );LOCAL void ProcCleanUp( ID resid, W pid );LOCAL void ProcBreak(ID taskid);LOCAL void KillProcess( UW sysproc );/* Message management internal IF */IMPORT	ER	_tkse_snd_msg(ID pid, MESSAGE *msg, W opt, W msgflg);IMPORT	W	MAX_MSGSZ;		/* Maximum size of individual message	*/LOCAL	W	MaxProc;		/* Maximum number of processes		*/EXPORT	W	MAX_SUBTASKS = TSD_PTM_MST_8;	/* Maximum number of subtasks		*/LOCAL	W	SYS_STKSZ = TSD_PTM_SSS_32768;	/* System stack size	*/EXPORT	PINFO	*TopPI;			/* Start of PINFO[]		*/LOCAL	QUEUE	FreePI;			/* Empty PINFO queue		*/EXPORT	QUEUE	UsedPI;			/* PINFO queue in use		*/EXPORT	W	PINFO_sz;		/* PINFO size		*/LOCAL	ID	LastProcID;		/* Last process ID		*/#define	PRC_DMY_PRI	(140)		/* Priority at the time of process generation	*//* * Termination type (exit_kind) */#define	EXIT_ABORT	(MS_ABORT)#define	EXIT_NORM	(MS_EXIT)#define	EXIT_TERM	(MS_TERM)#define	EXIT_TERM_TASK	(0x00)#define	EXIT_TERM_CHILD	(0x10)#define	EXIT_FORCE	(0x11)/* * PINFO exclusive access lock */LOCAL	FastLock	_PinfoLock;/* * Exclusive control lock for process management *	(*) Do not lock ProcMgrLock within PINFO lock. *	   When it is necessary to lock ProcMgrLock and PINFO at the same time, *	   lock ProcMgrLock and then PINFO. */EXPORT	FastLock	ProcMgrLock;/*======================================================================	Process-related utility======================================================================*//*	Search for PINFO based on process ID*/Inline	PINFO*	SearchPinfo( ID pid ){	PINFO	*pi;	pi = (PINFO*)QueSearch(&UsedPI, &UsedPI, pid, (W)offsetof(PINFO, procid));	return ( pi == (PINFO*)&UsedPI )? NULL: pi;}/*	Allocate new process ID	Due to limitations on wsnd_evt(), a process ID must be 0x7fff or smaller.*/LOCAL	ID	NewProcID( void ){	ID	pid = LastProcID;	do {		pid = (ID)((UW)(pid + 1) & TSD_NPI_MSK_0X7FFF);	} while (( SearchPinfo(pid) != NULL )||( pid == 0 ));	LastProcID = pid;	return pid;}/*	Fetch process management information based on process ID (without locks).*/LOCAL	ER	_GetPidToPinfo(W pid, PINFO **ppi){	PINFO	*pi;	ER	err;	if ( pid < TSD_GPP_VAL_M1 ) {		return E_ID;	}	if ( pid > 0 ) {		pi = SearchPinfo(pid);		if ( pi == NULL ) {			return E_NOEXS;		}	} else {		err = GetMyPinfo(&pi);		if ( err < E_OK ) {			return err;		}		if ( pid == TSD_GPP_VAL_M1 ) {			pi = pi->parent; /* Parent */			if ( pi == NULL ) {				return E_NOEXS;			}		}	}	*ppi = pi;	return E_OK;}/*	Fetch process management information based on task ID (without locks).*/LOCAL	PINFO*	_GetPinfo(ID taskid){	ID		resid;	PRCMINFO	*info;	ER		err;	resid = tk_get_rid(taskid);	if ( resid == __CommArea->SysResID ) {		T_RTSK	ref;		tk_ref_tsk(taskid, &ref);		if ( ref.exinf != PRCTSK_EXINF ) {			return NULL; /* Non-process */		}	}	err = tk_get_res(resid, PM_SVC, (VP*)&info);	if ( err < E_OK ) {		return NULL;	}	return info->pinfo;}/*	Fetch process space ID (LSID)*/LOCAL	UW	_GetLSID(PINFO *pinfo){	return GetLSID_pinfo(pinfo);}/*	Fetch unique logical space table*/LOCAL	VP	_GetUATB(UW lsid){	return GetUATB_lsid(lsid);}/*======================================================================	Process termination notification======================================================================*/#define	N_EMG	5typedef struct emglst	EMGLST;struct emglst {	EMGLST	*next;		/* Link to next list */	struct emgent {		W	pid;	/* Destination process ID of termination notification */		W	t_mask;	/* Type of termination to be notified */	} ent[N_EMG];};/*	Send process termination notification and delete the list.*/LOCAL void sendEmg( PINFO *pi ){	EXITMSG	msg;	EMGLST	*p, *q;	W	i, mask;	switch ( pi->exitkind ) {	  case EXIT_NORM:		msg.kind = MS_EXIT;		break;	  case EXIT_TERM:	  case EXIT_TERM_CHILD:		msg.kind = MS_TERM;		break;	  default:		msg.kind = MS_ABORT;		break;	}	msg.type = MS_SYS2;	msg.size = (W)(sizeof(EXITMSG) - offsetof(EXITMSG, kind));	msg.pid  = pi->procid;	msg.code = pi->exitcode;	mask = (W)MSGMASK(msg.kind);	p = pi->emg_lst;	while ( p != NULL ) {		for ( i = 0; i < N_EMG; ++i ) {			if (( p->ent[i].pid == 0 )			  ||( (p->ent[i].t_mask & mask) == 0 )) {				continue;			}			_tkse_snd_msg(p->ent[i].pid, (MESSAGE*)&msg, NOWAIT, TSD_TSM_VAL_M1);		}		q = p;		p = p->next;		Vfree(q);	}	pi->emg_lst = NULL;}/*	Refer to/update a process termination notification list.*/LOCAL WER chgEmgEntry( PINFO *pi, W pid, W t_mask ){	W	old_mask = 0;	EMGLST	*p, *free_p = NULL;	W	i, free_i = 0;	for ( p = pi->emg_lst; p != NULL; p = p->next ) {		for ( i = 0; i < N_EMG; ++i ) {			if ( p->ent[i].pid == pid ) {				old_mask = p->ent[i].t_mask;				if ( t_mask > 0 ) {					p->ent[i].t_mask = t_mask; /* Change */				} else if ( t_mask == 0 ) {					p->ent[i].pid = 0;         /* Delete */				}				return old_mask;			}			if ( p->ent[i].pid == 0 ) {				/* Empty entry */				free_p = p;				free_i = i;			}		}	}	if ( t_mask <= 0 ) {		return old_mask;	}	if ( free_p == NULL ) {		/* Add new EMGLST */		p = Vcalloc(1, sizeof(EMGLST));		if ( p == NULL ) {			return E_NOMEM;		}		p->next = pi->emg_lst;		pi->emg_lst = p;		free_p = p;		free_i = 0;	}	/* Add */	free_p->ent[free_i].pid = pid;	free_p->ent[free_i].t_mask = t_mask;	return old_mask;}/*	Set/refer to process termination notification*/LOCAL WER _tkse_req_emg( ID pid, W t_mask ){	PINFO	*mypi, *pi;	W	old_mask;	ER	err;	/* Parameter check */	if (( t_mask >= 0 )&&( ((UW)t_mask & ~(UW)(MM_ABORT|MM_EXIT|MM_TERM)) != 0 )) {		err = E_PAR;		goto err_ret1;	}	Lock(&ProcMgrLock);	err = GetMyPinfo(&mypi);	if ( err < E_OK ) {		goto err_ret2;	}	err = GetPidToPinfo(pid, &pi);	if ( err < E_OK ) {		goto err_ret2;	}	if ( pi == mypi ) {		err = E_ILUSE;		goto err_ret2;	}	/* Set/refer to  */	old_mask = chgEmgEntry(pi, mypi->procid, t_mask);	if ( old_mask < E_OK ) {		err = old_mask;		goto err_ret2;	}	if ( t_mask > 0 ) {		if ( old_mask == 0 ) {			mypi->emg_cnt++;	/* Add */		}	} else if ( t_mask == 0 ) {		if ( old_mask != 0 ) {			mypi->emg_cnt--;	/* Delete */		}	}	Unlock(&ProcMgrLock);	return old_mask;err_ret2:	Unlock(&ProcMgrLock);err_ret1:	return err;}/*======================================================================	Common processing======================================================================*//*	Execute process startup functions*/LOCAL	void	CallStartUp(PINFO *pi){	tk_sta_ssy(0, pi->resid, pi->procid);}/*	Execute process cleanup functions*/LOCAL	void	CallCleanUp(PINFO *pi){	tk_cln_ssy(0, pi->resid, pi->procid);}/*	Change process priority*/Inline	W	CLAMP(W val, W minv, W maxv){	return	(val < minv) ? minv : ((val > maxv) ? maxv : val);}/* TK/SE = > TK priority */LOCAL	PRI	SE_K__Pri(W pri, W *slt){	if ((pri < MIN_ABSGRP_PRI )||( pri > MAX_RRGRP2_PRI)) {		return E_PAR;	}	if (pri < MIN_RRGRP1_PRI) {		*slt = ABSGRP_STIME;		return pri + PRI_ADJVAL;	}	if (pri < MIN_RRGRP2_PRI) {		*slt = MIN_RRGRP2_PRI - pri;		return	RRGRP1_TSKPRI;	}	*slt = (MAX_RRGRP2_PRI + 1) - pri;	return	RRGRP2_TSKPRI;}/* TK = > TK/SE priority */LOCAL	W	K_SE_Pri(PRI pri, W slt){	if (pri == RRGRP1_TSKPRI) {		return	CLAMP((MAX_RRGRP1_PRI + 1) - slt, MIN_RRGRP1_PRI, MAX_RRGRP1_PRI);	}	if (pri == RRGRP2_TSKPRI) {		return	CLAMP((MAX_RRGRP2_PRI + 1) - slt, MIN_RRGRP2_PRI, MAX_RRGRP2_PRI);	}	if (pri <= MAX_ABSGRP_TSKPRI) {		return	CLAMP(pri - PRI_ADJVAL, MIN_ABSGRP_PRI, MAX_ABSGRP_PRI);	}	return TSD_KSP_RTN_128;					/* Invalid */}/*	Check changes to priority (within the same group)*/LOCAL	ER	CheckPri(W old_pri, W new_pri){	if (new_pri < 0 ) {		return E_PAR;	}	if (old_pri < MIN_RRGRP1_PRI) {		if (new_pri >= MIN_RRGRP1_PRI) {			return E_PAR;		}	} else if (old_pri < MIN_RRGRP2_PRI) {		if ((new_pri < MIN_RRGRP1_PRI )||( new_pri >= MIN_RRGRP2_PRI)) {			return E_PAR;		}	} else {		if ((new_pri < MIN_RRGRP2_PRI )||( new_pri > MAX_RRGRP2_PRI)) {			return E_PAR;		}	}	return	E_OK;}/*	Fetch task state*/LOCAL	ER	RefTask(ID tid, T_RTSK *rtsk){	return tk_ref_tsk(tid, rtsk);}/*	Fetch priority*/LOCAL	W	GetPri(ID tskid){	ER	err;	T_RTSK	rtsk;	err = RefTask(tskid, &rtsk);	return (err != 0) ? err : K_SE_Pri(rtsk.tskpri, (W)rtsk.slicetime);}/*	Set priority*/LOCAL	ER	ChangePri(ID tid, W pri){	ER	er;	W	slt;	return	( (er = tk_chg_pri(tid, SE_K__Pri(pri, &slt))) ||		  (er = tk_chg_slt(tid, (UW)slt)) ) ? er : E_OK;}/*	Fetch system time (second)*/LOCAL	UW	GetSysSec( void ){	SYSTIM		now;	longlong	ll;	tk_get_tim(&now);	hilo_ll(ll, now.hi, now.lo);	return (UW)lltol(li_div(ll, TSD_GSS_VAL_1000));}/*	Check if a task is included in current process.*/EXPORT	BOOL	CheckSubTask(ID tid){	PINFO	*pi;	W	i;	pi = GetPinfo(TSK_SELF);	if ( pi == NULL ) {		return FALSE;	}	for (i = 0;(( i < MAX_SUBTASKS )&&( pi->tsk[i].tskid != tid)); i++){		;	}	return ( i < MAX_SUBTASKS );}/*	Process termination processing*/LOCAL	void	FinishProc(PINFO *pi){	PINFO		*cpi, *ppi;	PRCMINFO	*info;	QUEUE		*q;	W		i;	/* Release in-process resources: Execute cleanup() function for all managers. */	CallCleanUp(pi);	/* PRCMINFO is cleared by execution of cleanup function.	   Set pinfo again because it is used to refer to PINFO in subsequent processing. */	tk_get_res(pi->resid, PM_SVC, (VP*)&info);	info->pinfo = pi;	Lock(&ProcMgrLock);	LockPinfo();	/* Stop profile */	pi_profil(pi, NULL);	/* Change the number of child processes of a parent process. */	ppi = pi->parent;	if (ppi &&( ppi->nchild > 0)) {		ppi->nchild--;	}	i = (W)(pi->nchild + pi->emg_cnt);	if ( i > 0 ) {		for ( q = ( pi->emg_cnt == 0U )? pi->q.next: UsedPI.next;						q != &UsedPI; q = q->next ) {			cpi = (PINFO*)q;			if ( cpi->parent == pi ) {				/* Change a parent process of child processes. */				cpi->parent = ppi;				ppi->nchild++;				if ( --i == 0 ) {					break;				}			}			if ( cpi->emg_lst != NULL ) {				/* Reset process termination notification */				if ( chgEmgEntry(cpi, pi->procid, 0) > 0 ) {					if ( --i == 0 ) {						break;					}				}			}		}	}	/* Delete from queue */	QueRemove(&pi->q);	UnlockPinfo();#if VIRTUAL_ADDRESS	/* Delete address space of process */	UnmapProc(pi);#else

⌨️ 快捷键说明

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