Mercurial > ecos
diff packages/compat/uitron/current/include/uit_func.inl @ 2:443894e2e912 ecos-v1_2_1-release
Block commit of eCos version 1.2.1
| author | jlarmour |
|---|---|
| date | Tue, 11 May 1999 12:24:34 +0000 |
| parents | 3111d98ba7b3 |
| children | ece80412419a |
line wrap: on
line diff
--- a/packages/compat/uitron/current/include/uit_func.inl +++ b/packages/compat/uitron/current/include/uit_func.inl @@ -2,9 +2,9 @@ #define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL //=========================================================================== // -// uit_func.inl +// uit_func.inl // -// uITRON compatibility functions +// uITRON compatibility functions // //=========================================================================== //####COPYRIGHTBEGIN#### @@ -24,18 +24,18 @@ // September 30, 1998. // // The Initial Developer of the Original Code is Cygnus. Portions created -// by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved. +// by Cygnus are Copyright (C) 1998,1999 Cygnus Solutions. All Rights Reserved. // ------------------------------------------- // //####COPYRIGHTEND#### //=========================================================================== //#####DESCRIPTIONBEGIN#### // -// Author(s): hmt -// Contributors: hmt -// Date: 1998-03-13 -// Purpose: uITRON compatibility functions -// Description: +// Author(s): hmt +// Contributors: hmt +// Date: 1998-03-13 +// Purpose: uITRON compatibility functions +// Description: // //####DESCRIPTIONEND#### // @@ -56,19 +56,24 @@ #include <cyg/kernel/sched.inl> #include <cyg/kernel/clock.inl> + +// ------------------------------------------------------------------------ +// The variable where dis_dsp/ena_dsp state is held: +extern cyg_uint32 cyg_uitron_dis_dsp_old_priority; + // ------------------------------------------------------------------------ // Parameter checking; either check the expression and return an error code // if not true, or assert the truth with a made-up message. #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS // default: uitron error codes are returned -#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \ - if ( ! (_true_) ) return (_error_); \ +#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \ + if ( ! (_true_) ) return (_error_); \ CYG_MACRO_END #else // ...but they are asserted if asserts are on -#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \ - CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ ); \ +#define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START \ + CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ ); \ CYG_MACRO_END #endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS @@ -81,111 +86,111 @@ CYG_MACRO_END // // Usage: // INT snd_msg( ID mbxid, ... ) { -// Cyg_Mbox *p; -// CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p ); -// p->...(...); +// Cyg_Mbox *p; +// CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p ); +// p->...(...); // internal: plain assignment to the object pointer, from static array -#define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \ - (_ptr_) = CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1); \ +#define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \ + (_ptr_) = CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1); \ CYG_MACRO_END // internal: plain assignment to the object pointer, from pointer array // with error checking. -#define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \ - (_ptr_) = CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ]; \ - if ( NULL == (_ptr_) ) return E_NOEXS; \ +#define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START \ + (_ptr_) = CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ]; \ + if ( NULL == (_ptr_) ) return E_NOEXS; \ CYG_MACRO_END -#define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ ) \ -CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ - CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ - CYG_UIT_SPTR( _which_, _idx_, _ptr_ ); \ +#define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ ) \ +CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ + CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ + CYG_UIT_SPTR( _which_, _idx_, _ptr_ ); \ CYG_MACRO_END -#define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ ) \ -CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ - CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ - CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ); \ +#define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ ) \ +CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ + CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ + CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ); \ CYG_MACRO_END // As above but for handler numbers which return E_PAR when out of range -#define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ ) \ -CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR ); \ +#define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ ) \ +CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR ); \ CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR ); \ - CYG_UIT_SPTR( _which_, _num_, _ptr_ ); \ + CYG_UIT_SPTR( _which_, _num_, _ptr_ ); \ CYG_MACRO_END // And a macro to check that creation of an object is OK -#define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ ) \ -CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ - CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ - Cyg_Scheduler::lock(); \ - if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) { \ - Cyg_Scheduler::unlock(); \ - return E_OBJ; \ - } \ +#define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ ) \ +CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID ); \ + CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID ); \ + Cyg_Scheduler::lock(); \ + if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) { \ + Cyg_Scheduler::unlock(); \ + return E_OBJ; \ + } \ CYG_MACRO_END // define a magic new operator in order to call constructors -#define CYG_UITRON_NEWFUNCTION( _class_ ) \ -inline void *operator new(size_t size, _class_ *ptr) \ -{ \ - CYG_CHECK_DATA_PTR( ptr, "Bad pointer" ); \ - return ptr; \ +#define CYG_UITRON_NEWFUNCTION( _class_ ) \ +inline void *operator new(size_t size, _class_ *ptr) \ +{ \ + CYG_CHECK_DATA_PTR( ptr, "Bad pointer" ); \ + return ptr; \ } // now configury to support selectable create/delete support ie. an // array of pointers to the objects themselves. #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( TASKS, _idx_, _ptr_ ) #endif #ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( SEMAS, _idx_, _ptr_ ) #endif #ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( MBOXES, _idx_, _ptr_ ) #endif #ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( FLAGS, _idx_, _ptr_ ) #endif #ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLFIXED, _idx_, _ptr_ ) #endif #ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE -#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ ) #else -#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \ +#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ ) \ CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ ) #endif @@ -197,46 +202,46 @@ inline void *operator new(size_t size, _ // if not checking and not asserted, these are removed to avoid usused // variable warnings. #define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_EMPTY_STATEMENT -#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_EMPTY_STATEMENT -#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_EMPTY_STATEMENT +#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_EMPTY_STATEMENT +#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_EMPTY_STATEMENT #define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( _tmout_ ) CYG_EMPTY_STATEMENT #else // the default: // Check a task is actually a uITRON task -#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( \ - (&cyg_uitron_TASKS[0] <= (_self_)) && \ - ((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]), \ - E_CTX ); \ +#define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( \ + (&cyg_uitron_TASKS[0] <= (_self_)) && \ + ((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]), \ + E_CTX ); \ CYG_MACRO_END -#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START \ - Cyg_Thread *self = Cyg_Thread::self(); \ - CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self ); \ +#define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START \ + Cyg_Thread *self = Cyg_Thread::self(); \ + CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self ); \ CYG_MACRO_END // Check dispatching is enabled for calls which might wait -#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( 0 == Cyg_Scheduler::get_sched_lock(), E_CTX ); \ +#define CYG_UITRON_CHECK_DISPATCH_ENABLED() CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( 0 == cyg_uitron_dis_dsp_old_priority, E_CTX ); \ CYG_MACRO_END #define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO(_tmout_) CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR ); \ - if ( TMO_POL != (_tmout_) ) \ - CYG_UITRON_CHECK_DISPATCH_ENABLED(); \ + CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR ); \ + if ( TMO_POL != (_tmout_) ) \ + CYG_UITRON_CHECK_DISPATCH_ENABLED(); \ CYG_MACRO_END #endif #ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR -#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \ +#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \ CYG_MACRO_END #else // do check for NULL -#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \ - CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \ - CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR ); \ +#define CYG_UIT_PARAMCHECK_PTR( _p_ ) CYG_MACRO_START \ + CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR ); \ + CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR ); \ CYG_MACRO_END #endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR @@ -248,25 +253,25 @@ CYG_MACRO_END // This macro examines context and finds out which, then executes a return // with the correct uITRON condition code. -#define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START \ - Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason(); \ - if ( Cyg_Thread::TIMEOUT == reason ) \ - return E_TMOUT; \ - if ( Cyg_Thread::BREAK == reason ) \ - return E_RLWAI; \ - if ( Cyg_Thread::DESTRUCT == reason ) \ - return E_DLT; \ - return E_SYS; /* if no plausible reason was found */ \ +#define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START \ + Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason(); \ + if ( Cyg_Thread::TIMEOUT == reason ) \ + return E_TMOUT; \ + if ( Cyg_Thread::BREAK == reason ) \ + return E_RLWAI; \ + if ( Cyg_Thread::DESTRUCT == reason ) \ + return E_DLT; \ + return E_SYS; /* if no plausible reason was found */ \ CYG_MACRO_END -#define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START \ - Cyg_Thread *self = Cyg_Thread::self(); \ - CYG_UITRON_FAIL_RETURN_SELF( self ); \ +#define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START \ + Cyg_Thread *self = Cyg_Thread::self(); \ + CYG_UITRON_FAIL_RETURN_SELF( self ); \ CYG_MACRO_END // ------------------------------------------------------------------------ // Interrupts disabled? -#define CYG_UITRON_CHECK_CPU_UNLOC() \ +#define CYG_UITRON_CHECK_CPU_UNLOC() \ CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX ) // ------------------------------------------------------------------------ @@ -328,6 +333,11 @@ del_tsk ( ID tskid ) CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p ); Cyg_Scheduler::lock(); + // deal with the race condition here + if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] ) { + Cyg_Scheduler::unlock(); + return E_NOEXS; + } cyg_uint32 state = p->get_state(); if ( state & Cyg_Thread::EXITED ) // just disconnect the pointer from its object @@ -419,6 +429,13 @@ ter_tsk ( ID tskid ) #endif } Cyg_Scheduler::unlock(); +#ifdef CYGIMP_THREAD_PRIORITY + 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 return ret; } @@ -428,9 +445,18 @@ dis_dsp ( void ) { CYG_UITRON_CHECK_TASK_CONTEXT(); CYG_UITRON_CHECK_CPU_UNLOC(); - // Prevent preemption - if ( 0 == Cyg_Scheduler::get_sched_lock() ) - Cyg_Scheduler::lock(); + 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; } @@ -440,9 +466,19 @@ ena_dsp ( void ) { CYG_UITRON_CHECK_TASK_CONTEXT(); CYG_UITRON_CHECK_CPU_UNLOC(); - // Unlock the scheduler (if locked) and maybe switch threads - if ( 0 < Cyg_Scheduler::get_sched_lock() ) - Cyg_Scheduler::unlock(); + 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; } @@ -460,6 +496,8 @@ chg_pri ( ID tskid, PRI tskpri ) } else CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p ); + + 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 && @@ -468,6 +506,15 @@ chg_pri ( ID tskid, PRI tskpri ) 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()) ) @@ -496,9 +543,7 @@ rot_rdq ( PRI tskpri ) CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri && tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR ); #endif -#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE Cyg_Thread::rotate_queue( tskpri ); -#endif #endif // CYGIMP_THREAD_PRIORITY got priorities at all? return E_OK; } @@ -530,9 +575,13 @@ ER get_tid ( ID *p_tskid ) { Cyg_Thread *self = Cyg_Thread::self(); - CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self ); CYG_UIT_PARAMCHECK_PTR( p_tskid ); - *p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1; + if ( (&cyg_uitron_TASKS[0] <= (self)) && + ((self) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]) ) + // then I am a uITRON task + *p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1; + else + *p_tskid = 0; // Otherwise, non-task portion return E_OK; } @@ -574,6 +623,11 @@ ref_tsk ( T_RTSK *pk_rtsk, ID tskid ) #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 @@ -756,7 +810,7 @@ del_sem ( ID semid ) // deal with the race condition here if ( p != CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] ) { Cyg_Scheduler::unlock(); - return E_OBJ; + return E_NOEXS; } CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] = NULL; p->~Cyg_Counting_Semaphore2(); @@ -877,7 +931,7 @@ del_flg ( ID flgid ) // deal with the race condition here if ( p != CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] ) { Cyg_Scheduler::unlock(); - return E_OBJ; + return E_NOEXS; } CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] = NULL; p->~Cyg_Flag(); @@ -1034,7 +1088,7 @@ del_mbx ( ID mbxid ) // deal with the race condition here if ( p != CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] ) { Cyg_Scheduler::unlock(); - return E_OBJ; + return E_NOEXS; } CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] = NULL; p->~Cyg_Mbox(); @@ -1054,29 +1108,29 @@ del_mbx ( ID mbxid ) #ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR // represent a NULL as NADR internally -#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_MACRO_START \ - if ( NULL == (_p_) ) \ - (_p_) = (T_MSG *)NADR; \ +#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_MACRO_START \ + if ( NULL == (_p_) ) \ + (_p_) = (T_MSG *)NADR; \ CYG_MACRO_END // we get a NADR back sometimes, meaning NULL -#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_MACRO_START \ - if ( NADR == (_p_) ) \ - (_p_) = (T_MSG *)NULL; \ +#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_MACRO_START \ + if ( NADR == (_p_) ) \ + (_p_) = (T_MSG *)NULL; \ CYG_MACRO_END #else // NULL is checked for and makes an error -#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_EMPTY_STATEMENT -#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_EMPTY_STATEMENT +#define CYG_UIT_TMSG_FIXUP_IN( _p_ ) CYG_EMPTY_STATEMENT +#define CYG_UIT_TMSG_FIXUP_OUT( _p_ ) CYG_EMPTY_STATEMENT #endif // and sometimes either in status enquiries -#define CYG_UIT_TMSG_FIXUP_ALL( _p_ ) CYG_MACRO_START \ - if ( NULL == (_p_) ) \ - (_p_) = (T_MSG *)NADR; \ - else if ( NADR == (_p_) ) \ - (_p_) = (T_MSG *)NULL; \ +#define CYG_UIT_TMSG_FIXUP_ALL( _p_ ) CYG_MACRO_START \ + if ( NULL == (_p_) ) \ + (_p_) = (T_MSG *)NADR; \ + else if ( NADR == (_p_) ) \ + (_p_) = (T_MSG *)NULL; \ CYG_MACRO_END CYG_UIT_FUNC_INLINE @@ -1178,40 +1232,40 @@ ref_mbx ( T_RMBX *pk_rmbx, ID mbxid ) // - Extended Synchronization and Communication Functions #if 0 // NOT SUPPORTED -ER cre_mbf ( ID mbfid, T_CMBF *pk_cmbf ); -ER del_mbf ( ID mbfid ); -ER snd_mbf ( ID mbfid, VP msg, INT msgsz ); -ER psnd_mbf ( ID mbfid, VP msg, INT msgsz ); -ER tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout ); -ER rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid ); -ER prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid ); -ER trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout ); -ER ref_mbf ( T_RMBF *pk_rmbf, ID mbfid ); -ER cre_por ( ID porid, T_CPOR *pk_cpor ); -ER del_por ( ID porid ); -ER cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT +ER cre_mbf ( ID mbfid, T_CMBF *pk_cmbf ); +ER del_mbf ( ID mbfid ); +ER snd_mbf ( ID mbfid, VP msg, INT msgsz ); +ER psnd_mbf ( ID mbfid, VP msg, INT msgsz ); +ER tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout ); +ER rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid ); +ER prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid ); +ER trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout ); +ER ref_mbf ( T_RMBF *pk_rmbf, ID mbfid ); +ER cre_por ( ID porid, T_CPOR *pk_cpor ); +ER del_por ( ID porid ); +ER cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz ); -ER pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT +ER pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz ); -ER tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT +ER tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT cmsgsz, TMO tmout ); -ER acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT +ER acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn ); -ER pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT +ER pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn ); -ER tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT +ER tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT acpptn, TMO tmout ); -ER fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz +ER fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz ); -ER rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz ); -ER ref_por ( T_RPOR *pk_rpor, ID porid ); +ER rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz ); +ER ref_por ( T_RPOR *pk_rpor, ID porid ); #endif // - Interrupt Management Functions #if 0 // NOT SUPPORTED -ER def_int ( UINT dintno, T_DINT *pk_dint ); -void ret_wup ( ID tskid ); +ER def_int ( UINT dintno, T_DINT *pk_dint ); +void ret_wup ( ID tskid ); #endif CYG_UIT_FUNC_INLINE @@ -1219,9 +1273,19 @@ ER loc_cpu ( void ) { CYG_UITRON_CHECK_TASK_CONTEXT(); + 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_Interrupt::disable_interrupts(); - if ( 0 == Cyg_Scheduler::get_sched_lock() ) - Cyg_Scheduler::lock(); + Cyg_Scheduler::unlock(); return E_OK; } @@ -1230,17 +1294,27 @@ ER unl_cpu ( void ) { CYG_UITRON_CHECK_TASK_CONTEXT(); + 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 ); +#endif + cyg_uitron_dis_dsp_old_priority = 0; + } Cyg_Interrupt::enable_interrupts(); - if ( 0 < Cyg_Scheduler::get_sched_lock() ) - Cyg_Scheduler::unlock(); + Cyg_Scheduler::unlock(); + CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards! return E_OK; } #if 0 // NOT SUPPORTED -ER dis_int ( UINT eintno ); -ER ena_int ( UINT eintno ); -ER chg_iXX ( UINT iXXXX ); -ER ref_iXX ( UINT *p_iXXXX ); +ER dis_int ( UINT eintno ); +ER ena_int ( UINT eintno ); +ER chg_iXX ( UINT iXXXX ); +ER ref_iXX ( UINT *p_iXXXX ); #endif // - Memorypool Management Functions @@ -1286,7 +1360,7 @@ del_mpl ( ID mplid ) // deal with the race condition here if ( p != CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] ) { Cyg_Scheduler::unlock(); - return E_OBJ; + return E_NOEXS; } CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] = NULL; p->~Cyg_Mempool_Variable(); @@ -1436,7 +1510,7 @@ del_mpf ( ID mpfid ) // deal with the race condition here if ( p != CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] ) { Cyg_Scheduler::unlock(); - return E_OBJ; + return E_NOEXS; } CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] = NULL; p->~Cyg_Mempool_Fixed(); @@ -1711,16 +1785,16 @@ get_ver ( T_VER *pk_ver ) { CYG_UIT_PARAMCHECK_PTR( pk_ver ); - pk_ver->maker = CYGNUM_UITRON_VER_MAKER; - pk_ver->id = CYGNUM_UITRON_VER_ID; - pk_ver->spver = CYGNUM_UITRON_VER_SPVER; - pk_ver->prver = CYGNUM_UITRON_VER_PRVER; - pk_ver->prno[0] = CYGNUM_UITRON_VER_PRNO_0; - pk_ver->prno[1] = CYGNUM_UITRON_VER_PRNO_1; - pk_ver->prno[2] = CYGNUM_UITRON_VER_PRNO_2; - pk_ver->prno[3] = CYGNUM_UITRON_VER_PRNO_3; - pk_ver->cpu = CYGNUM_UITRON_VER_CPU; - pk_ver->var = CYGNUM_UITRON_VER_VAR; + pk_ver->maker = CYGNUM_UITRON_VER_MAKER; + pk_ver->id = CYGNUM_UITRON_VER_ID; + pk_ver->spver = CYGNUM_UITRON_VER_SPVER; + pk_ver->prver = CYGNUM_UITRON_VER_PRVER; + pk_ver->prno[0] = CYGNUM_UITRON_VER_PRNO_0; + pk_ver->prno[1] = CYGNUM_UITRON_VER_PRNO_1; + pk_ver->prno[2] = CYGNUM_UITRON_VER_PRNO_2; + pk_ver->prno[3] = CYGNUM_UITRON_VER_PRNO_3; + pk_ver->cpu = CYGNUM_UITRON_VER_CPU; + pk_ver->var = CYGNUM_UITRON_VER_VAR; return E_OK; } @@ -1735,7 +1809,7 @@ ref_sys ( T_RSYS *pk_rsys ) pk_rsys->sysstat = TSS_LOC; else pk_rsys->sysstat = - (Cyg_Scheduler::get_sched_lock() == 0) ? TSS_TSK : TSS_DDSP; + (0 == cyg_uitron_dis_dsp_old_priority) ? TSS_TSK : TSS_DDSP; return E_OK; } @@ -1749,19 +1823,19 @@ ref_cfg ( T_RCFG *pk_rcfg ) } #if 0 // NOT SUPPORTED -ER def_svc ( FN s_fncd, T_DSVC *pk_dsvc ); -ER def_exc ( UINT exckind, T_DEXC *pk_dexc ); +ER def_svc ( FN s_fncd, T_DSVC *pk_dsvc ); +ER def_exc ( UINT exckind, T_DEXC *pk_dexc ); #endif // - Network Support Functions #if 0 // NOT SUPPORTED -ER nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr, +ER nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr, INT datsz ); -ER nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr, +ER nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr, INT datsz ); -ER nget_nod ( NODE *p_node ); -ER nget_ver ( T_VER *pk_ver, NODE node ); +ER nget_nod ( NODE *p_node ); +ER nget_ver ( T_VER *pk_ver, NODE node ); #endif // ========================================================================
