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

📄 prcmgr.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* Unloading of process */	UnloadProc(pi);#endif	if (( pi->exitkind <= EXIT_TERM_CHILD )&&( pi->emg_lst != NULL )) {		/* Send process termination notification */		sendEmg(pi);	}	if ((ppi )&&( pi->exitkind <= MS_TERM)) {		/* Send a termination message to the parent process. */		MESSAGE	msg;		msg.msg_type = (pi->exitkind != 0U) ? (W)pi->exitkind : MS_ABORT;		msg.msg_size = sizeof(W) + sizeof(W);		msg.msg_body.EXIT.pid = pi->procid;		msg.msg_body.EXIT.code = pi->exitcode;		_tkse_snd_msg(ppi->procid, &msg, NOWAIT, TSD_TSM_VAL_M1);	}	/* Initialize PINFO and register in FreePI. */	info->pinfo = NULL;  /* Clear it because it was set again after cleanup. */	tk_del_res(pi->resid);	bzero((VP)pi, (size_t)PINFO_BASE_SZ);	QueInsert(&pi->q, &FreePI);	Unlock(&ProcMgrLock);}/*	Termination processing of in-process task		Call a task while ProcMgrLock is locked.		By this procedure, ProcMgrLock is unlocked.*/LOCAL	void	ExitTask(PINFO *pi, ID tskid){	W	i;	BOOL	last = TRUE;	LockPinfo();	/* Check if it is the last task. */	for ( i = 0; i < MAX_SUBTASKS; i++ ) {		if (( pi->tsk[i].tskid < 0 )		  || ((tskid != TSK_SELF )&&( pi->tsk[i].tskid == tskid)) ) {#if VIRTUAL_ADDRESS			/* Release user stack */			UnmapStack(pi, pi->tsk[i].stack_addr);#endif			pi->tsk[i].tskid = 0;		}		if ( pi->tsk[i].tskid > 0 ) {			last = FALSE;		}	}	UnlockPinfo();	Unlock(&ProcMgrLock);	/* When it is the last task, perform termination processing of process. */	if ( last != 0 ) {		FinishProc(pi);	}	if ( tskid == TSK_SELF ) {		tk_exd_tsk();	/* No Return */	} else {		tk_ter_tsk(tskid);		tk_del_tsk(tskid);	}}/*	Termination processing of in-process task	To forcedly terminate a process where the forced exception handler does not work properly,	call a task directly from the exception handler.*/EXPORT	void	_ExitTask( PINFO *pi, ID tskid ){	Lock(&ProcMgrLock);	ExitTask(pi, tskid); /* By this procedure, ProcMgrLock is unlocked. */}/*	Forced termination of in-process task		Call a task while ProcMgrLock is locked.*/LOCAL	void	KillTasks(PINFO *pi, ID mytid, W exit_kind, W exit_code){	W	i;	ID	tid;	LockPinfo();	/* When the main task is terminated, the process is terminated. */	if (pi->tsk[0].tskid == mytid) {		if (pi->cinfo.cprc.prchdr != NULL) {			IAfree(pi->cinfo.cprc.prchdr, TA_RNG0);		}				if (exit_kind == EXIT_TERM_TASK) {			exit_kind = EXIT_NORM;		}	}	for (i = 0; i < MAX_SUBTASKS; i++) {		tid = pi->tsk[i].tskid;		if (tid != 0) {			if (tid == mytid) {		/* Current task */				pi->tsk[i].tskid = TSD_KTK_TID_M1;			} else if (exit_kind != 0) {		/* Other task */				/* Forced termination request				 *	PINFO must not be locked,				 *	otherwise the break handler is called.				 */				UnlockPinfo();				tk_ras_tex(tid, 0);				LockPinfo();			}		}	}	if (exit_kind &&( pi->exitkind == 0)) {		pi->exitkind = exit_kind;		/* Terminated state	*/		pi->exitcode = exit_code;		/* Termination code	*/	}	UnlockPinfo();}/*	Terminate all child processes*/LOCAL	void	TermChild(PINFO *parpi, ID mytid){	PINFO	*pi;	W	i;	for (pi = parpi, i = 0; i < parpi->nchild; i++) {		pi = (PINFO*)QueSearch(&pi->q, &UsedPI, (W)parpi,						(W)offsetof(PINFO, parent));		if (pi == (PINFO*)&UsedPI) {			break;		}		KillTasks(pi, mytid, EXIT_TERM_CHILD, 0);		TermChild(pi, mytid);	}	parpi->nchild = 0;}/*	Generate in-process task*/LOCAL	ER	CreateTask(PINFO *pi, FP entry, W pri, VP caller_gp){	ER	err;	W	i;	T_CTSK	ctsk;	ID	tskid;#if VIRTUAL_ADDRESS	VP	stkptr;#endif	/* Find task slot */	for (i = 0;(( i < MAX_SUBTASKS )&& pi->tsk[i].tskid); i++) {		;	}	if (i >= MAX_SUBTASKS) {		return E_LIMIT;	/* Limitation error on number of tasks */	}#if VIRTUAL_ADDRESS	/* Stack mapping */	err = MapStack(pi, (W)pi->ldinfo.stacksz, &stkptr);	if ( err < E_OK ) {		goto err_ret0;	}	pi->tsk[i].stack_addr = stkptr;#endif	/* Generate task */	ctsk.exinf   = PRCTSK_EXINF;	ctsk.tskatr  = TA_HLNG | TA_FPU | TA_SSTKSZ | TA_RESID | TA_GP			| (pi->sysproc ? TA_RNG1 : TA_RNG3);	ctsk.itskpri = PRC_DMY_PRI;	ctsk.task    = entry;	ctsk.sstksz  = SYS_STKSZ;	ctsk.resid   = pi->resid;#if VIRTUAL_ADDRESS	ctsk.stksz   = 0;	ctsk.tskatr |= TA_USERSTACK | TA_TASKSPACE;	ctsk.stkptr  = (VB*)stkptr + pi->ldinfo.stacksz;	ctsk.lsid    = (INT)GetLSID(pi);	ctsk.uatb    = GetUATB((UW)ctsk.lsid);#else	ctsk.stksz   = GetLoadInfo(pi->ldinfo.loadno)->stacksz;#endif#if TA_GP	ctsk.gp = caller_gp;#endif	tskid = tk_cre_tsk(&ctsk);	if ( tskid < E_OK ) {		err = tskid;		goto err_ret1;	}	/* Priority setting */	err = ChangePri(tskid, pri);	if ( err < E_OK ) {		goto err_ret2;	}	LockPinfo();	pi->tsk[i].msg_waimask = 0;	pi->tsk[i].tskid = tskid;	UnlockPinfo();	return tskid;err_ret2:	(void)tk_del_tsk(tskid);err_ret1:#if VIRTUAL_ADDRESS	UnmapStack(pi, stkptr);err_ret0:#endif	return err;}/*	Generate process	mode	Use OR to specify the following:		0x0001	System process		0x0002	Start debug*/LOCAL	WER	CreateProcess(POBJ_HDR* pohdr, W pri, MESSAGE *msg, UW mode){	PINFO	*pi, *new = NULL;	ER	err;	W	pid = 0, tid = 0;	FP	entry;	VP	prchdr;	INT	hdrsize;	/* Parameter check */	if (CheckSpaceR((VP)msg, (W)offsetof(MESSAGE, msg_body)) ||	    (CheckSpaceR((VP)&msg->msg_body, msg->msg_size)) ) {		return E_MACV;	}	if ((W)MSGSIZE((UW)msg->msg_size) > MAX_MSGSZ) {		return E_LIMIT;	}	Lock(&ProcMgrLock);	/* Fetch PINFO of current process */	pi = GetPinfo(TSK_SELF);	if (!(pi )) {		err = E_CTX;		goto EEXIT;	}	if (pri == TSD_CPS_VAL_M1) {		pri = GetPri(TSK_SELF);	}	if ((pri < MIN_ABSGRP_PRI )||( pri > MAX_RRGRP2_PRI)) {		err = E_PAR;		goto EEXIT;	}	mode |= pi->dbgmode << 1;	/* Obtain PINFO */	new = (PINFO*)QueRemoveNext(&FreePI);	if ( new == NULL ) {		err = E_LIMIT;		goto EEXIT;	}	err = tk_cre_res();	if ( err < E_OK ) {		QueInsert(&new->q, &FreePI);		err = E_LIMIT;		goto EEXIT;	}	new->resid = err;	/* */	switch (pohdr->type) {	case TPA_LINK:		hdrsize = sizeof(LINK);		prchdr = IAmalloc((size_t)hdrsize, TA_RNG0);		if ( prchdr == NULL ) {			err = E_NOMEM;			goto EEXIT;		}		memcpy(prchdr, pohdr->src.lnk, sizeof(LINK));		break;	case TPA_SEIO:		hdrsize = (INT)strlen(pohdr->src.path) + 1;		/* + 1 (NULL code) */		prchdr = IAmalloc((size_t)hdrsize, TA_RNG0);		if ( prchdr == NULL ) {			err = E_NOMEM;			goto EEXIT;		}		memcpy(prchdr, pohdr->src.path, (size_t)hdrsize);		break;	case TPA_PTR:		hdrsize = sizeof(VP);		prchdr = pohdr->src.buf;		break;	default:		err = E_NOMEM;		goto EEXIT;	}	/* Generate process space and map		(Allocate/load initial page to process space) */	new->sysproc = mode & 1U;#if VIRTUAL_ADDRESS	err = MapProc(new, pohdr, &entry);#else	err = LoadProc(new, pohdr, &entry);#endif	/* Generate main task */	if (err >= 0) {		tid = err = CreateTask(new, entry, pri, NULL);#if VIRTUAL_ADDRESS		if (err < 0) {			UnmapProc(new);		}#else		if (err < 0) {			UnloadProc(new);		}#endif	}	LockPinfo();	if (err >= 0) {		/* Allocate process ID */		pid = NewProcID();		/* Insert new process PINFO immediately after current process */		QueInsert(&new->q, pi->q.next);		/* Set details of PINFO */		new->procid  = pid;			/* Process ID	*/		new->parent  = pi;			/* Parent process	*/		new->fexchdr = NULL;		new->ctime   = GetSysSec();		/* Time of generation	*/		new->user    = pi->user;		/* User information	*/		new->consinf = pi->consinf;		/* Console information */		pi->nchild++;				/* Number of child processes*/		new->cinfo.hdrsize     = hdrsize;		new->cinfo.cprc.prcatr = (ATR)(pohdr->type | ( new->sysproc ? (TPA_SYS) : (TPA_USR) ));		new->cinfo.cprc.prchdr = prchdr;		new->cinfo.cprc.pri    = pri;	} else {		tk_del_res(new->resid);		bzero((VP)new, (size_t)PINFO_BASE_SZ);		QueInsert(&new->q, &FreePI);	}	UnlockPinfo();EEXIT:	Unlock(&ProcMgrLock);	if (err < 0) {		return err;	}	/* Initialize manager-dependent section */	CallStartUp(new);	/* Send startup message */	err = _tkse_snd_msg(pid, msg, NOWAIT, TSD_TSM_VAL_M1);	if (err < 0) {		/* Delete process */		Lock(&ProcMgrLock);		new->exitkind = EXIT_FORCE;		ExitTask(new, tid);		return err;	}	if ( (mode & TSD_CPS_MSK_2) == 0U ) {		/* Start task */		tk_sta_tsk(tid, (W)MSGSIZE((UW)msg->msg_size));	} else {		/* Start debug */		tk_dis_dsp();		tk_sta_tsk(tid, (W)MSGSIZE((UW)msg->msg_size));		tk_sus_tsk(tid);		tk_ena_dsp();		if ( BDM_NotifyStartProcess(new) < E_OK ) {			tk_rsm_tsk(tid);		}	}	return pid;}/*======================================================================	Process SVC handling======================================================================*//*	Use current task as initial process (special process of ring 0)				(Internal use only: not defined as SVC)*/EXPORT	void	MakeFirstProc(TC *name, PRI ipri){	PINFO		*pi;	PRCMINFO	*info;	ID		pid;	Lock(&ProcMgrLock);	/* Obtain PINFO */	pi = (PINFO*)QueRemoveNext(&FreePI);	/* Obtain process ID */	pid = NewProcID();	/* Set PINFO for task */	pi->resid = __CommArea->SysResID;	tk_get_res(pi->resid, PM_SVC, (VP*)&info);	info->pinfo = pi;	QueInit(&info->dynldq);	tk_chg_pri(TSK_SELF, ipri);	/* Set details of PINFO */	LockPinfo();	QueInsert(&pi->q, &UsedPI);	pi->procid       = pid;			/* Process ID		*/	pi->parent       = NULL;		/* Parent process		*/	tc_strncpy(pi->name, name, PNAME_SZ);	/* Process name		*/	pi->sysproc      = 1;	/* System process	*/	pi->tsk[0].tskid = GetMyTid();		/* Task ID		*/	pi->ctime        = GetSysSec();		/* Time of generation		*/	pi->user         = &UserInfo;		/* User information		*/	UnlockPinfo();	Unlock(&ProcMgrLock);#if VIRTUAL_ADDRESS	{	/* Set unique space */	IMPORT T_TSKSPC GetTSKSPC_pinfo( PINFO *pinfo );	T_TSKSPC tskspc;	tskspc = GetTSKSPC_pinfo(pi);	tk_set_tsp(TSK_SELF, &tskspc);	/* Initialize local memory */	pi->ldinfo.topadr = (VP)LOCALSPACE_TOP;	InitLocalMemory(pi);	}#endif	/* Initialize manager-dependent section */	CallStartUp(pi);}/*	Generate process*/LOCAL	WER	_tkse_cre_prc2(LINK* lnk, PRI pri, MESSAGE *msg){	POBJ_HDR	pohdr;	if (CheckSpaceR((VP)lnk, sizeof(LINK)) != 0) {		return E_MACV;	}	pohdr.type = TPA_LINK;	pohdr.src.lnk = lnk;	return	CreateProcess(&pohdr, pri, msg, 0);}/*	Generate system process*/LOCAL	WER	_tkse_cre_sysprc(LINK* lnk, PRI pri, MESSAGE *msg){	POBJ_HDR	pohdr;	if (CheckSpaceR((VP)lnk, sizeof(LINK)) != 0) {		return E_MACV;	}	pohdr.type = TPA_LINK;	pohdr.src.lnk = lnk;	return	CreateProcess(&pohdr, pri, msg, 1);}LOCAL	WER	_tkse_cre_prc(T_CPRC *pk_cprc, MESSAGE *msg){	ATR	atr;	ER	err = E_OK;	POBJ_HDR	pohdr;	if ((pk_cprc == NULL) ||	    (pk_cprc && CheckSpaceR((VP)pk_cprc, sizeof(T_CPRC)  )) ||	    (msg     && CheckSpaceR((VP)msg    , sizeof(MESSAGE) )) ) {		err = E_MACV;		goto err_ret;	}	atr = pk_cprc->prcatr;	if ((atr & ~(TPA_RNGMASK | TPA_INPUTMASK)) != 0) {		err = E_PAR;		goto err_ret;	}	pohdr.type = (W)(atr & TPA_INPUTMASK);	switch (pohdr.type) {	case TPA_LINK:		pohdr.src.lnk = (LINK*)pk_cprc->prchdr;		break;	case TPA_SEIO:		pohdr.src.path = (B*)pk_cprc->prchdr;		break;	case TPA_PTR:		pohdr.src.buf = (VP)pk_cprc->prchdr;		break;	default:		err = E_PAR;		goto err_ret;	}		err = CreateProcess(&pohdr, pk_cprc->pri, msg,			    ((atr & TPA_RNGMASK) <= TPA_SYS) ? 1:0);err_ret:	return err;}/*	Normal process termination*/LOCAL	void	_tkse_ext_prc(W exit_code){	PINFO	*pi;	Lock(&ProcMgrLock);	if ( GetPidToPinfo(0, &pi) < E_OK ) {		Unlock(&ProcMgrLock);		/* bms_printf("tkse_ext_prc: no process\n"); */		SYSLOG((LOG_ERR, "tkse_ext_prc() in Not Process"));		syslog_wait();		if ( _isDebugMode() != 0 ) {			tm_monitor();		}		tk_exd_tsk();	} else {		KillTasks(pi, GetMyTid(), EXIT_NORM, exit_code);		ExitTask(pi, TSK_SELF);	/* No Return */	}}/*	Forced process termination*/LOCAL	ER	 _tkse_ter_prc(ID pid, W abort_code, W opt){	PINFO	*pi, *mypi;	ER	err;	if (((UW)opt & ~(UW)(TERM_NRM | TERM_ALL)) != 0) {		return E_PAR;	}	Lock(&ProcMgrLock);	err = GetPidToPinfo(pid, &pi);	if ( err < E_OK ) {		goto err_ret;	}	mypi = GetPinfo(TSK_SELF);	if (!(mypi )) {		err = E_CTX;	} else if (mypi == pi) {		err = E_ILUSE;	} else if (pi == INIT_PINFO) {		err = E_ILUSE;	} else if (mypi->user->user.level > pi->user->user.level) {		err = E_ILUSE;	} else {		if (opt == TERM_ALL) {			TermChild(pi, GetMyTid());		}		KillTasks(pi, TSD_KTK_VAL_M1, EXIT_TERM, abort_code);		if (mypi->exitkind == EXIT_TERM_CHILD) {			ExitTask(pi, TSK_SELF);	/* No Return */		}	}err_ret:	Unlock(&ProcMgrLock);	return err;}/*	Abnormal termination of process (Internal use only: not defined as SVC)	Called from message management.*/EXPORT	ER	 _tkse_abo_prc(ID pid, W abort_code){	PINFO	*pi;	ER	err;	Lock(&ProcMgrLock);	err = GetPidToPinfo(pid, &pi);	if ( err < E_OK ) {		goto err_ret;	}	KillTasks(pi, GetMyTid(), EXIT_ABORT, abort_code);	if ( GetPinfo(TSK_SELF) == pi ) {		ExitTask(pi, TSK_SELF);	/* No Return */	}err_ret:	Unlock(&ProcMgrLock);	return err;}#if _USE_TKSE_ABO_TSK/*	Abnormal termination of process (Internal use only: not defined as SVC)*/LOCAL	WER	_tkse_abo_tsk(ID tskid, W abort_code){	PINFO	*pi;	W	pid = E_NOEXS;	Lock(&ProcMgrLock);	if ((pi = GetPinfo(tskid)) != 0) {		pid = pi->procid;		KillTasks(pi, TSD_KTK_VAL_M1, EXIT_ABORT, abort_code);	}	Unlock(&ProcMgrLock);

⌨️ 快捷键说明

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