ER ini_mpf(ID mpfid) { MPFCB *p_mpfcb; bool_t dspreq; ER ercd; LOG_INI_MPF_ENTER(mpfid); CHECK_TSKCTX_UNL(); CHECK_MPFID(mpfid); p_mpfcb = get_mpfcb(mpfid); t_lock_cpu(); dspreq = init_wait_queue(&(p_mpfcb->wait_queue)); p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt; p_mpfcb->unused = 0U; p_mpfcb->freelist = INDEX_NULL; if (dspreq) { dispatch(); } ercd = E_OK; t_unlock_cpu(); error_exit: LOG_INI_MPF_LEAVE(ercd); return(ercd); }
ER get_mpf(ID mpfid, void **p_blk) { MPFCB *p_mpfcb; WINFO_MPF winfo_mpf; ER ercd; LOG_GET_MPF_ENTER(mpfid, p_blk); CHECK_DISPATCH(); CHECK_MPFID(mpfid); p_mpfcb = get_mpfcb(mpfid); t_lock_cpu(); if (p_mpfcb->fblkcnt > 0) { get_mpf_block(p_mpfcb, p_blk); ercd = E_OK; } else { p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF); wobj_make_wait((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf); dispatch(); ercd = winfo_mpf.winfo.wercd; if (ercd == E_OK) { *p_blk = winfo_mpf.blk; } } t_unlock_cpu(); error_exit: LOG_GET_MPF_LEAVE(ercd, *p_blk); return(ercd); }
ER pget_mpf(ID mpfid, void **p_blk) { MPFCB *p_mpfcb; ER ercd; LOG_PGET_MPF_ENTER(mpfid, p_blk); CHECK_TSKCTX_UNL(); CHECK_MPFID(mpfid); p_mpfcb = get_mpfcb(mpfid); t_lock_cpu(); if (p_mpfcb->fblkcnt > 0) { get_mpf_block(p_mpfcb, p_blk); ercd = E_OK; } else { ercd = E_TMOUT; } t_unlock_cpu(); error_exit: LOG_PGET_MPF_LEAVE(ercd, *p_blk); return(ercd); }
/* * Refer fixed size memory wait queue */ SYSCALL INT td_mpf_que_impl( ID mpfid, ID list[], INT nent ) { MPFCB *mpfcb; QUEUE *q; ER ercd = E_OK; CHECK_MPFID(mpfid); mpfcb = get_mpfcb(mpfid); BEGIN_DISABLE_INTERRUPT; if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; } else { INT n = 0; for ( q = mpfcb->wait_queue.next; q != &mpfcb->wait_queue; q = q->next ) { if ( n++ < nent ) { *list++ = ((TCB*)q)->tskid; } } ercd = n; } END_DISABLE_INTERRUPT; return ercd; }
/* * Get fixed size memory block */ SYSCALL ER tk_get_mpf_impl( ID mpfid, VP *p_blf, TMO tmout ) { MPFCB *mpfcb; FREEL *free; ER ercd = E_OK; CHECK_MPFID(mpfid); CHECK_TMOUT(tmout); CHECK_DISPATCH(); mpfcb = get_mpfcb(mpfid); knl_LockOBJ(&mpfcb->lock); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; goto error_exit; } /* If there is no space, ready for wait */ if ( mpfcb->frbcnt <= 0 ) { goto wait_mpf; } else { /* Get memory block */ if ( mpfcb->freelist != NULL ) { free = mpfcb->freelist; mpfcb->freelist = free->next; *p_blf = free; } else { *p_blf = mpfcb->unused; mpfcb->unused = (VB*)mpfcb->unused + mpfcb->blfsz; } mpfcb->frbcnt--; } error_exit: knl_UnlockOBJ(&mpfcb->lock); return ercd; wait_mpf: /* Ready for wait */ BEGIN_CRITICAL_SECTION; knl_ctxtsk->wspec = ( (mpfcb->mpfatr & TA_TPRI) != 0 )? &knl_wspec_mpf_tpri: &knl_wspec_mpf_tfifo; knl_ctxtsk->wercd = &ercd; knl_ctxtsk->winfo.mpf.p_blf = p_blf; knl_gcb_make_wait((GCB*)mpfcb, tmout); knl_UnlockOBJ(&mpfcb->lock); END_CRITICAL_SECTION; return ercd; }
/* * Return fixed size memory block */ SYSCALL ER tk_rel_mpf_impl( ID mpfid, VP blf ) { MPFCB *mpfcb; TCB *tcb; FREEL *free; ER ercd = E_OK; CHECK_MPFID(mpfid); CHECK_DISPATCH(); mpfcb = get_mpfcb(mpfid); knl_LockOBJ(&mpfcb->lock); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( blf < mpfcb->mempool || blf >= knl_mempool_end(mpfcb) || (((VB*)blf - (VB*)mpfcb->mempool) % mpfcb->blfsz) != 0 ) { ercd = E_PAR; goto error_exit; } #endif DISABLE_INTERRUPT; if ( !isQueEmpty(&mpfcb->wait_queue) ) { /* Send memory block to waiting task, and then release the task */ tcb = (TCB*)mpfcb->wait_queue.next; *tcb->winfo.mpf.p_blf = blf; knl_wait_release_ok(tcb); ENABLE_INTERRUPT; } else { ENABLE_INTERRUPT; /* Free memory block */ free = (FREEL*)blf; free->next = mpfcb->freelist; mpfcb->freelist = free; mpfcb->frbcnt++; } error_exit: knl_UnlockOBJ(&mpfcb->lock); return ercd; }
ER rel_mpf(ID mpfid, void *blk) { MPFCB *p_mpfcb; SIZE blkoffset; uint_t blkidx; TCB *p_tcb; ER ercd; LOG_REL_MPF_ENTER(mpfid, blk); CHECK_TSKCTX_UNL(); CHECK_MPFID(mpfid); p_mpfcb = get_mpfcb(mpfid); CHECK_PAR(p_mpfcb->p_mpfinib->mpf <= blk); blkoffset = ((char *) blk) - (char *)(p_mpfcb->p_mpfinib->mpf); CHECK_PAR(blkoffset % p_mpfcb->p_mpfinib->blksz == 0U); CHECK_PAR(blkoffset / p_mpfcb->p_mpfinib->blksz < p_mpfcb->unused); blkidx = (uint_t)(blkoffset / p_mpfcb->p_mpfinib->blksz); CHECK_PAR((p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next == INDEX_ALLOC); t_lock_cpu(); if (!queue_empty(&(p_mpfcb->wait_queue))) { p_tcb = (TCB *) queue_delete_next(&(p_mpfcb->wait_queue)); ((WINFO_MPF *)(p_tcb->p_winfo))->blk = blk; if (wait_complete(p_tcb)) { dispatch(); } ercd = E_OK; } else { p_mpfcb->fblkcnt++; (p_mpfcb->p_mpfinib->p_mpfmb + blkidx)->next = p_mpfcb->freelist; p_mpfcb->freelist = blkidx; ercd = E_OK; } t_unlock_cpu(); error_exit: LOG_REL_MPF_LEAVE(ercd); return(ercd); }
ER ref_mpf(ID mpfid, T_RMPF *pk_rmpf) { MPFCB *p_mpfcb; ER ercd; LOG_REF_MPF_ENTER(mpfid, pk_rmpf); CHECK_TSKCTX_UNL(); CHECK_MPFID(mpfid); p_mpfcb = get_mpfcb(mpfid); t_lock_cpu(); pk_rmpf->wtskid = wait_tskid(&(p_mpfcb->wait_queue)); pk_rmpf->fblkcnt = p_mpfcb->fblkcnt; ercd = E_OK; t_unlock_cpu(); error_exit: LOG_REF_MPF_LEAVE(ercd, pk_rmpf); return(ercd); }
ER tget_mpf(ID mpfid, void **p_blk, TMO tmout) { MPFCB *p_mpfcb; WINFO_MPF winfo_mpf; TMEVTB tmevtb; ER ercd; LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout); CHECK_DISPATCH(); CHECK_MPFID(mpfid); CHECK_TMOUT(tmout); p_mpfcb = get_mpfcb(mpfid); t_lock_cpu(); if (p_mpfcb->fblkcnt > 0) { get_mpf_block(p_mpfcb, p_blk); ercd = E_OK; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { p_runtsk->tstat = (TS_WAITING | TS_WAIT_MPF); wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf, &tmevtb, tmout); dispatch(); ercd = winfo_mpf.winfo.wercd; if (ercd == E_OK) { *p_blk = winfo_mpf.blk; } } t_unlock_cpu(); error_exit: LOG_TGET_MPF_LEAVE(ercd, *p_blk); return(ercd); }
/* * Delete fixed size memory pool */ SYSCALL ER tk_del_mpf_impl( ID mpfid ) { MPFCB *mpfcb; VP mempool = NULL; ATR memattr = 0; ER ercd = E_OK; CHECK_MPFID(mpfid); CHECK_DISPATCH(); mpfcb = get_mpfcb(mpfid); knl_LockOBJ(&mpfcb->lock); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; } else { DISABLE_INTERRUPT; mempool = mpfcb->mempool; memattr = mpfcb->mpfatr; /* Release wait state of task (E_DLT) */ knl_wait_delete(&mpfcb->wait_queue); /* Return to FreeQue */ QueInsert(&mpfcb->wait_queue, &knl_free_mpfcb); mpfcb->mpfid = 0; ENABLE_INTERRUPT; } knl_UnlockOBJ(&mpfcb->lock); #if USE_IMALLOC if ( (mempool != NULL) && ((memattr & TA_USERBUF) == 0) ) { knl_Ifree(mempool); } #endif return ercd; }
/* * Refer fixed size memory pool state */ SYSCALL ER td_ref_mpf_impl( ID mpfid, TD_RMPF *pk_rmpf ) { MPFCB *mpfcb; ER ercd = E_OK; CHECK_MPFID(mpfid); mpfcb = get_mpfcb(mpfid); BEGIN_DISABLE_INTERRUPT; if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; } else if ( knl_isLockedOBJ(&mpfcb->lock) ) { ercd = E_CTX; } else { pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue); pk_rmpf->exinf = mpfcb->exinf; pk_rmpf->frbcnt = mpfcb->frbcnt; } END_DISABLE_INTERRUPT; return ercd; }
/* * Get object name from control block */ EXPORT ER knl_fix_memorypool_getname(ID id, UB **name) { MPFCB *mpfcb; ER ercd = E_OK; CHECK_MPFID(id); BEGIN_DISABLE_INTERRUPT; mpfcb = get_mpfcb(id); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; goto error_exit; } if ( (mpfcb->mpfatr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = mpfcb->name; error_exit: END_DISABLE_INTERRUPT; return ercd; }
/* * Check fixed size pool state */ SYSCALL ER tk_ref_mpf_impl( ID mpfid, T_RMPF *pk_rmpf ) { MPFCB *mpfcb; ER ercd = E_OK; CHECK_MPFID(mpfid); CHECK_DISPATCH(); mpfcb = get_mpfcb(mpfid); knl_LockOBJ(&mpfcb->lock); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; } else { DISABLE_INTERRUPT; pk_rmpf->wtsk = knl_wait_tskid(&mpfcb->wait_queue); ENABLE_INTERRUPT; pk_rmpf->exinf = mpfcb->exinf; pk_rmpf->frbcnt = mpfcb->frbcnt; } knl_UnlockOBJ(&mpfcb->lock); return ercd; }