⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task_manage.c

📁 日本著名的的嵌入式实时操作系统T-Kernel的源码及用户手册。
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *---------------------------------------------------------------------- *    T-Kernel * *    Copyright (C) 2004 by Ken Sakamura. All rights reserved. *    T-Kernel is distributed under the T-License. *---------------------------------------------------------------------- * *    Version:   1.01.00 *    Released by T-Engine Forum(http://www.t-engine.org) at 2004/6/28. * *---------------------------------------------------------------------- *//* *	task_manage.c (T-Kernel/OS) *	Task Management Function */#include "kernel.h"#include "task.h"#include "wait.h"#include "check.h"#include "cpu_task.h"#include <tm/tmonitor.h>/* * Create task */SYSCALL ID _tk_cre_tsk P1( T_CTSK *pk_ctsk ){	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	};	TCB	*tcb;	INT	stksz, sstksz, sysmode, resid;	VP	stack, sstack;	ER	ercd;	CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR);	CHECK_PRI(pk_ctsk->itskpri);	CHECK_NOCOP(pk_ctsk->tskatr);#ifdef USE_SINGLE_STACK	CHECK_NOSPT((pk_ctsk->tskatr & TA_USERSTACK) == 0);#endif#ifdef 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;#ifdef 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(sstksz, TA_RNG0);	if ( sstack == NULL ) return E_NOMEM;	if ( stksz > 0 ) {		/* Allocate user stack area */		stack = IAmalloc(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 = 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(tcb->name, 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 = sysmode;	tcb->sysmode  = 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;		/* No task eigenspace */	}	/* 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;}/* * Task deletion *	Call from critical section */LOCAL void _del_tsk( TCB *tcb ){	VP	stack;	/* Free system stack */	stack = (VB*)tcb->isstack + RESERVE_SSTACK(tcb->tskatr) - tcb->sstksz;	IAfree(stack, TA_RNG0);	if ( tcb->stksz > 0 ) {		/* Free user stack */		stack = (VB*)tcb->istack - tcb->stksz;		IAfree(stack, tcb->tskatr);	}	/* Return control block to FreeQue */	QueInsert(&tcb->tskque, &free_tcb);	tcb->state = TS_NONEXIST;}/* * Delete task  */SYSCALL ER _tk_del_tsk( ID tskid ){	TCB	*tcb;	TSTAT	state;	ER	ercd = E_OK;	CHECK_TSKID(tskid);	tcb = get_tcb(tskid);	BEGIN_CRITICAL_SECTION;	state = tcb->state;	if ( state != TS_DORMANT ) {		ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;	} else {		_del_tsk(tcb);	}	END_CRITICAL_SECTION;	return ercd;}/* ------------------------------------------------------------------------ *//* * Start task */SYSCALL ER _tk_sta_tsk( ID tskid, INT stacd ){	TCB	*tcb;	TSTAT	state;	ER	ercd = E_OK;	CHECK_TSKID(tskid);	tcb = get_tcb(tskid);	BEGIN_CRITICAL_SECTION;	state = tcb->state;	if ( state != TS_DORMANT ) {		ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;	} else {		setup_stacd(tcb, stacd);		make_ready(tcb);	}	END_CRITICAL_SECTION;	return ercd;}/* * Task finalization *	Call from critical section */LOCAL void _ter_tsk( TCB *tcb ){	TSTAT	state;	if ( tcb->svclocked != NULL ) {		/* Unlock all extended SVC locks */		AllUnlockSVC(tcb);	}	state = tcb->state;	if ( state == TS_READY ) {		make_non_ready(tcb);	} else if ( (state & TS_WAIT) != 0 ) {		wait_cancel(tcb);		if ( tcb->wspec->rel_wai_hook != NULL ) {			(*tcb->wspec->rel_wai_hook)(tcb);		}	}#ifdef NUM_MTXID	/* signal mutex */	signal_all_mutex(tcb);#endif	cleanup_context(tcb);}/* * End its own task */SYSCALL void _tk_ext_tsk( void ){#ifdef DORMANT_STACK_SIZE	/* To avoid destroying stack used in 'make_dormant', 	   allocate the dummy area on the stack. */	volatile VB _dummy[DORMANT_STACK_SIZE];#endif	/* Check context error */#ifdef CHK_CTX2	if ( in_indp() ) {#ifndef NO_KERNEL_MESSAGE		tm_putstring("tk_ext_tsk was called in the task independent\n");#endif		tm_monitor(); /* To monitor */	}#endif#ifdef CHK_CTX1	if ( in_ddsp() ) {#ifndef NO_KERNEL_MESSAGE		tm_putstring("tk_ext_tsk was called in the dispatch disabled\n");#endif	}#endif	DISABLE_INTERRUPT;	_ter_tsk(ctxtsk);	make_dormant(ctxtsk);	force_dispatch();	/* No return */#ifdef DORMANT_STACK_SIZE	/* for WARNING */	_dummy[0] = 0;#endif}/* * End and delete its own task */SYSCALL void _tk_exd_tsk( void ){	/* Check context error */#ifdef CHK_CTX2	if ( in_indp() ) {#ifndef NO_KERNEL_MESSAGE		tm_putstring("tk_exd_tsk was called in the task independent\n");#endif		tm_monitor(); /* To monitor */	}#endif#ifdef CHK_CTX1	if ( in_ddsp() ) {#ifndef NO_KERNEL_MESSAGE		tm_putstring("tk_exd_tsk was called in the dispatch disabled\n");#endif	}#endif	DISABLE_INTERRUPT;	_ter_tsk(ctxtsk);	_del_tsk(ctxtsk);	force_dispatch();	/* No return */}/* * Termination of other task */SYSCALL ER _tk_ter_tsk( ID tskid ){	TCB	*tcb;	TSTAT	state;	ER	ercd = E_OK;	CHECK_TSKID(tskid);	CHECK_NONSELF(tskid);	CHECK_INTSK();	tcb = get_tcb(tskid);	BEGIN_CRITICAL_SECTION;	state = tcb->state;	if ( !task_alive(state) ) {		ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;	} else if ( tcb->klocked ) {		/* Normally, it does not become this state.		 * When the state is page-in wait in the virtual memory		 * system and when triying to terminate any task,		 * it becomes this state.		 */		ercd = E_OBJ;	} else {		_ter_tsk(tcb);		make_dormant(tcb);	}	END_CRITICAL_SECTION;	return ercd;}/* ------------------------------------------------------------------------ *//* * Change task priority */SYSCALL ER _tk_chg_pri( ID tskid, PRI tskpri ){	TCB	*tcb;	INT	priority;	ER	ercd;	CHECK_TSKID_SELF(tskid);	CHECK_PRI_INI(tskpri);	tcb = get_tcb_self(tskid);	BEGIN_CRITICAL_SECTION;	if ( tcb->state == TS_NONEXIST ) {		ercd = E_NOEXS;		goto error_exit;	}	/* Converiosn priority to internal expression */	if ( tskpri == TPRI_INI ) {		priority = tcb->ipriority;	} else {		priority = int_priority(tskpri);	}#ifdef NUM_MTXID	/* Mutex priority change limit */	ercd = chg_pri_mutex(tcb, priority);	if ( ercd < E_OK ) goto error_exit;	tcb->bpriority = priority;	priority = ercd;#else	tcb->bpriority = priority;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -