Beispiel #1
0
SYSCALL void
ext_tsk(void)
{
	LOG_EXT_TSK_ENTER();

#ifdef ACTIVATED_STACK_SIZE
	/*
	 *  create_context と activate_context で,使用中のスタック領
	 *  域を破壊しないように,スタック上にダミー領域を確保する.
	 */
	(void) alloca(ACTIVATED_STACK_SIZE);
#endif /* ACTIVATED_STACK_SIZE */

	if (sense_context()) {
		/*
		 *  非タスクコンテキストから ext_tsk が呼ばれた場合,
		 *  システムログにエラーを記録し,そのまま実行を続ける
		 *  が, 動作は保証されない.
		 */
		syslog_0(LOG_EMERG,
			"ext_tsk is called from non-task contexts.");
	}
	if (sense_lock()) {
		/*
		 *  CPUロック状態で ext_tsk が呼ばれた場合は,CPUロック
		 *  を解除してからタスクを終了する.実装上は,サービス
		 *  コール内でのCPUロックを省略すればよいだけ.
		 */
		syslog_0(LOG_WARNING,
			"ext_tsk is called from CPU locked state.");
	}
	else {
		if (sense_context()) {
			i_lock_cpu();
		}
		else  {
			t_lock_cpu();
		}
	}
	if (!(enadsp)) {
		/*
		 *  ディスパッチ禁止状態で ext_tsk が呼ばれた場合は,
		 *  ディスパッチ許可状態にしてからタスクを終了する.
		 */
		syslog_0(LOG_WARNING,
			"ext_tsk is called from dispatch disabled state.");
		enadsp = TRUE;
	}
	exit_task();
}
ER
wup_tsk(ID tskid)
{
	TCB		*p_tcb;
	ER		ercd;

	LOG_WUP_TSK_ENTER(tskid);
	CHECK_UNL();
	if (tskid == TSK_SELF && !sense_context()) {
		p_tcb = p_runtsk;
	}
	else {
		CHECK_ID(VALID_TSKID(tskid));
		p_tcb = get_tcb(tskid);
	}

	lock_cpu();
	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (TSTAT_DORMANT(p_tcb->tstat)) {
		ercd = E_OBJ;
	}
	else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
		wait_complete(p_tcb);
		if (p_runtsk != p_schedtsk) {
			if (!sense_context()) {
				dispatch();
			}
			else {
				request_dispatch();
			}
		}
		ercd = E_OK;
	}
	else if (!(p_tcb->wupque)) {
		p_tcb->wupque = true;
		ercd = E_OK;
	}
	else {
		ercd = E_QOVR;
	}
	unlock_cpu();

  error_exit:
	LOG_WUP_TSK_LEAVE(ercd);
	return(ercd);
}
ER
psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
{
	PDQCB	*p_pdqcb;
	ER		ercd;

	LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
	CHECK_UNL();
	CHECK_ID(VALID_PDQID(pdqid));
	p_pdqcb = get_pdqcb(pdqid);
	CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);

	lock_cpu();
	if (send_pridata(p_pdqcb, data, datapri)) {
		if (p_runtsk != p_schedtsk) {
			if (!sense_context()) {
				dispatch();
			}
			else {
				request_dispatch();
			}
		}
		ercd = E_OK;
	}
	else {
		ercd = E_TMOUT;
	}
	unlock_cpu();

  error_exit:
	LOG_PSND_PDQ_LEAVE(ercd);
	return(ercd);
}
ER
act_tsk(ID tskid)
{
	TCB		*p_tcb;
	ER		ercd;

	LOG_ACT_TSK_ENTER(tskid);
	CHECK_UNL();								/*[NGKI1114]*/
	if (tskid == TSK_SELF && !sense_context()) {
		p_tcb = p_runtsk;						/*[NGKI1121]*/
	}
	else {
		CHECK_ID(VALID_TSKID(tskid));			/*[NGKI1115]*/
		p_tcb = get_tcb(tskid);
	}

	lock_cpu();
	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
		ercd = E_NOEXS;							/*[NGKI1116]*/
	}
	else if (TSTAT_DORMANT(p_tcb->tstat)) {
		make_active(p_tcb);						/*[NGKI1118]*/
		if (p_runtsk != p_schedtsk) {
			if (!sense_context()) {
				dispatch();
			}
			else {
				request_dispatch();
			}
		}
		ercd = E_OK;
	}
	else if ((p_tcb->p_tinib->tskatr & TA_NOACTQUE) != 0U || p_tcb->actque) {
		ercd = E_QOVR;			   				/*[NGKI3528]*/
	}
	else {
		p_tcb->actque = true;					/*[NGKI3527]*/
		ercd = E_OK;
	}
	unlock_cpu();

  error_exit:
	LOG_ACT_TSK_LEAVE(ercd);
	return(ercd);
}
Beispiel #5
0
bool_t
sns_dpn(void)
{
	bool_t	state;

	LOG_SNS_DPN_ENTER();
	state = (sense_context() || t_sense_lock() || !dspflg) ? true : false;
	LOG_SNS_DPN_LEAVE(state);
	return(state);
}
Beispiel #6
0
bool_t
sns_ctx(void)
{
	bool_t	state;

	LOG_SNS_CTX_ENTER();
	state = sense_context() ? true : false;
	LOG_SNS_CTX_LEAVE(state);
	return(state);
}
Beispiel #7
0
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;
	PCB		*my_p_pcb;
	TEVTCB	*my_p_tevtcb;

	assert(sense_context());
	assert(!i_sense_lock());

	i_lock_cpu();
	my_p_pcb = i_acquire_tsk_lock_self();

	my_p_tevtcb = my_p_pcb->p_tevtcb;

	/*
	 *  current_timeを更新する.
	 */
	my_p_tevtcb->current_time = my_p_tevtcb->next_time;

	/*
	 *  next_time,next_subtimeを更新する.
	 */
