ER_UINT acre_sem(const T_CSEM *pk_csem) { SEMCB *p_semcb; SEMINIB *p_seminib; ER ercd; LOG_ACRE_SEM_ENTER(pk_csem); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_csem->sematr, TA_TPRI); CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem); CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM); t_lock_cpu(); if (tnum_sem == 0 || queue_empty(&free_semcb)) { ercd = E_NOID; } else { p_semcb = ((SEMCB *) queue_delete_next(&free_semcb)); p_seminib = (SEMINIB *)(p_semcb->p_seminib); p_seminib->sematr = pk_csem->sematr; p_seminib->isemcnt = pk_csem->isemcnt; p_seminib->maxsem = pk_csem->maxsem; queue_initialize(&(p_semcb->wait_queue)); p_semcb->semcnt = p_semcb->p_seminib->isemcnt; ercd = SEMID(p_semcb); } t_unlock_cpu(); error_exit: LOG_ACRE_SEM_LEAVE(ercd); return(ercd); }
ER_UINT acre_alm(const T_CALM *pk_calm) { ALMCB *p_almcb; ALMINIB *p_alminib; ER ercd; LOG_ACRE_ALM_ENTER(pk_calm); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_calm->almatr, TA_NULL); CHECK_ALIGN_FUNC(pk_calm->almhdr); CHECK_NONNULL_FUNC(pk_calm->almhdr); t_lock_cpu(); if (tnum_alm == 0 || queue_empty(&free_almcb)) { ercd = E_NOID; } else { p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb)) - offsetof(ALMCB, tmevtb))); p_alminib = (ALMINIB *)(p_almcb->p_alminib); p_alminib->almatr = pk_calm->almatr; p_alminib->exinf = pk_calm->exinf; p_alminib->almhdr = pk_calm->almhdr; p_almcb->almsta = false; ercd = ALMID(p_almcb); } t_unlock_cpu(); error_exit: LOG_ACRE_ALM_LEAVE(ercd); return(ercd); }
ER_UINT acre_flg(const T_CFLG *pk_cflg) { FLGCB *p_flgcb; FLGINIB *p_flginib; ER ercd; LOG_ACRE_FLG_ENTER(pk_cflg); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR); t_lock_cpu(); if (tnum_flg == 0 || queue_empty(&free_flgcb)) { ercd = E_NOID; } else { p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb)); p_flginib = (FLGINIB *)(p_flgcb->p_flginib); p_flginib->flgatr = pk_cflg->flgatr; p_flginib->iflgptn = pk_cflg->iflgptn; queue_initialize(&(p_flgcb->wait_queue)); p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn; ercd = FLGID(p_flgcb); } t_unlock_cpu(); error_exit: LOG_ACRE_FLG_LEAVE(ercd); return(ercd); }
/* * Interrupt handler definition */ SYSCALL ER _tk_def_int( UINT dintno, T_DINT *pk_dint ) { FP inthdr; CHECK_PAR(dintno < N_INTVEC); if ( pk_dint != NULL ) { /* Set interrupt handler */ CHECK_RSATR(pk_dint->intatr, TA_HLNG|TA_ASSPRC); #if PSR_DI == PSR_I CHECK_PAR( !(dintno == EIT_FIQ && (pk_dint->intatr & TA_HLNG) != 0) ); #endif #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[dintno] = inthdr; inthdr = ( dintno == EIT_DEFAULT )? defaulthdr_startup: ( dintno < IRQVEC_TOP )? exchdr_startup: ( dintno <= IRQVEC_END )? inthdr_startup: exchdr_startup; } define_inthdr(dintno, inthdr); /* Set cpu target */ if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) { SetIntAssprc(dintno, pk_dint->assprc); } else { SetIntAssprc(dintno, 1 << get_prid()); } END_CRITICAL_NO_DISPATCH; } else { /* Clear interrupt handler */ switch ( dintno ) { case VECNO_DEFAULT: inthdr = SaveMonHdr.default_hdr; break; case VECNO_BREAK: inthdr = SaveMonHdr.break_hdr; break; case VECNO_MONITOR: inthdr = SaveMonHdr.monitor_hdr; break; default: inthdr = NULL; } BEGIN_CRITICAL_SECTION; /* Clear cpu target */ ClrIntAssprc(dintno); define_inthdr(dintno, inthdr); hll_inthdr[dintno] = NULL; END_CRITICAL_NO_DISPATCH; } return E_OK; }
/* * Create mutex */ SYSCALL ID _tk_cre_mtx( CONST T_CMTX *pk_cmtx ) { #if CHK_RSATR const ATR VALID_MTXATR = { TA_CEILING |TA_NODISWAI #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif MTXCB *mtxcb; ID mtxid; INT ceilpri; ER ercd; CHECK_RSATR(pk_cmtx->mtxatr, VALID_MTXATR); if ( (pk_cmtx->mtxatr & TA_CEILING) == TA_CEILING ) { CHECK_PRI(pk_cmtx->ceilpri); ceilpri = int_priority(pk_cmtx->ceilpri); } else { ceilpri = 0; } BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ mtxcb = (MTXCB*)QueRemoveNext(&free_mtxcb); if ( mtxcb == NULL ) { ercd = E_LIMIT; } else { mtxid = ID_MTX(mtxcb - mtxcb_table); /* Initialize control block */ QueInit(&mtxcb->wait_queue); mtxcb->mtxid = mtxid; mtxcb->exinf = pk_cmtx->exinf; mtxcb->mtxatr = pk_cmtx->mtxatr; mtxcb->ceilpri = ceilpri; mtxcb->mtxtsk = NULL; mtxcb->mtxlist = NULL; #if USE_OBJECT_NAME if ( (pk_cmtx->mtxatr & TA_DSNAME) != 0 ) { strncpy((char*)mtxcb->name, (char*)pk_cmtx->dsname, (UINT)OBJECT_NAME_LENGTH); } #endif ercd = mtxid; } END_CRITICAL_SECTION; return ercd; }
ER_UINT acre_pdq(const T_CPDQ *pk_cpdq) { PDQCB *p_pdqcb; PDQINIB *p_pdqinib; ATR pdqatr; PDQMB *p_pdqmb; ER ercd; LOG_ACRE_PDQ_ENTER(pk_cpdq); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI); CHECK_DPRI(pk_cpdq->maxdpri); pdqatr = pk_cpdq->pdqatr; p_pdqmb = pk_cpdq->pdqmb; t_lock_cpu(); if (queue_empty(&free_pdqcb)) { ercd = E_NOID; } else { if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) { p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt); pdqatr |= TA_MBALLOC; } if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) { ercd = E_NOMEM; } else { p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb)); p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib); p_pdqinib->pdqatr = pdqatr; p_pdqinib->pdqcnt = pk_cpdq->pdqcnt; p_pdqinib->maxdpri = pk_cpdq->maxdpri; p_pdqinib->p_pdqmb = p_pdqmb; queue_initialize(&(p_pdqcb->swait_queue)); queue_initialize(&(p_pdqcb->rwait_queue)); p_pdqcb->count = 0U; p_pdqcb->p_head = NULL; p_pdqcb->unused = 0U; p_pdqcb->p_freelist = NULL; ercd = PDQID(p_pdqcb); } } t_unlock_cpu(); error_exit: LOG_ACRE_PDQ_LEAVE(ercd); return(ercd); }
ER_UINT acre_isr(const T_CISR *pk_cisr) { ISRCB *p_isrcb; ISRINIB *p_isrinib; QUEUE *p_isr_queue; ER ercd; LOG_ACRE_ISR_ENTER(pk_cisr); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_cisr, T_CISR); CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR|TA_DOMMASK); CHECK_ATRDOMID_KERNEL(get_atrdomid(pk_cisr->isratr)); CHECK_INTNO_CREISR(pk_cisr->intno); CHECK_ALIGN_FUNC(pk_cisr->isr); CHECK_NONNULL_FUNC(pk_cisr->isr); CHECK_ISRPRI(pk_cisr->isrpri); CHECK_ACPTN(sysstat_acvct.acptn3); p_isr_queue = search_isr_queue(pk_cisr->intno); CHECK_OBJ(p_isr_queue != NULL); t_lock_cpu(); if (tnum_isr == 0 || queue_empty(&free_isrcb)) { ercd = E_NOID; } else { p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb)); p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib); p_isrinib->isratr = pk_cisr->isratr; p_isrinib->exinf = pk_cisr->exinf; p_isrinib->intno = pk_cisr->intno; p_isrinib->p_isr_queue = p_isr_queue; p_isrinib->isr = pk_cisr->isr; p_isrinib->isrpri = pk_cisr->isrpri; p_isrinib->acvct.acptn1 = TACP_KERNEL; p_isrinib->acvct.acptn2 = TACP_KERNEL; p_isrinib->acvct.acptn3 = TACP_KERNEL | rundom; p_isrinib->acvct.acptn4 = TACP_KERNEL; enqueue_isr(p_isr_queue, p_isrcb); ercd = ISRID(p_isrcb); } t_unlock_cpu(); error_exit: LOG_ACRE_ISR_LEAVE(ercd); return(ercd); }
ER_UINT acre_dtq(const T_CDTQ *pk_cdtq) { DTQCB *p_dtqcb; DTQINIB *p_dtqinib; ATR dtqatr; DTQMB *p_dtqmb; ER ercd; LOG_ACRE_DTQ_ENTER(pk_cdtq); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_cdtq->dtqatr, TA_TPRI); dtqatr = pk_cdtq->dtqatr; p_dtqmb = pk_cdtq->dtqmb; t_lock_cpu(); if (queue_empty(&free_dtqcb)) { ercd = E_NOID; } else { if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) { p_dtqmb = kernel_malloc(sizeof(DTQMB) * pk_cdtq->dtqcnt); dtqatr |= TA_MBALLOC; } if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) { ercd = E_NOMEM; } else { p_dtqcb = ((DTQCB *) queue_delete_next(&free_dtqcb)); p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib); p_dtqinib->dtqatr = dtqatr; p_dtqinib->dtqcnt = pk_cdtq->dtqcnt; p_dtqinib->p_dtqmb = p_dtqmb; queue_initialize(&(p_dtqcb->swait_queue)); queue_initialize(&(p_dtqcb->rwait_queue)); p_dtqcb->count = 0U; p_dtqcb->head = 0U; p_dtqcb->tail = 0U; ercd = DTQID(p_dtqcb); } } t_unlock_cpu(); error_exit: LOG_ACRE_DTQ_LEAVE(ercd); return(ercd); }
/* * Create rendezvous port */ SYSCALL ID _tk_cre_por( CONST T_CPOR *pk_cpor ) { #if CHK_RSATR const ATR VALID_PORATR = { TA_TPRI |TA_NODISWAI #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif PORCB *porcb; ID porid; ER ercd; CHECK_RSATR(pk_cpor->poratr, VALID_PORATR); CHECK_PAR(pk_cpor->maxcmsz >= 0); CHECK_PAR(pk_cpor->maxrmsz >= 0); CHECK_INTSK(); BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ porcb = (PORCB*)QueRemoveNext(&free_porcb); if ( porcb == NULL ) { ercd = E_LIMIT; } else { porid = ID_POR(porcb - porcb_table); /* Initialize control block */ QueInit(&porcb->call_queue); porcb->porid = porid; porcb->exinf = pk_cpor->exinf; porcb->poratr = pk_cpor->poratr; QueInit(&porcb->accept_queue); porcb->maxcmsz = pk_cpor->maxcmsz; porcb->maxrmsz = pk_cpor->maxrmsz; #if USE_OBJECT_NAME if ( (pk_cpor->poratr & TA_DSNAME) != 0 ) { strncpy((char*)porcb->name, (char*)pk_cpor->dsname, OBJECT_NAME_LENGTH); } #endif ercd = porid; } END_CRITICAL_SECTION; return ercd; }
/* * Create semaphore */ SYSCALL ID tk_cre_sem_impl( T_CSEM *pk_csem ) { #if CHK_RSATR const ATR VALID_SEMATR = { TA_TPRI |TA_CNT #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif SEMCB *semcb; ID semid; ER ercd; CHECK_RSATR(pk_csem->sematr, VALID_SEMATR); CHECK_PAR(pk_csem->isemcnt >= 0); CHECK_PAR(pk_csem->maxsem > 0); CHECK_PAR(pk_csem->maxsem >= pk_csem->isemcnt); BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ semcb = (SEMCB*)QueRemoveNext(&knl_free_semcb); if ( semcb == NULL ) { ercd = E_LIMIT; } else { semid = ID_SEM(semcb - knl_semcb_table); /* Initialize control block */ QueInit(&semcb->wait_queue); semcb->semid = semid; semcb->exinf = pk_csem->exinf; semcb->sematr = pk_csem->sematr; semcb->semcnt = pk_csem->isemcnt; semcb->maxsem = pk_csem->maxsem; #if USE_OBJECT_NAME if ( (pk_csem->sematr & TA_DSNAME) != 0 ) { strncpy((char*)semcb->name, (char*)pk_csem->dsname, OBJECT_NAME_LENGTH); } #endif ercd = semid; } END_CRITICAL_SECTION; return ercd; }
ER_UINT acre_sem(const T_CSEM *pk_csem) { ID domid; SEMCB *p_semcb; SEMINIB *p_seminib; ACPTN acptn; ER ercd; LOG_ACRE_SEM_ENTER(pk_csem); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_csem, T_CSEM); CHECK_RSATR(pk_csem->sematr, TA_TPRI|TA_DOMMASK); domid = get_atrdomid(pk_csem->sematr); CHECK_ATRDOMID_INACTIVE(domid); CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem); CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM); CHECK_ACPTN(sysstat_acvct.acptn3); t_lock_cpu(); if (tnum_sem == 0 || queue_empty(&free_semcb)) { ercd = E_NOID; } else { p_semcb = ((SEMCB *) queue_delete_next(&free_semcb)); p_seminib = (SEMINIB *)(p_semcb->p_seminib); p_seminib->sematr = pk_csem->sematr; p_seminib->isemcnt = pk_csem->isemcnt; p_seminib->maxsem = pk_csem->maxsem; acptn = default_acptn(domid); p_seminib->acvct.acptn1 = acptn; p_seminib->acvct.acptn2 = acptn; p_seminib->acvct.acptn3 = acptn | rundom; p_seminib->acvct.acptn4 = acptn; queue_initialize(&(p_semcb->wait_queue)); p_semcb->semcnt = p_semcb->p_seminib->isemcnt; ercd = SEMID(p_semcb); } t_unlock_cpu(); error_exit: LOG_ACRE_SEM_LEAVE(ercd); return(ercd); }
ER_UINT acre_cyc(const T_CCYC *pk_ccyc) { CYCCB *p_cyccb; CYCINIB *p_cycinib; ER ercd; LOG_ACRE_CYC_ENTER(pk_ccyc); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_ccyc->cycatr, TA_STA); CHECK_ALIGN_FUNC(pk_ccyc->cychdr); CHECK_NONNULL_FUNC(pk_ccyc->cychdr); CHECK_PAR(0 < pk_ccyc->cyctim && pk_ccyc->cyctim <= TMAX_RELTIM); CHECK_PAR(0 <= pk_ccyc->cycphs && pk_ccyc->cycphs <= TMAX_RELTIM); t_lock_cpu(); if (tnum_cyc == 0 || queue_empty(&free_cyccb)) { ercd = E_NOID; } else { p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb)) - offsetof(CYCCB, tmevtb))); p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib); p_cycinib->cycatr = pk_ccyc->cycatr; p_cycinib->exinf = pk_ccyc->exinf; p_cycinib->cychdr = pk_ccyc->cychdr; p_cycinib->cyctim = pk_ccyc->cyctim; p_cycinib->cycphs = pk_ccyc->cycphs; if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) { p_cyccb->cycsta = true; tmevtb_enqueue_cyc(p_cyccb, base_time + p_cyccb->p_cycinib->cycphs); } else { p_cyccb->cycsta = false; } ercd = CYCID(p_cyccb); } t_unlock_cpu(); error_exit: LOG_ACRE_CYC_LEAVE(ercd); return(ercd); }
ER_UINT acre_alm(const T_CALM *pk_calm) { ALMCB *p_almcb; ALMINIB *p_alminib; T_NFYINFO *p_nfyinfo; ER ercd, rercd; LOG_ACRE_ALM_ENTER(pk_calm); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_calm->almatr, TA_NULL); rercd = check_nfyinfo(&(pk_calm->nfyinfo)); if (rercd != E_OK) { ercd = rercd; goto error_exit; } lock_cpu(); if (tnum_alm == 0 || queue_empty(&free_almcb)) { ercd = E_NOID; } else { p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb)) - offsetof(ALMCB, tmevtb))); p_alminib = (ALMINIB *)(p_almcb->p_alminib); p_alminib->almatr = pk_calm->almatr; if (pk_calm->nfyinfo.nfymode == TNFY_HANDLER) { p_alminib->exinf = pk_calm->nfyinfo.nfy.handler.exinf; p_alminib->nfyhdr = (NFYHDR)(pk_calm->nfyinfo.nfy.handler.tmehdr); } else { p_nfyinfo = &aalm_nfyinfo_table[p_alminib - aalminib_table]; *p_nfyinfo = pk_calm->nfyinfo; p_alminib->exinf = (intptr_t) p_nfyinfo; p_alminib->nfyhdr = notify_handler; } p_almcb->almsta = false; ercd = ALMID(p_almcb); } unlock_cpu(); error_exit: LOG_ACRE_ALM_LEAVE(ercd); return(ercd); }
/* * Interrupt handler definition */ SYSCALL ER tk_def_int_impl( UINT dintno, T_DINT *pk_dint ) { FP inthdr; CHECK_PAR(dintno < N_INTVEC); #if !USE_HLL_INTHDR CHECK_PAR((pk_dint->intatr & TA_HLNG) == 0); #endif if ( pk_dint != NULL ) { /* Set interrupt handler */ CHECK_RSATR(pk_dint->intatr, TA_HLNG); #if PSR_DI == PSR_I CHECK_PAR( !(dintno == EIT_FIQ && (pk_dint->intatr & TA_HLNG) != 0) ); #endif inthdr = pk_dint->inthdr; BEGIN_CRITICAL_SECTION; #if USE_HLL_INTHDR if ( (pk_dint->intatr & TA_HLNG) != 0 ) { knl_hll_inthdr[dintno] = inthdr; inthdr = (dintno < 32) ? knl_inthdr_startup: knl_exchdr_startup; /* SWI handler */ } #endif knl_define_inthdr(dintno, inthdr); END_CRITICAL_SECTION; } else { /* Clear interrupt handler */ switch ( dintno ) { default: inthdr = NULL; } BEGIN_CRITICAL_SECTION; knl_define_inthdr(dintno, inthdr); #if USE_HLL_INTHDR knl_hll_inthdr[dintno] = NULL; #endif END_CRITICAL_SECTION; } return E_OK; }
/* * Definition of subsystem */ SYSCALL ER tk_def_ssy_impl P2( ID ssid, T_DSSY *pk_dssy ) { SSYCB *ssycb; ER ercd = E_OK; CHECK_SSYID(ssid); #if CHK_RSATR if ( pk_dssy != NULL ) { CHECK_RSATR(pk_dssy->ssyatr, TA_NULL|TA_GP); } #endif ssycb = get_ssycb(ssid); BEGIN_CRITICAL_SECTION; if ( pk_dssy != NULL ) { /* Register */ if ( ssycb->svchdr != knl_no_support ) { ercd = E_OBJ; /* Registered */ goto error_exit; } ssycb->svchdr = (SVC)pk_dssy->svchdr; #if TA_GP if ( (pk_dssy->ssyatr & TA_GP) != 0 ) { gp = pk_dssy->gp; } ssycb->gp = gp; #endif } else { /* Delete */ if ( ssycb->svchdr == knl_no_support ) { ercd = E_NOEXS; /* Not registered */ goto error_exit; } ssycb->svchdr = knl_no_support; } error_exit: END_CRITICAL_SECTION; return ercd; }
/* * Create mailbox */ SYSCALL ID _tk_cre_mbx( CONST T_CMBX *pk_cmbx ) { #if CHK_RSATR const ATR VALID_MBXATR = { TA_MPRI |TA_TPRI |TA_NODISWAI #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif MBXCB *mbxcb; ID mbxid; ER ercd; CHECK_RSATR(pk_cmbx->mbxatr, VALID_MBXATR); BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ mbxcb = (MBXCB*)QueRemoveNext(&free_mbxcb); if ( mbxcb == NULL ) { ercd = E_LIMIT; } else { mbxid = ID_MBX(mbxcb - mbxcb_table); /* Initialize control block */ QueInit(&mbxcb->wait_queue); mbxcb->mbxid = mbxid; mbxcb->exinf = pk_cmbx->exinf; mbxcb->mbxatr = pk_cmbx->mbxatr; mbxcb->mq_head.msgque[0] = NULL; #if USE_OBJECT_NAME if ( (pk_cmbx->mbxatr & TA_DSNAME) != 0 ) { STRNCPY((char*)mbxcb->name, (char*)pk_cmbx->dsname, OBJECT_NAME_LENGTH); } #endif ercd = mbxid; } END_CRITICAL_SECTION; return ercd; }
/* * Create event flag */ SYSCALL ID tk_cre_flg_impl( T_CFLG *pk_cflg ) { #if CHK_RSATR const ATR VALID_FLGATR = { TA_TPRI |TA_WMUL #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif FLGCB *flgcb; ID flgid; ER ercd; CHECK_RSATR(pk_cflg->flgatr, VALID_FLGATR); BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ flgcb = (FLGCB*)QueRemoveNext(&knl_free_flgcb); if ( flgcb == NULL ) { ercd = E_LIMIT; } else { flgid = ID_FLG(flgcb - knl_flgcb_table); /* Initialize control block */ QueInit(&flgcb->wait_queue); flgcb->flgid = flgid; flgcb->exinf = pk_cflg->exinf; flgcb->flgatr = pk_cflg->flgatr; flgcb->flgptn = pk_cflg->iflgptn; #if USE_OBJECT_NAME if ( (pk_cflg->flgatr & TA_DSNAME) != 0 ) { strncpy((char*)flgcb->name, (char*)pk_cflg->dsname, OBJECT_NAME_LENGTH); } #endif ercd = flgid; } END_CRITICAL_SECTION; return ercd; }
ER_UINT acre_flg(const T_CFLG *pk_cflg) { ID domid; FLGCB *p_flgcb; FLGINIB *p_flginib; ACPTN acptn; ER ercd; LOG_ACRE_FLG_ENTER(pk_cflg); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_cflg, T_CFLG); CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR|TA_DOMMASK); domid = get_atrdomid(pk_cflg->flgatr); CHECK_ATRDOMID_INACTIVE(domid); CHECK_ACPTN(sysstat_acvct.acptn3); t_lock_cpu(); if (tnum_flg == 0 || queue_empty(&free_flgcb)) { ercd = E_NOID; } else { p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb)); p_flginib = (FLGINIB *)(p_flgcb->p_flginib); p_flginib->flgatr = pk_cflg->flgatr; p_flginib->iflgptn = pk_cflg->iflgptn; acptn = default_acptn(domid); p_flginib->acvct.acptn1 = acptn; p_flginib->acvct.acptn2 = acptn; p_flginib->acvct.acptn3 = acptn | rundom; p_flginib->acvct.acptn4 = acptn; queue_initialize(&(p_flgcb->wait_queue)); p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn; ercd = FLGID(p_flgcb); } t_unlock_cpu(); error_exit: LOG_ACRE_FLG_LEAVE(ercd); return(ercd); }
ER_UINT acre_isr(const T_CISR *pk_cisr) { ISRCB *p_isrcb; ISRINIB *p_isrinib; QUEUE *p_isr_queue; ER ercd; LOG_ACRE_ISR_ENTER(pk_cisr); CHECK_TSKCTX_UNL(); CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR); CHECK_INTNO_CREISR(pk_cisr->intno); CHECK_ALIGN_FUNC(pk_cisr->isr); CHECK_NONNULL_FUNC(pk_cisr->isr); CHECK_ISRPRI(pk_cisr->isrpri); p_isr_queue = search_isr_queue(pk_cisr->intno); CHECK_OBJ(p_isr_queue != NULL); t_lock_cpu(); if (tnum_isr == 0 || queue_empty(&free_isrcb)) { ercd = E_NOID; } else { p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb)); p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib); p_isrinib->isratr = pk_cisr->isratr; p_isrinib->exinf = pk_cisr->exinf; p_isrinib->intno = pk_cisr->intno; p_isrinib->p_isr_queue = p_isr_queue; p_isrinib->isr = pk_cisr->isr; p_isrinib->isrpri = pk_cisr->isrpri; enqueue_isr(p_isr_queue, p_isrcb); ercd = ISRID(p_isrcb); } t_unlock_cpu(); error_exit: LOG_ACRE_ISR_LEAVE(ercd); return(ercd); }
/* * 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; }
/* * Create message buffer */ SYSCALL ID _tk_cre_mbf( CONST T_CMBF *pk_cmbf ) { #if CHK_RSATR const ATR VALID_MBFATR = { TA_TPRI |TA_NODISWAI #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif MBFCB *mbfcb; ID mbfid; INT bufsz; VB *msgbuf; ER ercd; CHECK_RSATR(pk_cmbf->mbfatr, VALID_MBFATR); CHECK_PAR(pk_cmbf->bufsz >= 0); CHECK_PAR(pk_cmbf->maxmsz > 0); bufsz = (INT)ROUNDSZ(pk_cmbf->bufsz); if ( bufsz > 0 ) { msgbuf = Imalloc((UINT)bufsz); if ( msgbuf == NULL ) { return E_NOMEM; } } else { msgbuf = NULL; } BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ mbfcb = (MBFCB*)QueRemoveNext(&free_mbfcb); if ( mbfcb == NULL ) { ercd = E_LIMIT; } else { mbfid = ID_MBF(mbfcb - mbfcb_table); /* Initialize control block */ QueInit(&mbfcb->send_queue); mbfcb->mbfid = mbfid; mbfcb->exinf = pk_cmbf->exinf; mbfcb->mbfatr = pk_cmbf->mbfatr; QueInit(&mbfcb->recv_queue); mbfcb->buffer = msgbuf; mbfcb->bufsz = mbfcb->frbufsz = bufsz; mbfcb->maxmsz = pk_cmbf->maxmsz; mbfcb->head = mbfcb->tail = 0; #if USE_OBJECT_NAME if ( (pk_cmbf->mbfatr & TA_DSNAME) != 0 ) { strncpy((char*)mbfcb->name, (char*)pk_cmbf->dsname, OBJECT_NAME_LENGTH); } #endif ercd = mbfid; } END_CRITICAL_SECTION; if ( ercd < E_OK && msgbuf != NULL ) { Ifree(msgbuf); } 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 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_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); }
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_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); }
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); }
/* * 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_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); }
ER_UINT acre_pdq(const T_CPDQ *pk_cpdq) { ID domid; PDQCB *p_pdqcb; PDQINIB *p_pdqinib; ATR pdqatr; PDQMB *p_pdqmb; ACPTN acptn; ER ercd; LOG_ACRE_PDQ_ENTER(pk_cpdq); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_cpdq, T_CPDQ); CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI|TA_DOMMASK); domid = get_atrdomid(pk_cpdq->pdqatr); CHECK_ATRDOMID_INACTIVE(domid); CHECK_DPRI(pk_cpdq->maxdpri); if (pk_cpdq->pdqmb != NULL) { CHECK_ALIGN_MB(pk_cpdq->pdqmb); CHECK_OBJ(valid_memobj_kernel(pk_cpdq->pdqmb, sizeof(PDQMB) * pk_cpdq->pdqcnt)); } CHECK_ACPTN(sysstat_acvct.acptn3); pdqatr = pk_cpdq->pdqatr; p_pdqmb = pk_cpdq->pdqmb; t_lock_cpu(); if (tnum_pdq == 0 || queue_empty(&free_pdqcb)) { ercd = E_NOID; } else { if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) { p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt); pdqatr |= TA_MBALLOC; } if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) { ercd = E_NOMEM; } else { p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb)); p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib); p_pdqinib->pdqatr = pdqatr; p_pdqinib->pdqcnt = pk_cpdq->pdqcnt; p_pdqinib->maxdpri = pk_cpdq->maxdpri; p_pdqinib->p_pdqmb = p_pdqmb; acptn = default_acptn(domid); p_pdqinib->acvct.acptn1 = acptn; p_pdqinib->acvct.acptn2 = acptn; p_pdqinib->acvct.acptn3 = acptn | rundom; p_pdqinib->acvct.acptn4 = acptn; queue_initialize(&(p_pdqcb->swait_queue)); queue_initialize(&(p_pdqcb->rwait_queue)); p_pdqcb->count = 0U; p_pdqcb->p_head = NULL; p_pdqcb->unused = 0U; p_pdqcb->p_freelist = NULL; ercd = PDQID(p_pdqcb); } } t_unlock_cpu(); error_exit: LOG_ACRE_PDQ_LEAVE(ercd); return(ercd); }