예제 #1
0
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);
}
예제 #2
0
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);
}