#if TIC_DENO == 1U
	my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME;
#else /* TIC_DENO == 1U */
	my_p_tevtcb->next_subtime += TIC_NUME % TIC_DENO;
	my_p_tevtcb->next_time = my_p_tevtcb->current_time + TIC_NUME / TIC_DENO;
	if (my_p_tevtcb->next_subtime >= TIC_DENO) {
		my_p_tevtcb->next_subtime -= TIC_DENO;
		my_p_tevtcb->next_time += 1U;
	}
#endif /* TIC_DENO == 1U */

	/*
	 *  curent_timeよりイベント発生時刻の早い(または同じ)タイムイベン
	 *  トを,タイムイベントヒープから削除し,コールバック関数を呼び出
	 *  す.
	 */
	while ((my_p_tevtcb->last_index) > 0 && EVTTIM_LE(my_p_tevtcb, TMEVT_NODE(my_p_tevtcb, 1).time, my_p_tevtcb->current_time)) {
		p_tmevtb = TMEVT_NODE(my_p_tevtcb, 1).p_tmevtb;
		tmevtb_delete_top(my_p_tevtcb);
		(*(p_tmevtb->callback))(p_tmevtb->arg);
	}

	/*
	 *  min_timeを更新する.
	 */
	my_p_tevtcb->min_time = my_p_tevtcb->current_time;

	release_tsk_lock(my_p_pcb);
	i_unlock_cpu();
}
Beispiel #8
0
/*
 *   IMASKの設定参照機能
 */
SYSCALL ER
chg_ims(IMS ims)
{

    if(sense_context()){
        if(!sigismember(&ims,SIGUSR1))
            return(E_PAR);
    }else{
        if(sigismember(&ims,SIGUSR1))
            return(E_PAR);
    }
    
    
    sigprocmask(SIG_SETMASK,&ims,0);    
	return(E_OK);
}
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;

	assert(sense_context());
	assert(!i_sense_lock());

	i_lock_cpu();

	/*
	 *  update current time
	 */
	current_time = next_time;

	/*
	 *  update next_time and next_sub time
	 */
#if TIC_DENO == 1U
	next_time = current_time + TIC_NUME;
#else /* TIC_DENO == 1U */
	next_subtime += TIC_NUME % TIC_DENO;
	next_time = current_time + TIC_NUME / TIC_DENO;
	if (next_subtime >= TIC_DENO) {
		next_subtime -= TIC_DENO;
		next_time += 1U;
	}
