📄 uit_func.inl
字号:
else
ret = E_OBJ;
Cyg_Scheduler::unlock();
return ret;
}
#endif // CYGPKG_UITRON_TASKS_CREATE_DELETE
CYG_UIT_FUNC_INLINE
ER
sta_tsk ( ID tskid, INT stacd )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
Cyg_Scheduler::lock();
cyg_uint32 state = p->get_state();
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
// there is a race condition with deleting the task
// so test it now that we have the scheduler locked
if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] )
ret = E_NOEXS;
else // NOTE dangling else to the next line:
#endif
if ( state & Cyg_Thread::EXITED ) {
p->reinitialize();
#ifdef CYGIMP_THREAD_PRIORITY
p->set_priority( CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) );
#endif
p->set_entry_data( (CYG_ADDRWORD)stacd );
p->force_resume();
}
else
ret = E_OBJ;
Cyg_Scheduler::unlock();
return ret;
}
CYG_UIT_FUNC_INLINE
void
ext_tsk ( void )
{
Cyg_Thread::exit();
}
CYG_UIT_FUNC_INLINE
void
exd_tsk ( void )
{
#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
Cyg_Thread *p;
Cyg_Scheduler::lock();
p = Cyg_Thread::self();
ID tskid = (p - (&cyg_uitron_TASKS[0])) + 1;
// just disconnect the pointer from its object
CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
// Any associated storage management, and possibly calling the task
// destructor, is for future versions.
#else
// do nothing - deletion not supported so just exit...
#endif
Cyg_Thread::exit();
// does not return, does unlock the scheduler for us
}
CYG_UIT_FUNC_INLINE
ER
ter_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock();
if ( (0 != (Cyg_Thread::EXITED & p->get_state())) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
// already dormant
ret = E_OBJ;
else {
p->force_resume(); // let it run
p->kill(); // and set prio high so it runs RIGHT NOW!!
#ifdef CYGIMP_THREAD_PRIORITY
#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES != 0
// see if we are already at prio 0:
if ( 0 == cyg_uitron_dis_dsp_old_priority )
// then dispatch is enabled, we are not at prio 0
#endif
p->set_priority( (cyg_priority) 0 );
// if we do not do this, then we are not running a strictly
// uITRON compatible scheduler - so just hope for the best.
#endif
}
Cyg_Scheduler::unlock();
#ifdef CYGIMP_THREAD_PRIORITY
#if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0
if ( (E_OK == ret) && (0 != cyg_uitron_dis_dsp_old_priority) ) {
// then dispatching is disabled, so our prio is 0 too
Cyg_Thread::yield(); // so let the dying thread run;
Cyg_Thread::yield(); // no cost here of making sure.
}
#endif
#endif
return ret;
}
CYG_UIT_FUNC_INLINE
ER
dis_dsp ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
CYG_UITRON_CHECK_CPU_UNLOC();
Cyg_Scheduler::lock();
// Prevent preemption by going up to prio 0
if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
cyg_uitron_dis_dsp_old_priority = p->get_priority();
p->set_priority( 0 );
#else
cyg_uitron_dis_dsp_old_priority = 1;
#endif
}
Cyg_Scheduler::unlock();
return E_OK;
}
CYG_UIT_FUNC_INLINE
ER
ena_dsp ( void )
{
CYG_UITRON_CHECK_TASK_CONTEXT();
CYG_UITRON_CHECK_CPU_UNLOC();
Cyg_Scheduler::lock();
// Enable dispatching (if disabled) and maybe switch threads
if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
// We had prevented preemption by going up to prio 0
#ifdef CYGIMP_THREAD_PRIORITY
Cyg_Thread *p = Cyg_Thread::self();
p->set_priority( cyg_uitron_dis_dsp_old_priority );
p->to_queue_head(); // to ensure we continue to run
// if nobody higher pri
#endif
cyg_uitron_dis_dsp_old_priority = 0;
}
Cyg_Scheduler::unlock();
CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
return E_OK;
}
CYG_UIT_FUNC_INLINE
ER
chg_pri ( ID tskid, PRI tskpri )
{
Cyg_Thread *p;
ER ret = E_OK;
if ( 0 == tskid ) {
p = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
}
else
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
#ifdef CYGIMP_THREAD_PRIORITY
if ( 0 == tskpri )
// then use the initial priority [Level X]
tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
#endif
CYG_UIT_PARAMCHECK( 0 < tskpri, E_PAR );
#ifdef CYGIMP_THREAD_PRIORITY
#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
#else
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
#endif
// Handle changing our own prio specially, if dispatch disabled:
if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
// our actual prio is 0 now and must remain so:
if ( Cyg_Thread::self() == p ) { // by whichever route p was set
// set the priority we will return to when dispatch is enabled:
cyg_uitron_dis_dsp_old_priority = (cyg_uint32)tskpri;
return E_OK;
}
}
Cyg_Scheduler::lock();
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else
p->set_priority( (cyg_priority)tskpri );
Cyg_Scheduler::unlock();
#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
return ret;
}
CYG_UIT_FUNC_INLINE
ER
rot_rdq ( PRI tskpri )
{
// zero means our level; easiet way is to yield() the CPU.
if ( 0 == tskpri ) {
Cyg_Thread::yield();
return E_OK;
}
#ifdef CYGIMP_THREAD_PRIORITY
#if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
#else
CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
#endif
Cyg_Thread::rotate_queue( tskpri );
#endif // CYGIMP_THREAD_PRIORITY got priorities at all?
return E_OK;
}
CYG_UIT_FUNC_INLINE
ER
rel_wai ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else {
p->release();
// return E_OBJ if the thread was not sleeping
if ( Cyg_Thread::BREAK != p->get_wake_reason() )
ret = E_OBJ;
}
Cyg_Scheduler::unlock();
return ret;
}
CYG_UIT_FUNC_INLINE
ER
get_tid ( ID *p_tskid )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UIT_PARAMCHECK_PTR( p_tskid );
if ( (&cyg_uitron_TASKS[0] <= (self)) &&
((self) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]) &&
(0 == Cyg_Scheduler::get_sched_lock()) )
// then I am a uITRON task and not in an interrupt or DSR
*p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1;
else
*p_tskid = 0; // Otherwise, non-task portion
return E_OK;
}
CYG_UIT_FUNC_INLINE
ER
ref_tsk ( T_RTSK *pk_rtsk, ID tskid )
{
Cyg_Thread *p;
if ( 0 == tskid ) {
p = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
tskid = (p - (&cyg_uitron_TASKS[0])) + 1; // it gets used below
}
else
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK_PTR( pk_rtsk );
pk_rtsk->exinf = NADR;
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( (state & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
pk_rtsk->tskstat = TTS_DMT;
else if ( state == Cyg_Thread::RUNNING )
// If it's us, it's running, else it's ready
pk_rtsk->tskstat = (Cyg_Thread::self() == p)
? TTS_RUN // RUN state (we are it)
: TTS_RDY; // READY state
else if ( state & Cyg_Thread::SUSPENDED )
pk_rtsk->tskstat =
(state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
? TTS_WAS // WAIT-SUSPEND state
: TTS_SUS; // SUSPEND state
else
pk_rtsk->tskstat =
(state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
? TTS_WAI // WAIT state
: 0; // Not sure what's happening here!
#ifdef CYGIMP_THREAD_PRIORITY
if ( TTS_DMT == pk_rtsk->tskstat )
pk_rtsk->tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
else if ( (TTS_RUN == pk_rtsk->tskstat) &&
(0 != cyg_uitron_dis_dsp_old_priority) )
// then we are it and dispatching is disabled, so
// report our "real" priority - it is 0 in the kernel at the moment
pk_rtsk->tskpri = cyg_uitron_dis_dsp_old_priority;
else
pk_rtsk->tskpri = p->get_priority();
#else
pk_rtsk->tskpri = -1; // Not applicable
#endif
Cyg_Scheduler::unlock();
return E_OK;
}
// - Task-Dependent Synchronization Functions
CYG_UIT_FUNC_INLINE
ER
sus_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
(Cyg_Thread::EXIT == p->get_wake_reason()) )
ret = E_OBJ; // task is dormant
else
p->suspend();
Cyg_Scheduler::unlock();
return ret;
}
CYG_UIT_FUNC_INLINE
ER
rsm_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( 0 == (Cyg_Thread::SUSPENDED & state) )
ret = E_OBJ; // thread is not suspended
else
p->resume();
Cyg_Scheduler::unlock();
return ret;
}
CYG_UIT_FUNC_INLINE
ER
frsm_tsk ( ID tskid )
{
Cyg_Thread *p;
ER ret = E_OK;
CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
Cyg_Scheduler::lock(); // get an atomic view of the task
cyg_uint32 state = p->get_state();
if ( 0 == (Cyg_Thread::SUSPENDED & state) )
ret = E_OBJ; // thread is not suspended
else
p->force_resume();
Cyg_Scheduler::unlock();
return ret;
}
CYG_UIT_FUNC_INLINE
ER
slp_tsk ( void )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
// do this now for the case when no sleeping actually occurs
self->set_wake_reason( Cyg_Thread::DONE );
Cyg_Thread::counted_sleep();
if ( Cyg_Thread::DONE != self->get_wake_reason() )
CYG_UITRON_FAIL_RETURN_SELF( self );
return E_OK;
}
#ifdef CYGFUN_KERNEL_THREADS_TIMER
CYG_UIT_FUNC_INLINE
ER
tslp_tsk ( TMO tmout )
{
Cyg_Thread *self = Cyg_Thread::self();
CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
CYG_UIT_PARAMCHECK( -1 <= tmout, E_PAR );
CYG_UITRON_CHECK_DISPATCH_ENABLED();
// do this now for the case when no sleeping actually occurs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -