📄 prcmgr.c
字号:
/* 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 + -