#endif /* TIC_DENO == 1U */

	/*
	 *  if current time is not earlier than the earliest time event in time
	 *  event heap, it means a time event shall happen
	 */
	while (last_index > 0 && EVTTIM_LE(TMEVT_NODE(1).time, current_time)) {
		p_tmevtb = TMEVT_NODE(1).p_tmevtb;
		tmevtb_delete_top();
		(*(p_tmevtb->callback))(p_tmevtb->arg);
	}

	/*
	 *  update min time
	 */
	min_time = current_time;

	i_unlock_cpu();
}
Beispiel #10
0
ER
sig_sem(ID semid)
{
	SEMCB	*p_semcb;
	TCB		*p_tcb;
	ER		ercd;
    
	LOG_SIG_SEM_ENTER(semid);
	CHECK_UNL();
	CHECK_ID(VALID_SEMID(semid));
	p_semcb = get_semcb(semid);

	lock_cpu();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_semcb->p_seminib->acvct.acptn1)) {
		ercd = E_OACV;
	}
	else if (!queue_empty(&(p_semcb->wait_queue))) {
		p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
		wait_complete(p_tcb);
		if (p_runtsk != p_schedtsk) {
			if (!sense_context()) {
				dispatch();
			}
			else {
				request_dispatch_retint();
			}
		}
		ercd = E_OK;
	}
	else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
		p_semcb->semcnt += 1;
		ercd = E_OK;
	}
	else {
		ercd = E_QOVR;
	}
	unlock_cpu();

  error_exit:
	LOG_SIG_SEM_LEAVE(ercd);
	return(ercd);
}
void
signal_time(void)
{
	TMEVTB	*p_tmevtb;
	bool_t	callflag;

	assert(sense_context());
	assert(!sense_lock());

	lock_cpu();
	in_signal_time = true;							/*[ASPD1033]*/

	do {
		/*
		 *  コールバック関数を呼び出さなければループを抜ける[ASPD1020].
		 */
		callflag = false;

		/*
		 *  現在のイベント時刻を求める[ASPD1022].
		 */
		update_current_evttim();

		/*
		 *  発生時刻がcurrent_evttim以前のタイムイベントがあれば,タイ
		 *  ムイベントヒープから削除し,コールバック関数を呼び出す
		 *  [ASPD1018][ASPD1019].
		 */
		while (p_last_tmevtn >= p_top_tmevtn
							&& EVTTIM_LE(top_evttim, current_evttim)) {
			p_tmevtb = tmevtb_delete_top();
			(*(p_tmevtb->callback))(p_tmevtb->arg);
			callflag = true;
		}
	} while (callflag);								/*[ASPD1020]*/

	/*
	 *  高分解能タイマ割込みの発生タイミングを設定する[ASPD1025].
	 */
	set_hrt_event();

	in_signal_time = false;							/*[ASPD1033]*/
	unlock_cpu();
}
Beispiel #12
0
void
call_ovrhdr(void)
{
	PRI		saved_ipm;

	assert(sense_context());
	assert(!i_sense_lock());
	assert(ovrinib.ovrhdr != NULL);

	p_runtsk->leftotm = 0U;
	saved_ipm = i_get_ipm();

	LOG_OVR_ENTER(p_runtsk);
	(*((OVRHDR)(ovrinib.ovrhdr)))(TSKID(p_runtsk), p_runtsk->p_tinib->exinf);
	LOG_OVR_LEAVE(p_runtsk);

	if (i_sense_lock()) {
		i_unlock_cpu();
	}
	i_set_ipm(saved_ipm);
}
ER
rel_wai(ID tskid)
{
	TCB		*p_tcb;
	ER		ercd;

	LOG_REL_WAI_ENTER(tskid);
	CHECK_UNL();
	CHECK_ID(VALID_TSKID(tskid));
	p_tcb = get_tcb(tskid);

	lock_cpu();
	if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (!TSTAT_WAITING(p_tcb->tstat)) {
		ercd = E_OBJ;
	}
	else {
		wait_dequeue_wobj(p_tcb);
		wait_dequeue_tmevtb(p_tcb);
		p_tcb->p_winfo->wercd = E_RLWAI;
		make_non_wait(p_tcb);
		if (p_runtsk != p_schedtsk) {
			if (!sense_context()) {
				dispatch();
			}
			else {
				request_dispatch();
			}
		}
		ercd = E_OK;
	}
	unlock_cpu();

  error_exit:
	LOG_REL_WAI_LEAVE(ercd);
	return(ercd);
}
Beispiel #14
0
bool_t
sns_dpn(void)
{
	bool_t	state;
	bool_t	locked;

	LOG_SNS_DPN_ENTER();

	/*
	 *  PCBへアクセスするためCPUロック状態とする
	 */
	locked = t_sense_lock();
	if (!locked) {
		t_lock_cpu();
	}
	state = (sense_context() || locked || !((get_my_p_pcb())->dspflg)) ? true : false;
	if (!locked) {
		t_unlock_cpu();
	}

	LOG_SNS_DPN_LEAVE(state);
	return(state);
}
Beispiel #15
0
void
call_ovrhdr(void)
{
    assert(sense_context());
    assert(!i_sense_lock());
    assert(ovrinib.ovrhdr != NULL);

    i_lock_cpu();
    if (p_runtsk!= NULL && p_runtsk->leftotm == 1U) {
        p_runtsk->leftotm = 0U;
        i_unlock_cpu();

        LOG_OVR_ENTER(p_runtsk);
        ((OVRHDR)(ovrinib.ovrhdr))(TSKID(p_runtsk), p_runtsk->p_tinib->exinf);
        LOG_OVR_LEAVE(p_runtsk);
    }
    else {
        /*
         *  このルーチンが呼び出される前に,オーバランハンドラの起動が
         *  キャンセルされた場合
         */
        i_unlock_cpu();
    }
}