SYSCALL INT _tk_cal_por_u( ID porid, UINT calptn, void *msg, INT cmsgsz, TMO_U tmout ) { PORCB *porcb; TCB *tcb; QUEUE *queue; RNO rdvno; INT rmsgsz; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(calptn != 0); CHECK_PAR(cmsgsz >= 0); CHECK_TMOUT(tmout); CHECK_DISPATCH(); porcb = get_porcb(porid); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( cmsgsz > porcb->maxcmsz ) { ercd = E_PAR; goto error_exit; } #endif /* Search accept wait task */ queue = porcb->accept_queue.next; while ( queue != &porcb->accept_queue ) { tcb = (TCB*)queue; queue = queue->next; if ( (calptn & tcb->winfo.acp.acpptn) == 0 ) { continue; } /* Check rendezvous call wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_CAL) ) { ercd = E_DISWAI; goto error_exit; } /* Send message */ rdvno = gen_rdvno(ctxtsk); if ( cmsgsz > 0 ) { memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz); } *tcb->winfo.acp.p_rdvno = rdvno; *tcb->winfo.acp.p_cmsgsz = cmsgsz; wait_release_ok(tcb); /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_RDV) ) { ercd = E_DISWAI; goto error_exit; } /* Ready for rendezvous end wait */ ercd = E_TMOUT; ctxtsk->wspec = &wspec_rdv; ctxtsk->wid = 0; ctxtsk->wercd = &ercd; ctxtsk->winfo.rdv.rdvno = rdvno; ctxtsk->winfo.rdv.msg = msg; ctxtsk->winfo.rdv.maxrmsz = porcb->maxrmsz; ctxtsk->winfo.rdv.p_rmsgsz = &rmsgsz; make_wait(TMO_FEVR, porcb->poratr); QueInit(&ctxtsk->tskque); goto error_exit; } /* Ready for rendezvous call wait */ ctxtsk->wspec = ( (porcb->poratr & TA_TPRI) != 0 )? &wspec_cal_tpri: &wspec_cal_tfifo; ctxtsk->wercd = &ercd; ctxtsk->winfo.cal.calptn = calptn; ctxtsk->winfo.cal.msg = msg; ctxtsk->winfo.cal.cmsgsz = cmsgsz; ctxtsk->winfo.cal.p_rmsgsz = &rmsgsz; gcb_make_wait_with_diswai((GCB*)porcb, tmout); error_exit: END_CRITICAL_SECTION; return ( ercd < E_OK )? ercd: rmsgsz; }
SYSCALL INT _tk_acp_por_u( ID porid, UINT acpptn, RNO *p_rdvno, void *msg, TMO_U tmout ) { PORCB *porcb; TCB *tcb; QUEUE *queue; RNO rdvno; INT cmsgsz; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(acpptn != 0); CHECK_TMOUT(tmout); CHECK_DISPATCH(); porcb = get_porcb(porid); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } /* Search call wait task */ queue = porcb->call_queue.next; while ( queue != &porcb->call_queue ) { tcb = (TCB*)queue; queue = queue->next; if ( (acpptn & tcb->winfo.cal.calptn) == 0 ) { continue; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } /* Receive message */ *p_rdvno = rdvno = gen_rdvno(tcb); cmsgsz = tcb->winfo.cal.cmsgsz; if ( cmsgsz > 0 ) { memcpy(msg, tcb->winfo.cal.msg, (UINT)cmsgsz); } /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, tcb, TTW_RDV) ) { wait_release_ng(tcb, E_DISWAI); goto error_exit; } wait_cancel(tcb); /* Make the other task at rendezvous end wait state */ tcb->wspec = &wspec_rdv; tcb->wid = 0; tcb->winfo.rdv.rdvno = rdvno; tcb->winfo.rdv.msg = tcb->winfo.cal.msg; tcb->winfo.rdv.maxrmsz = porcb->maxrmsz; tcb->winfo.rdv.p_rmsgsz = tcb->winfo.cal.p_rmsgsz; timer_insert(&tcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, tcb); QueInit(&tcb->tskque); goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } ercd = E_TMOUT; if ( tmout != TMO_POL ) { /* Ready for rendezvous accept wait */ ctxtsk->wspec = &wspec_acp; ctxtsk->wid = porid; ctxtsk->wercd = &ercd; ctxtsk->winfo.acp.acpptn = acpptn; ctxtsk->winfo.acp.msg = msg; ctxtsk->winfo.acp.p_rdvno = p_rdvno; ctxtsk->winfo.acp.p_cmsgsz = &cmsgsz; make_wait(tmout, porcb->poratr); QueInsert(&ctxtsk->tskque, &porcb->accept_queue); } error_exit: END_CRITICAL_SECTION; return ( ercd < E_OK )? ercd: cmsgsz; }
ER_UINT acre_mtx(const T_CMTX *pk_cmtx) { MTXCB *p_mtxcb; MTXINIB *p_mtxinib; ATR mtxatr; PRI ceilpri; ID domid; const DOMINIB *p_dominib; ACPTN acptn; ER ercd; LOG_ACRE_MTX_ENTER(pk_cmtx); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_cmtx, T_CMTX); mtxatr = pk_cmtx->mtxatr; ceilpri = pk_cmtx->ceilpri; if ((mtxatr & MTXPROTO_MASK) == TA_CEILING) { CHECK_VALIDATR(mtxatr, TA_CEILING|TA_DOMMASK); CHECK_PAR(VALID_TPRI(ceilpri)); } else { CHECK_VALIDATR(pk_cmtx->mtxatr, TA_TPRI|TA_DOMMASK); } domid = get_atrdomid(mtxatr); if (domid == TDOM_SELF) { if (rundom == TACP_KERNEL) { domid = TDOM_KERNEL; } else { domid = p_runtsk->p_tinib->domid; } mtxatr = set_atrdomid(mtxatr, domid); } switch (domid) { case TDOM_KERNEL: p_dominib = &dominib_kernel; break; case TDOM_NONE: p_dominib = &dominib_none; break; default: CHECK_RSATR(VALID_DOMID(domid)); p_dominib = get_dominib(domid); break; } CHECK_ACPTN(p_dominib->acvct.acptn1); lock_cpu(); if (tnum_mtx == 0 || queue_empty(&(p_dominib->p_domcb->free_mtxcb))) { ercd = E_NOID; } else { p_mtxcb = (MTXCB *) queue_delete_next(&(p_dominib->p_domcb->free_mtxcb)); p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib); p_mtxinib->mtxatr = mtxatr; p_mtxinib->ceilpri = INT_PRIORITY(ceilpri); acptn = default_acptn(domid); p_mtxinib->acvct.acptn1 = acptn; p_mtxinib->acvct.acptn2 = acptn; p_mtxinib->acvct.acptn3 = p_dominib->acvct.acptn1; p_mtxinib->acvct.acptn4 = acptn; queue_initialize(&(p_mtxcb->wait_queue)); p_mtxcb->p_loctsk = NULL; ercd = MTXID(p_mtxcb); } unlock_cpu(); error_exit: LOG_ACRE_MTX_LEAVE(ercd); return(ercd); }
/* * Create task */ SYSCALL ID _tk_cre_tsk P1( CONST T_CTSK *pk_ctsk ) { #if CHK_RSATR const ATR VALID_TSKATR = { /* Valid value of task attribute */ TA_HLNG |TA_SSTKSZ |TA_USERSTACK |TA_TASKSPACE |TA_RESID |TA_RNG3 |TA_FPU |TA_COP0 |TA_COP1 |TA_COP2 |TA_COP3 |TA_GP #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif TCB *tcb; INT stksz, sstksz, sysmode, resid; void *stack = NULL, *sstack; ER ercd; CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR); CHECK_PRI(pk_ctsk->itskpri); CHECK_NOCOP(pk_ctsk->tskatr); #if USE_SINGLE_STACK CHECK_NOSPT((pk_ctsk->tskatr & TA_USERSTACK) == 0); #endif #if CHK_PAR if ( (pk_ctsk->tskatr & TA_USERSTACK) != 0 ) { CHECK_PAR((pk_ctsk->tskatr & TA_RNG3) != TA_RNG0); CHECK_PAR(pk_ctsk->stksz == 0); } else { CHECK_PAR(pk_ctsk->stksz >= 0); } if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) { CHECK_PAR(pk_ctsk->lsid >= 0 && pk_ctsk->lsid <= MAX_LSID); } #endif if ( (pk_ctsk->tskatr & TA_RESID) != 0 ) { CHECK_RESID(pk_ctsk->resid); resid = pk_ctsk->resid; } else { resid = SYS_RESID; /* System resource group */ } if ( (pk_ctsk->tskatr & TA_SSTKSZ) != 0 ) { CHECK_PAR(pk_ctsk->sstksz >= MIN_SYS_STACK_SIZE); sstksz = pk_ctsk->sstksz; } else { sstksz = default_sstksz; } if ( (pk_ctsk->tskatr & TA_RNG3) == TA_RNG0 ) { sysmode = 1; sstksz += pk_ctsk->stksz; stksz = 0; } else { sysmode = 0; #if USE_SINGLE_STACK sstksz += pk_ctsk->stksz; stksz = 0; #else stksz = pk_ctsk->stksz; #endif } /* Adjust stack size by 8 bytes */ sstksz = (sstksz + 7) / 8 * 8; stksz = (stksz + 7) / 8 * 8; /* Allocate system stack area */ sstack = IAmalloc((UINT)sstksz, TA_RNG0); if ( sstack == NULL ) { return E_NOMEM; } if ( stksz > 0 ) { /* Allocate user stack area */ stack = IAmalloc((UINT)stksz, pk_ctsk->tskatr); if ( stack == NULL ) { IAfree(sstack, TA_RNG0); return E_NOMEM; } } BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ tcb = (TCB*)QueRemoveNext(&free_tcb); if ( tcb == NULL ) { ercd = E_LIMIT; goto error_exit; } /* Initialize control block */ tcb->exinf = pk_ctsk->exinf; tcb->tskatr = pk_ctsk->tskatr; tcb->task = pk_ctsk->task; tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri); tcb->resid = resid; tcb->stksz = stksz; tcb->sstksz = sstksz; #if USE_OBJECT_NAME if ( (pk_ctsk->tskatr & TA_DSNAME) != 0 ) { STRNCPY((char*)tcb->name, (char*)pk_ctsk->dsname, OBJECT_NAME_LENGTH); } #endif #if TA_GP /* Set global pointer */ if ( (pk_ctsk->tskatr & TA_GP) != 0 ) { gp = pk_ctsk->gp; } tcb->gp = gp; #endif /* Set stack pointer */ if ( stksz > 0 ) { tcb->istack = (VB*)stack + stksz; } else { tcb->istack = pk_ctsk->stkptr; } tcb->isstack = (VB*)sstack + sstksz - RESERVE_SSTACK(tcb->tskatr); /* Set initial value of task operation mode */ tcb->isysmode = (B)sysmode; tcb->sysmode = (H)sysmode; /* Set initial value of task space */ if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) { tcb->tskctxb.uatb = pk_ctsk->uatb; tcb->tskctxb.lsid = pk_ctsk->lsid; } else { tcb->tskctxb.uatb = NULL; tcb->tskctxb.lsid = 0; /* Task Space */ } /* make it to DORMANT state */ make_dormant(tcb); ercd = tcb->tskid; error_exit: END_CRITICAL_SECTION; if ( ercd < E_OK ) { IAfree(sstack, TA_RNG0); if ( stksz > 0 ) { IAfree(stack, pk_ctsk->tskatr); } } return ercd; }
ER_UINT acre_mbf(const T_CMBF *pk_cmbf) { MBFCB *p_mbfcb; MBFINIB *p_mbfinib; ATR mbfatr; uint_t maxmsz; size_t mbfsz; void *mbfmb; ID domid; const DOMINIB *p_dominib; ACPTN acptn; ER ercd; LOG_ACRE_MBF_ENTER(pk_cmbf); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_cmbf, T_CMBF); mbfatr = pk_cmbf->mbfatr; maxmsz = pk_cmbf->maxmsz; mbfsz = pk_cmbf->mbfsz; mbfmb = pk_cmbf->mbfmb; CHECK_VALIDATR(mbfatr, TA_TPRI|TA_DOMMASK); if (mbfmb != NULL) { CHECK_PAR(MB_ALIGN(mbfmb)); CHECK_OBJ(valid_memobj_kernel(mbfmb, mbfsz)); } domid = get_atrdomid(mbfatr); if (domid == TDOM_SELF) { if (rundom == TACP_KERNEL) { domid = TDOM_KERNEL; } else { domid = p_runtsk->p_tinib->domid; } mbfatr = set_atrdomid(mbfatr, domid); } switch (domid) { case TDOM_KERNEL: p_dominib = &dominib_kernel; break; case TDOM_NONE: p_dominib = &dominib_none; break; default: CHECK_RSATR(VALID_DOMID(domid)); p_dominib = get_dominib(domid); break; } CHECK_ACPTN(p_dominib->acvct.acptn1); lock_cpu(); if (tnum_mbf == 0 || queue_empty(&(p_dominib->p_domcb->free_mbfcb))) { ercd = E_NOID; } else { if (mbfsz != 0 && mbfmb == NULL) { mbfmb = malloc_mpk(mbfsz, p_dominib); mbfatr |= TA_MBALLOC; } if (mbfsz != 0 && mbfmb == NULL) { ercd = E_NOMEM; } else { p_mbfcb = (MBFCB *) queue_delete_next(&(p_dominib->p_domcb->free_mbfcb)); p_mbfinib = (MBFINIB *)(p_mbfcb->p_mbfinib); p_mbfinib->mbfatr = mbfatr; p_mbfinib->maxmsz = maxmsz; p_mbfinib->mbfsz = mbfsz; p_mbfinib->mbfmb = mbfmb; acptn = default_acptn(domid); p_mbfinib->acvct.acptn1 = acptn; p_mbfinib->acvct.acptn2 = acptn; p_mbfinib->acvct.acptn3 = p_dominib->acvct.acptn1; p_mbfinib->acvct.acptn4 = acptn; queue_initialize(&(p_mbfcb->swait_queue)); queue_initialize(&(p_mbfcb->rwait_queue)); p_mbfcb->fmbfsz = mbfsz; p_mbfcb->head = 0U; p_mbfcb->tail = 0U; p_mbfcb->smbfcnt = 0U; ercd = MBFID(p_mbfcb); } } unlock_cpu(); error_exit: LOG_ACRE_MBF_LEAVE(ercd); return(ercd); }
/* * Create variable size memory pool */ SYSCALL ID _tk_cre_mpl( CONST T_CMPL *pk_cmpl ) { #if CHK_RSATR const ATR VALID_MPLATR = { TA_TPRI |TA_RNG3 |TA_NODISWAI #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif MPLCB *mplcb; ID mplid; INT mplsz; void *mempool; ER ercd; CHECK_RSATR(pk_cmpl->mplatr, VALID_MPLATR); CHECK_PAR(pk_cmpl->mplsz > 0 && pk_cmpl->mplsz <= MAX_ALLOCATE); CHECK_DISPATCH(); mplsz = roundSize(pk_cmpl->mplsz); /* Allocate memory for memory pool */ mempool = IAmalloc((UINT)mplsz + sizeof(QUEUE)*2, pk_cmpl->mplatr); if ( mempool == NULL ) { return E_NOMEM; } BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ mplcb = (MPLCB*)QueRemoveNext(&free_mplcb); if ( mplcb == NULL ) { ercd = E_LIMIT; } else { mplid = ID_MPL(mplcb - mplcb_table); /* Initialize control block */ QueInit(&mplcb->wait_queue); mplcb->mplid = mplid; mplcb->exinf = pk_cmpl->exinf; mplcb->mplatr = pk_cmpl->mplatr; mplcb->mplsz = mplsz; #if USE_OBJECT_NAME if ( (pk_cmpl->mplatr & TA_DSNAME) != 0 ) { strncpy((char*)mplcb->name, (char*)pk_cmpl->dsname, OBJECT_NAME_LENGTH); } #endif /* Initialize memory pool */ init_mempool(mplcb, mempool, mplsz + (INT)sizeof(QUEUE)*2); ercd = mplid; } END_CRITICAL_SECTION; if ( ercd < E_OK ) { IAfree(mempool, pk_cmpl->mplatr); } return ercd; }
ER_UINT acre_mpf(const T_CMPF *pk_cmpf) { MPFCB *p_mpfcb; MPFINIB *p_mpfinib; ATR mpfatr; void *mpf; MPFMB *p_mpfmb; ER ercd; LOG_ACRE_MPF_ENTER(pk_cmpf); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI); CHECK_PAR(pk_cmpf->blkcnt != 0); CHECK_PAR(pk_cmpf->blksz != 0); if (pk_cmpf->mpf != NULL) { CHECK_PAR(MPF_ALIGN(pk_cmpf->mpf)); } if (pk_cmpf->mpfmb != NULL) { CHECK_PAR(MB_ALIGN(pk_cmpf->mpfmb)); } mpfatr = pk_cmpf->mpfatr; mpf = pk_cmpf->mpf; p_mpfmb = pk_cmpf->mpfmb; lock_cpu(); if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) { ercd = E_NOID; } else { if (mpf == NULL) { mpf = kernel_malloc(ROUND_MPF_T(pk_cmpf->blksz) * pk_cmpf->blkcnt); mpfatr |= TA_MEMALLOC; } if (mpf == NULL) { ercd = E_NOMEM; } else { if (p_mpfmb == NULL) { p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt); mpfatr |= TA_MBALLOC; } if (p_mpfmb == NULL) { if (pk_cmpf->mpf == NULL) { kernel_free(mpf); } ercd = E_NOMEM; } else { p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb)); p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib); p_mpfinib->mpfatr = mpfatr; p_mpfinib->blkcnt = pk_cmpf->blkcnt; p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz); p_mpfinib->mpf = mpf; p_mpfinib->p_mpfmb = p_mpfmb; queue_initialize(&(p_mpfcb->wait_queue)); p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt; p_mpfcb->unused = 0U; p_mpfcb->freelist = INDEX_NULL; ercd = MPFID(p_mpfcb); } } } unlock_cpu(); error_exit: LOG_ACRE_MPF_LEAVE(ercd); return(ercd); }
ER_UINT acre_tsk(const T_CTSK *pk_ctsk) { ID domid; const DOMINIB *p_dominib; TCB *p_tcb; TINIB *p_tinib; ATR tskatr; SIZE sstksz, ustksz; void *sstk, *ustk; ACPTN acptn; ER ercd; LOG_ACRE_TSK_ENTER(pk_ctsk); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_ctsk, T_CTSK); CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR|TA_DOMMASK); domid = get_atrdomid(pk_ctsk->tskatr); CHECK_ATRDOMID_ACTIVE(domid); CHECK_ALIGN_FUNC(pk_ctsk->task); CHECK_NONNULL_FUNC(pk_ctsk->task); CHECK_TPRI(pk_ctsk->itskpri); p_dominib = (domid == TDOM_SELF) ? p_runtsk->p_tinib->p_dominib : (domid == TDOM_KERNEL) ? &dominib_kernel : get_dominib(domid); if (p_dominib == &dominib_kernel) { /* * システムタスクの場合 */ ustksz = 0U; ustk = NULL; CHECK_PAR(pk_ctsk->sstk == NULL); CHECK_PAR(pk_ctsk->stksz > 0U); sstksz = pk_ctsk->stksz; sstk = pk_ctsk->stk; if (sstk != NULL) { CHECK_PAR(pk_ctsk->sstksz == 0U); } else { sstksz += pk_ctsk->sstksz; } } else { /* * ユーザタスクの場合 */ ustksz = pk_ctsk->stksz; ustk = pk_ctsk->stk; CHECK_PAR(ustksz >= TARGET_MIN_USTKSZ); CHECK_NOSPT(ustk != NULL); CHECK_TARGET_USTACK(ustksz, ustk, p_dominib); sstksz = pk_ctsk->sstksz; sstk = pk_ctsk->sstk; } CHECK_PAR(sstksz >= TARGET_MIN_SSTKSZ); if (sstk != NULL) { CHECK_ALIGN_STKSZ(sstksz); CHECK_ALIGN_STACK(sstk); } CHECK_ACPTN(sysstat_acvct.acptn3); tskatr = pk_ctsk->tskatr; t_lock_cpu(); if (queue_empty(&free_tcb)) { ercd = E_NOID; } else { if (sstk == NULL) { sstk = kernel_malloc(ROUND_STK_T(sstksz)); tskatr |= TA_MEMALLOC; } if (sstk == NULL) { ercd = E_NOMEM; } else { p_tcb = ((TCB *) queue_delete_next(&free_tcb)); p_tinib = (TINIB *)(p_tcb->p_tinib); p_tinib->p_dominib = p_dominib; p_tinib->tskatr = tskatr; p_tinib->exinf = pk_ctsk->exinf; p_tinib->task = pk_ctsk->task; p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri); #ifdef USE_TSKINICTXB init_tskinictxb(&(p_tinib->tskinictxb), p_dominib, sstksz, sstk, utsksz, ustk, pk_ctsk); #else /* USE_TSKINICTXB */ p_tinib->sstksz = sstksz; p_tinib->sstk = sstk; p_tinib->ustksz = ustksz; p_tinib->ustk = ustk; #endif /* USE_TSKINICTXB */ p_tinib->texatr = TA_NULL; p_tinib->texrtn = NULL; acptn = default_acptn(domid); p_tinib->acvct.acptn1 = acptn; p_tinib->acvct.acptn2 = acptn; p_tinib->acvct.acptn3 = acptn | rundom; p_tinib->acvct.acptn4 = acptn; p_tcb->actque = false; make_dormant(p_tcb); queue_initialize(&(p_tcb->mutex_queue)); if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) { make_active(p_tcb); } ercd = TSKID(p_tcb); } } t_unlock_cpu(); error_exit: LOG_ACRE_TSK_LEAVE(ercd); return(ercd); }
ER_UINT acre_tsk(const T_CTSK *pk_ctsk) { TCB *p_tcb; TINIB *p_tinib; ATR tskatr; TASK task; PRI itskpri; size_t stksz; STK_T *stk; ER ercd; LOG_ACRE_TSK_ENTER(pk_ctsk); CHECK_TSKCTX_UNL(); tskatr = pk_ctsk->tskatr; task = pk_ctsk->task; itskpri = pk_ctsk->itskpri; stksz = pk_ctsk->stksz; stk = pk_ctsk->stk; CHECK_RSATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR); CHECK_PAR(FUNC_ALIGN(task)); CHECK_PAR(FUNC_NONNULL(task)); CHECK_PAR(VALID_TPRI(itskpri)); CHECK_PAR(stksz >= TARGET_MIN_STKSZ); if (stk != NULL) { CHECK_PAR(STKSZ_ALIGN(stksz)); CHECK_PAR(STACK_ALIGN(stk)); } lock_cpu(); if (queue_empty(&free_tcb)) { ercd = E_NOID; } else { if (stk == NULL) { stk = kernel_malloc(ROUND_STK_T(stksz)); tskatr |= TA_MEMALLOC; } if (stk == NULL) { ercd = E_NOMEM; } else { p_tcb = ((TCB *) queue_delete_next(&free_tcb)); p_tinib = (TINIB *)(p_tcb->p_tinib); p_tinib->tskatr = tskatr; p_tinib->exinf = pk_ctsk->exinf; p_tinib->task = task; p_tinib->ipriority = INT_PRIORITY(itskpri); #ifdef USE_TSKINICTXB init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk); #else /* USE_TSKINICTXB */ p_tinib->stksz = stksz; p_tinib->stk = stk; #endif /* USE_TSKINICTXB */ p_tcb->actque = false; make_dormant(p_tcb); if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) { make_active(p_tcb); } ercd = TSKID(p_tcb); } } unlock_cpu(); error_exit: LOG_ACRE_TSK_LEAVE(ercd); return(ercd); }
/* * Create fixed size memory pool */ SYSCALL ID tk_cre_mpf_impl( T_CMPF *pk_cmpf ) { #if CHK_RSATR const ATR VALID_MPFATR = { TA_TPRI |TA_RNG3 |TA_USERBUF #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif MPFCB *mpfcb; ID mpfid; W blfsz, mpfsz; VP mempool; CHECK_RSATR(pk_cmpf->mpfatr, VALID_MPFATR); CHECK_PAR(pk_cmpf->mpfcnt > 0); CHECK_PAR(pk_cmpf->blfsz > 0); #if !USE_IMALLOC /* TA_USERBUF must be specified if configured in no Imalloc */ CHECK_PAR((pk_cmpf->mpfatr & TA_USERBUF) != 0); #endif CHECK_DISPATCH(); blfsz = (W)MINSZ(pk_cmpf->blfsz); mpfsz = blfsz * pk_cmpf->mpfcnt; #if USE_IMALLOC if ( (pk_cmpf->mpfatr & TA_USERBUF) != 0 ) { /* Size of user buffer must be multiples of sizeof(FREEL) */ if ( blfsz != pk_cmpf->blfsz ) { return E_PAR; } /* Use user buffer */ mempool = pk_cmpf->bufptr; } else { /* Allocate memory for memory pool */ mempool = knl_Imalloc((UW)mpfsz); if ( mempool == NULL ) { return E_NOMEM; } } #else /* Size of user buffer must be larger than sizeof(FREEL) */ if ( blfsz != pk_cmpf->blfsz ) { return E_PAR; } /* Use user buffer */ mempool = pk_cmpf->bufptr; #endif /* Get control block from FreeQue */ DISABLE_INTERRUPT; mpfcb = (MPFCB*)QueRemoveNext(&knl_free_mpfcb); ENABLE_INTERRUPT; if ( mpfcb == NULL ) { #if USE_IMALLOC if ( (pk_cmpf->mpfatr & TA_USERBUF) == 0 ) { knl_Ifree(mempool); } #endif return E_LIMIT; } knl_LockOBJ(&mpfcb->lock); mpfid = ID_MPF(mpfcb - knl_mpfcb_table); /* Initialize control block */ QueInit(&mpfcb->wait_queue); mpfcb->exinf = pk_cmpf->exinf; mpfcb->mpfatr = pk_cmpf->mpfatr; mpfcb->mpfcnt = mpfcb->frbcnt = pk_cmpf->mpfcnt; mpfcb->blfsz = blfsz; mpfcb->mpfsz = mpfsz; mpfcb->unused = mpfcb->mempool = mempool; mpfcb->freelist = NULL; #if USE_OBJECT_NAME if ( (pk_cmpf->mpfatr & TA_DSNAME) != 0 ) { strncpy((char*)mpfcb->name, (char*)pk_cmpf->dsname, OBJECT_NAME_LENGTH); } #endif mpfcb->mpfid = mpfid; /* Set ID after completion */ knl_UnlockOBJ(&mpfcb->lock); return mpfid; }
/* * Create task */ SYSCALL ID tk_cre_tsk_impl P1( T_CTSK *pk_ctsk ) { #if CHK_RSATR const ATR VALID_TSKATR = { /* Valid value of task attribute */ TA_HLNG |TA_RNG3 |TA_USERBUF |TA_GP #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif TCB *tcb; W sstksz; VP stack; ER ercd; CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR); #if !USE_IMALLOC /* TA_USERBUF must be specified if configured in no Imalloc */ CHECK_PAR((pk_ctsk->tskatr & TA_USERBUF) != 0); #endif CHECK_PRI(pk_ctsk->itskpri); CHECK_PAR(pk_ctsk->stksz >= MIN_SYS_STACK_SIZE); /* Adjust stack size by 8 bytes */ sstksz = (pk_ctsk->stksz + 7) / 8 * 8; #if USE_IMALLOC if ( (pk_ctsk->tskatr & TA_USERBUF) != 0 ) { /* Size of User buffer must be multiples of 8 */ if ( sstksz != pk_ctsk->stksz ) { return E_PAR; } /* Use user buffer */ stack = pk_ctsk->bufptr; } else { /* Allocate system stack area */ stack = knl_Imalloc((UW)sstksz); if ( stack == NULL ) { return E_NOMEM; } } #else /* Size of User buffer must be multiples of 8 */ if ( sstksz != pk_ctsk->stksz ) { return E_PAR; } /* Use user buffer */ stack = pk_ctsk->bufptr; #endif BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ tcb = (TCB*)QueRemoveNext(&knl_free_tcb); if ( tcb == NULL ) { ercd = E_LIMIT; goto error_exit; } /* Initialize control block */ tcb->exinf = pk_ctsk->exinf; tcb->tskatr = pk_ctsk->tskatr & ~TA_RNG3; /* handling as TA_RNG0 */ tcb->task = pk_ctsk->task; tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri); tcb->sstksz = sstksz; #if USE_OBJECT_NAME if ( (pk_ctsk->tskatr & TA_DSNAME) != 0 ) { strncpy((char*)tcb->name, (char*)pk_ctsk->dsname, OBJECT_NAME_LENGTH); } #endif #if TA_GP /* Set global pointer */ if ( (pk_ctsk->tskatr & TA_GP) != 0 ) { gp = pk_ctsk->gp; } tcb->gp = gp; #endif /* Set stack pointer */ tcb->isstack = (VB*)stack + sstksz; /* Set initial value of task operation mode */ tcb->isysmode = 1; tcb->sysmode = 1; /* make it to DORMANT state */ knl_make_dormant(tcb); ercd = tcb->tskid; error_exit: END_CRITICAL_SECTION; #if USE_IMALLOC if ( (ercd < E_OK) && ((pk_ctsk->tskatr & TA_USERBUF) == 0) ) { knl_Ifree(stack); } #endif return ercd; }
/* * Interrupt handler definition */ SYSCALL ER _tk_def_int( UINT dintno, T_DINT *pk_dint ) { FP inthdr; INT vecno = dintno >> 5; INTMASKTBL *ptr; CHECK_PAR(vecno < MAX_INTVEC); if ( pk_dint != NULL ) { /* Set interrupt handler */ if ( vecno == VECNO_TLBMISS ) { CHECK_RSATR(pk_dint->intatr, 0); } else { CHECK_RSATR(pk_dint->intatr, TA_HLNG | TA_ASSPRC); } #if CHK_PAR if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) { if ( !chk_assprc(pk_dint->assprc) ) { return E_PAR; } } #endif inthdr = pk_dint->inthdr; BEGIN_CRITICAL_SECTION; if ( (pk_dint->intatr & TA_HLNG) != 0 ) { hll_inthdr[vecno] = inthdr; inthdr = ( vecno == VECNO_DEFAULT )? defaulthdr_startup: inthdr_startup; } define_inthdr(vecno, inthdr); if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) { if ( vecno < N_INTVEC) { ptr = &intmasktable[vecno]; if ( ptr->mask != 0) { if ( pk_dint->assprc & TP_PRC1 ) { out_w(ptr->maskaddr[1], in_w(ptr->maskaddr[1]) | ptr->mask); out_w(clraddr(ptr->maskaddr[0]), ptr->mask); } else if ( pk_dint->assprc & TP_PRC2 ) { out_w(ptr->maskaddr[0], in_w(ptr->maskaddr[0]) | ptr->mask); out_w(clraddr(ptr->maskaddr[1]), ptr->mask); } } } } END_CRITICAL_NO_DISPATCH; } else { /* Free interrupt handler */ switch ( vecno ) { case VECNO_TRAPA: inthdr = SaveMonHdr.trapa_hdr; break; case VECNO_BREAK: inthdr = SaveMonHdr.break_hdr; break; case VECNO_MONITOR: inthdr = SaveMonHdr.monitor_hdr; break; case VECNO_DEFAULT: inthdr = SaveMonHdr.default_hdr; break; case VECNO_TLBMISS: inthdr = SaveMonHdr.tlbmiss_hdr; break; default: inthdr = NULL; } BEGIN_CRITICAL_SECTION; define_inthdr(vecno, inthdr); if ( vecno < MAX_INTVEC ) { hll_inthdr[vecno] = NULL; } if ( vecno < N_INTVEC) { ptr = &intmasktable[vecno]; if ( ptr->mask != 0) { out_w(ptr->maskaddr[0], in_w(ptr->maskaddr[0]) | ptr->mask); out_w(ptr->maskaddr[1], in_w(ptr->maskaddr[1]) | ptr->mask); } } END_CRITICAL_NO_DISPATCH; } return E_OK; }
ER_UINT acre_sem(const T_CSEM *pk_csem) { SEMCB *p_semcb; SEMINIB *p_seminib; ATR sematr; uint_t isemcnt, maxsem; ID domid; const DOMINIB *p_dominib; ACPTN acptn; ER ercd; LOG_ACRE_SEM_ENTER(pk_csem); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_csem, T_CSEM); sematr = pk_csem->sematr; isemcnt = pk_csem->isemcnt; maxsem = pk_csem->maxsem; CHECK_VALIDATR(sematr, TA_TPRI|TA_DOMMASK); CHECK_PAR(0 <= isemcnt && isemcnt <= maxsem); CHECK_PAR(1 <= maxsem && maxsem <= TMAX_MAXSEM); domid = get_atrdomid(sematr); if (domid == TDOM_SELF) { if (rundom == TACP_KERNEL) { domid = TDOM_KERNEL; } else { domid = p_runtsk->p_tinib->domid; } sematr = set_atrdomid(sematr, domid); } switch (domid) { case TDOM_KERNEL: p_dominib = &dominib_kernel; break; case TDOM_NONE: p_dominib = &dominib_none; break; default: CHECK_RSATR(VALID_DOMID(domid)); p_dominib = get_dominib(domid); break; } CHECK_ACPTN(p_dominib->acvct.acptn1); lock_cpu(); if (tnum_sem == 0 || queue_empty(&(p_dominib->p_domcb->free_semcb))) { ercd = E_NOID; } else { p_semcb = (SEMCB *) queue_delete_next(&(p_dominib->p_domcb->free_semcb)); p_seminib = (SEMINIB *)(p_semcb->p_seminib); p_seminib->sematr = sematr; p_seminib->isemcnt = isemcnt; p_seminib->maxsem = maxsem; acptn = default_acptn(domid); p_seminib->acvct.acptn1 = acptn; p_seminib->acvct.acptn2 = acptn; p_seminib->acvct.acptn3 = p_dominib->acvct.acptn1; p_seminib->acvct.acptn4 = acptn; queue_initialize(&(p_semcb->wait_queue)); p_semcb->semcnt = isemcnt; ercd = SEMID(p_semcb); } unlock_cpu(); error_exit: LOG_ACRE_SEM_LEAVE(ercd); return(ercd); }