diff packages/compat/uitron/current/include/uit_func.inl @ 0:3111d98ba7b3 ecos-v1_1-release

Initial commit of eCos version 1.1
author jlarmour
date Tue, 11 May 1999 11:16:07 +0000
parents
children 443894e2e912
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/packages/compat/uitron/current/include/uit_func.inl
@@ -0,0 +1,1774 @@
+#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+#define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+//===========================================================================
+//
+//	uit_func.inl
+//
+//	uITRON compatibility functions
+//
+//===========================================================================
+//####COPYRIGHTBEGIN####
+//
+// -------------------------------------------
+// The contents of this file are subject to the Cygnus eCos Public License
+// Version 1.0 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://sourceware.cygnus.com/ecos
+// 
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Cygnus Operating System, released
+// 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.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//===========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s): 	hmt
+// Contributors:	hmt
+// Date:	1998-03-13
+// Purpose:	uITRON compatibility functions
+// Description:	
+//
+//####DESCRIPTIONEND####
+//
+//===========================================================================
+
+#ifdef CYGPKG_UITRON
+
+#ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+#include <cyg/compat/uitron/uit_objs.hxx> // uITRON setup CYGNUM_UITRON_SEMAS
+
+// kernel facilities only needed here
+#include <cyg/kernel/intr.hxx>
+#include <cyg/kernel/sched.hxx>
+
+// and the implementations of other kernel facilities
+#include <cyg/kernel/thread.inl>
+#include <cyg/kernel/sched.inl>
+#include <cyg/kernel/clock.inl>
+
+// ------------------------------------------------------------------------
+// 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_);					\
+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_ );	\
+CYG_MACRO_END
+#endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
+
+// ------------------------------------------------------------------------
+// CYG_UITRON_CHECK_AND_GETP
+// 
+// Macro to rangecheck and do the addressing of a static uitron system
+// object; _which_ sort of object is given, and token pasting is used
+// horribly to get the static array, limits and the like.
+//
+// Usage:
+//   INT snd_msg( ID mbxid, ... ) {
+//	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);		\
+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;				\
+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_ );				\
+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_ );				\
+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 );				\
+    CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR );  \
+    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;							\
+    }									\
+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; 							\
+}
+
+// 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_ )			\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ )
+#else
+#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_ )			\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ )
+#else
+#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_ )		\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ )
+#else
+#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_ )			\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ )
+#else
+#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_ )		\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
+#else
+#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_ )		\
+    CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ )
+#else
+#define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )		\
+    CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ )
+#endif
+
+// ------------------------------------------------------------------------
+// Common error checking macros
+
+#if !defined( CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS ) && \
+    !defined( CYGDBG_USE_ASSERTS )
+// 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_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 );       			\
+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 );				\
+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 );  \
+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_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 );			\
+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 );			\
+CYG_MACRO_END
+#endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+
+// ------------------------------------------------------------------------
+// CYG_UITRON_FAIL_RETURN
+//
+// After a call which waits, it might return with success, or due to a
+// timeout or a release wait (a forced escape from the waiting condition).
+// 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 */		\
+CYG_MACRO_END
+
+#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()					\
+    CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX )
+
+// ------------------------------------------------------------------------
+// the function definitions themselves:
+
+// ******************************************************
+// ***    6.5 C Language Interfaces                   ***
+// ******************************************************
+
+// - Task Management Functions
+
+#ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
+CYG_UITRON_NEWFUNCTION( Cyg_Thread )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_tsk ( ID tskid, T_CTSK *pk_ctsk )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_ctsk );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( TASKS, tskid );
+
+    Cyg_Thread *p = &(CYG_UITRON_OBJS( TASKS )[ tskid - 1 ]);
+    cyg_uint32 state = p->get_state();
+    if ( 0 == (state & Cyg_Thread::EXITED) )
+        ret = E_OBJ; // how did it get to be running?
+    else if ( ((INT)p->get_stack_size()) < pk_ctsk->stksz )
+        ret = E_NOMEM; // more stack requested than available
+    else {
+        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] =
+            new( p ) Cyg_Thread(
+                (CYG_ADDRWORD)      pk_ctsk->itskpri,
+                (cyg_thread_entry *)pk_ctsk->task,
+                (CYG_ADDRWORD)      0,
+                // preserve the original name and stack:
+#ifdef CYGVAR_KERNEL_THREADS_NAME
+                p->get_name(),
+#else
+                NULL,
+#endif
+                p->get_stack_base(),
+                p->get_stack_size() );
+        // but ensure the task state is dormant:
+        // (it is not constructed dormant, but suspended)
+        p->kill();
+        // and record the initial priority outside the task too.
+        CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_tsk ( ID tskid )
+{
+    Cyg_Thread *p;
+    ER ret = E_OK;
+    CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
+    
+    Cyg_Scheduler::lock();
+    cyg_uint32 state = p->get_state();
+    if ( state & Cyg_Thread::EXITED )
+        // just disconnect the pointer from its object
+        CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
+    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
+        p->set_priority( (cyg_priority) 0 );
+#endif
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+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();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+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_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 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_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
+#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE
+    Cyg_Thread::rotate_queue( tskpri );
+#endif
+#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_UITRON_CHECK_TASK_CONTEXT_SELF( self );
+    CYG_UIT_PARAMCHECK_PTR( p_tskid );
+    *p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1;
+    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
+        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
+    self->set_wake_reason( Cyg_Thread::DONE );
+    // note that TMO_POL is not treated specially, though it
+    // happens to work almost as a poll (some sleeping may occur)
+    if ( TMO_FEVR == tmout )
+        Cyg_Thread::counted_sleep();
+    else
+        Cyg_Thread::counted_sleep( (cyg_tick_count)tmout );
+    if ( Cyg_Thread::DONE != self->get_wake_reason() )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+wup_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->counted_wake();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+can_wup ( INT *p_wupcnt, ID tskid )
+{
+    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 );
+    CYG_UIT_PARAMCHECK_PTR( p_wupcnt );
+    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 {
+        cyg_uint32 result = p->cancel_counted_wake();
+        *p_wupcnt = result;
+    }
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+        
+// - Synchronization and Communication Functions
+        
+#ifdef CYGPKG_UITRON_SEMAS
+#if 0 < CYG_UITRON_NUM( SEMAS )
+
+#ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Counting_Semaphore2 )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_sem ( ID semid, T_CSEM *pk_csem )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_csem );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( SEMAS, semid );
+    if ( TA_TFIFO != pk_csem->sematr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] =
+            new( &(CYG_UITRON_OBJS( SEMAS )[ semid - 1 ]) )
+            Cyg_Counting_Semaphore2( (cyg_count32)pk_csem->isemcnt );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_sem ( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_OBJ;
+    }
+    CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] = NULL;
+    p->~Cyg_Counting_Semaphore2();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+sig_sem( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    p->post();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+wai_sem( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    cyg_bool result = p->wait();
+    if ( !result )
+        CYG_UITRON_FAIL_RETURN();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+preq_sem ( ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    cyg_bool result = p->trywait();
+    if ( !result )
+        return E_TMOUT;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+twai_sem ( ID semid, TMO tmout )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    cyg_bool result;
+    if ( TMO_FEVR == tmout )
+        result = p->wait();
+    else if ( TMO_POL == tmout )
+        result = p->trywait();
+    else
+        result = p->wait(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)tmout );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_sem ( T_RSEM *pk_rsem, ID semid )
+{
+    Cyg_Counting_Semaphore2 *p;
+    CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rsem );
+    pk_rsem->exinf  = NADR;
+    pk_rsem->wtsk   = p->waiting();
+    pk_rsem->semcnt = p->peek();
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( SEMAS )
+#endif // CYGPKG_UITRON_SEMAS
+
+#ifdef CYGPKG_UITRON_FLAGS
+#if 0 < CYG_UITRON_NUM( FLAGS )
+
+#ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Flag )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_flg ( ID flgid, T_CFLG *pk_cflg )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cflg );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( FLAGS, flgid );
+    if ( 0 != ((~(TA_WMUL | TA_WSGL)) & pk_cflg->flgatr) )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] =
+            new( &(CYG_UITRON_OBJS( FLAGS )[ flgid - 1 ]) )
+            Cyg_Flag( (Cyg_FlagValue) pk_cflg->iflgptn );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_flg ( ID flgid )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_OBJ;
+    }
+    CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] = NULL;
+    p->~Cyg_Flag();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+set_flg ( ID flgid, UINT setptn )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    p->setbits( setptn );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+clr_flg ( ID flgid, UINT clrptn )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    p->maskbits( clrptn );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    UINT result = p->wait( waiptn, wfmode );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_flgptn  = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    UINT result = p->poll( waiptn, wfmode );
+    if ( ! result )
+        return E_TMOUT;
+    *p_flgptn  = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
+              TMO tmout )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_flgptn );
+    CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // check we can use the wfmode value unchanged
+    CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
+    CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
+    CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
+
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    UINT result;
+    if ( TMO_FEVR == tmout )
+        result = p->wait( waiptn, wfmode );
+    else if ( TMO_POL == tmout )
+        result = p->poll( waiptn, wfmode );
+    else
+        result = p->wait( waiptn, wfmode,
+                          Cyg_Clock::real_time_clock->current_value() +
+                          (cyg_tick_count)tmout );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_flgptn  = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_flg ( T_RFLG *pk_rflg, ID flgid )
+{
+    Cyg_Flag *p;
+    CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rflg );
+    pk_rflg->exinf  = NADR;
+    pk_rflg->wtsk   = p->waiting();
+    pk_rflg->flgptn = p->peek();
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( FLAGS )
+#endif // CYGPKG_UITRON_FLAGS
+
+#ifdef CYGPKG_UITRON_MBOXES
+#if 0 < CYG_UITRON_NUM( MBOXES )
+
+#ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
+CYG_UITRON_NEWFUNCTION( Cyg_Mbox )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mbx ( ID mbxid, T_CMBX* pk_cmbx )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmbx );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MBOXES, mbxid );
+    if ( ((ATR)(TA_TFIFO + TA_MFIFO)) != pk_cmbx->mbxatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] =
+            new( &(CYG_UITRON_OBJS( MBOXES )[ mbxid - 1 ]) )
+            Cyg_Mbox();
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mbx ( ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_OBJ;
+    }
+    CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] = NULL;
+    p->~Cyg_Mbox();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
+
+// This bit of unpleasantness is to allow uITRON programs to send a NULL
+// message - if permitted by the parameter checking.
+// 
+// NULL is used internally to mean no message; but -1 is fine.  So we send
+// a NULL as a NADR and if we see a NULL coming back, change it to a NADR.
+//
+// One hopes that often this will be optimized out, since the one or both
+// of these being true has been detected and errored out just above.
+
+#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;						\
+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;						\
+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
+#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;						\
+CYG_MACRO_END
+
+CYG_UIT_FUNC_INLINE
+ER
+snd_msg ( ID mbxid, T_MSG *pk_msg )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_msg );
+    CYG_UIT_TMSG_FIXUP_IN( pk_msg );
+    cyg_bool result = p->tryput( (void *)pk_msg );
+    if ( ! result )
+        return E_QOVR;
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+rcv_msg ( T_MSG **ppk_msg, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    T_MSG *result = (T_MSG *)p->get();
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+prcv_msg ( T_MSG **ppk_msg, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    T_MSG *result = (T_MSG *)p->tryget();
+    if ( ! result )
+        return E_TMOUT;
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( ppk_msg );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    T_MSG *result;
+    if ( TMO_FEVR == tmout )
+        result = (T_MSG *)p->get();
+    else if ( TMO_POL == tmout )
+        result = (T_MSG *)p->tryget();
+    else
+        result = (T_MSG *)p->get(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)tmout );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    CYG_UIT_TMSG_FIXUP_OUT( result );
+    *ppk_msg = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mbx ( T_RMBX *pk_rmbx, ID mbxid )
+{
+    Cyg_Mbox *p;
+    CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmbx );
+    pk_rmbx->exinf  = NADR;
+    pk_rmbx->wtsk   = p->waiting_to_get();
+    pk_rmbx->pk_msg = (T_MSG *)p->peek_item();
+    CYG_UIT_TMSG_FIXUP_ALL( pk_rmbx->pk_msg );
+    return E_OK;
+}
+
+#undef CYG_UIT_TMSG_FIXUP_IN
+#undef CYG_UIT_TMSG_FIXUP_OUT
+#undef CYG_UIT_TMSG_FIXUP_ALL
+        
+#endif // 0 < CYG_UITRON_NUM( MBOXES )
+#endif // CYGPKG_UITRON_MBOXES
+
+// - 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
+              cmsgsz );
+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
+              cmsgsz, TMO tmout );
+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
+              acpptn );
+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	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 );
+#endif
+
+CYG_UIT_FUNC_INLINE
+ER
+loc_cpu ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    Cyg_Interrupt::disable_interrupts();
+    if ( 0 == Cyg_Scheduler::get_sched_lock() )
+        Cyg_Scheduler::lock();
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+unl_cpu ( void )
+{
+    CYG_UITRON_CHECK_TASK_CONTEXT();
+    Cyg_Interrupt::enable_interrupts();
+    if ( 0 < Cyg_Scheduler::get_sched_lock() )
+        Cyg_Scheduler::unlock();
+    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 );
+#endif
+        
+// - Memorypool Management Functions
+#ifdef CYGPKG_UITRON_MEMPOOLVAR
+#if 0 < CYG_UITRON_NUM( MEMPOOLVAR )
+
+#ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Variable )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mpl ( ID mplid, T_CMPL *pk_cmpl )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmpl );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLVAR, mplid );
+    Cyg_Mempool_Variable *p = &(CYG_UITRON_OBJS( MEMPOOLVAR )[ mplid - 1 ]);
+    cyg_uint8 *base;
+    cyg_int32 size;
+    CYG_ADDRWORD scratch;
+    // preserve the original memory area to use
+    p->get_arena( base, size, scratch );
+
+    if ( size < pk_cmpl->mplsz )
+        ret = E_NOMEM;
+    else if ( TA_TFIFO != pk_cmpl->mplatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] =
+            new( p ) Cyg_Mempool_Variable( base, size );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mpl ( ID mplid )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_OBJ;
+    }
+    CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] = NULL;
+    p->~Cyg_Mempool_Variable();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+get_blk ( VP *p_blk, ID mplid, INT blksz )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    VP result = (VP)p->alloc(blksz);
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_blk = result;
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+pget_blk ( VP *p_blk, ID mplid, INT blksz )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    VP result = (VP)p->try_alloc(blksz);
+    if ( ! result )
+        return E_TMOUT;
+    *p_blk = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blk );
+    CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    VP result;
+    if ( TMO_FEVR == tmout )
+        result = p->alloc(blksz);
+    else if ( TMO_POL == tmout )
+        result = p->try_alloc(blksz);
+    else
+        result = p->alloc( blksz,
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)tmout );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_blk = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+rel_blk ( ID mplid, VP blk )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( blk );
+    cyg_bool result = p->free( (cyg_uint8 *)blk, 0 );
+    if ( ! result )
+        return E_PAR;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mpl ( T_RMPL *pk_rmpl, ID mplid )
+{
+    Cyg_Mempool_Variable *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmpl );
+    pk_rmpl->exinf = NADR;
+    pk_rmpl->wtsk = p->waiting();
+    pk_rmpl->frsz = p->get_freemem();
+    
+    cyg_uint8 *base;
+    cyg_int32 size;
+    CYG_ADDRWORD maxfree;
+    p->get_arena(base, size, maxfree);
+    pk_rmpl->maxsz = maxfree;
+
+    return E_OK;
+}
+
+#endif // 0 < CYG_UITRON_NUM( MEMPOOLVAR )
+#endif // CYGPKG_UITRON_MEMPOOLVAR
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED
+#if 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
+
+#ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Fixed )
+
+CYG_UIT_FUNC_INLINE
+ER
+cre_mpf ( ID mpfid, T_CMPF *pk_cmpf )
+{
+    ER ret = E_OK;
+    CYG_UIT_PARAMCHECK_PTR( pk_cmpf );
+    CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLFIXED, mpfid );
+    Cyg_Mempool_Fixed *p = &(CYG_UITRON_OBJS( MEMPOOLFIXED )[ mpfid - 1 ]);
+    cyg_uint8 *base;
+    cyg_int32 size;
+    CYG_ADDRWORD scratch;
+    // preserve the original memory area to use
+    p->get_arena( base, size, scratch );
+
+    if ( size < (pk_cmpf->blfsz * (pk_cmpf->mpfcnt + 1)) )
+        ret = E_NOMEM;
+    else if ( TA_TFIFO != pk_cmpf->mpfatr )
+        ret = E_RSATR;
+    else
+        CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] =
+            new( p )
+            Cyg_Mempool_Fixed( base, size,
+                               (CYG_ADDRWORD)pk_cmpf->blfsz );
+    Cyg_Scheduler::unlock();
+    return ret;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+del_mpf ( ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    Cyg_Scheduler::lock();
+    // deal with the race condition here
+    if ( p != CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] ) {
+        Cyg_Scheduler::unlock();
+        return E_OBJ;
+    }
+    CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] = NULL;
+    p->~Cyg_Mempool_Fixed();
+    Cyg_Scheduler::unlock();
+    return E_OK;
+}
+#endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
+
+CYG_UIT_FUNC_INLINE
+ER
+get_blf ( VP *p_blf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    VP result = (VP)p->alloc();
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN();
+    *p_blf = result;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+pget_blf ( VP *p_blf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    VP result = (VP)p->try_alloc();
+    if ( ! result )
+        return E_TMOUT;
+    *p_blf = result;
+    return E_OK;
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+tget_blf ( VP *p_blf, ID mpfid, TMO tmout )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( p_blf );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
+    // do this now for the case when no sleeping actually occurs
+    Cyg_Thread *self = Cyg_Thread::self();
+    self->set_wake_reason( Cyg_Thread::TIMEOUT );
+    VP result;
+    if ( TMO_FEVR == tmout )
+        result = p->alloc();
+    else if ( TMO_POL == tmout )
+        result = p->try_alloc();
+    else
+        result = p->alloc(
+            Cyg_Clock::real_time_clock->current_value() +
+            (cyg_tick_count)tmout );
+    if ( ! result )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    *p_blf = result;
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+CYG_UIT_FUNC_INLINE
+ER
+rel_blf ( ID mpfid, VP blf )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( blf );
+    cyg_bool result = p->free( (cyg_uint8 *)blf );
+    if ( ! result )
+        return E_PAR;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_mpf ( T_RMPF *pk_rmpf, ID mpfid )
+{
+    Cyg_Mempool_Fixed *p;
+    CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_rmpf );
+    pk_rmpf->exinf = NADR;
+    pk_rmpf->wtsk = p->waiting();
+
+    cyg_int32 blocksize = p->get_blocksize();
+    pk_rmpf->frbcnt = p->get_freemem() / blocksize;
+    // these two are "implementation dependent" ie. eCos only
+    pk_rmpf->numbcnt = p->get_totalmem() / blocksize;
+    pk_rmpf->bsize = blocksize;
+
+    return E_OK;
+}
+        
+#endif // 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
+#endif // CYGPKG_UITRON_MEMPOOLFIXED
+
+// - Time Management Functions
+        
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+CYG_UIT_FUNC_INLINE
+ER
+set_tim ( SYSTIME *pk_tim )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_tim );
+    Cyg_Clock::real_time_clock->set_value( *pk_tim );
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+get_tim ( SYSTIME *pk_tim )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_tim );
+    *pk_tim = Cyg_Clock::real_time_clock->current_value();
+    return E_OK;
+}
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
+
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+CYG_UIT_FUNC_INLINE
+ER
+dly_tsk ( DLYTIME dlytim )
+{
+    CYG_UIT_PARAMCHECK( 0 <= dlytim, E_PAR );
+    CYG_UITRON_CHECK_DISPATCH_ENABLED();
+    if ( 0 >= dlytim )
+        return E_OK;
+    Cyg_Thread *self = Cyg_Thread::self();
+    CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
+    self->delay( dlytim );
+    if ( Cyg_Thread::DONE != self->get_wake_reason() )
+        CYG_UITRON_FAIL_RETURN_SELF( self );
+    return E_OK;
+}
+#endif // CYGFUN_KERNEL_THREADS_TIMER
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+#ifdef CYGPKG_UITRON_CYCLICS
+#if 0 < CYG_UITRON_NUM( CYCLICS )
+CYG_UIT_FUNC_INLINE
+ER
+def_cyc ( HNO cycno, T_DCYC *pk_dcyc )
+{
+    // pk_dcyc->cycatr is ignored
+    // The only relevant attribute is TA_HLNG/TA_ASM.
+    // This can be ignored as assembler routines are defined to be
+    // more conservative with registers than the procedure call standard.
+
+    Cyg_Timer *p;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    CYG_UIT_PARAMCHECK( NULL != pk_dcyc, E_PAR );
+#endif
+    if( NADR == pk_dcyc ) {
+        p->~Cyg_Timer();
+        return E_OK;
+    }
+    CYG_UIT_PARAMCHECK( 0 == (pk_dcyc->cycact & ~TCY_ON), E_PAR );
+    CYG_UIT_PARAMCHECK( 0 < pk_dcyc->cyctim, E_PAR );
+    p->initialize(
+        Cyg_Clock::real_time_clock,
+        (cyg_alarm_fn *)pk_dcyc->cychdr,
+        (CYG_ADDRWORD)pk_dcyc->exinf,
+        Cyg_Clock::real_time_clock->current_value() + pk_dcyc->cyctim,
+        pk_dcyc->cyctim,
+        pk_dcyc->cycact);
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+act_cyc ( HNO cycno, UINT cycact )
+{
+    Cyg_Timer *p;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+    CYG_UIT_PARAMCHECK( 0 == (cycact & ~(TCY_ON | TCY_INI)), E_PAR );
+    p->activate(cycact);
+    return E_OK;
+}
+
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_cyc ( T_RCYC *pk_rcyc, HNO cycno )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t;
+    CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+    CYG_UIT_PARAMCHECK_PTR( pk_rcyc );
+
+    pk_rcyc->exinf = (VP)p->get_data();
+    Cyg_Scheduler::lock();
+    t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
+    Cyg_Scheduler::unlock();
+    pk_rcyc->lfttim = t;
+    pk_rcyc->cycact = (UINT)p->is_enabled();
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( CYCLICS )
+#endif // CYGPKG_UITRON_CYCLICS
+
+#ifdef CYGPKG_UITRON_ALARMS
+#if 0 < CYG_UITRON_NUM( ALARMS )
+CYG_UIT_FUNC_INLINE
+ER
+def_alm ( HNO almno, T_DALM *pk_dalm )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t, now;
+    CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
+#ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
+    CYG_UIT_PARAMCHECK( NULL != pk_dalm, E_PAR );
+#endif
+    if( NADR == pk_dalm ) {
+        p->~Cyg_Timer();
+        return E_OK;
+    }
+
+    CYG_UIT_PARAMCHECK( 0 == (pk_dalm->tmmode & ~TTM_REL), E_PAR );
+
+    // make the time arithmetic safe without locking
+    now = Cyg_Clock::real_time_clock->current_value();
+    t = pk_dalm->almtim;
+    if( TTM_REL & pk_dalm->tmmode )
+        t += now;
+
+    CYG_UIT_PARAMCHECK( now < t, E_PAR );
+
+    p->initialize(Cyg_Clock::real_time_clock,
+                  (cyg_alarm_fn *)pk_dalm->almhdr,
+                  (CYG_ADDRWORD)pk_dalm->exinf,
+                  t, 0, Cyg_Timer::ENABLE);
+
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_alm ( T_RALM *pk_ralm, HNO almno )
+{
+    Cyg_Timer *p;
+    cyg_tick_count t;
+
+    CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
+    CYG_UIT_PARAMCHECK_PTR( pk_ralm );
+    CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
+
+    Cyg_Scheduler::lock();
+    t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
+    Cyg_Scheduler::unlock();
+    pk_ralm->exinf  = (VP)p->get_data();
+    pk_ralm->lfttim = t;
+    return E_OK;
+}
+#endif // 0 < CYG_UITRON_NUM( ALARMS )
+#endif // CYGPKG_UITRON_ALARMS
+
+#endif // CYGVAR_KERNEL_COUNTERS_CLOCK
+        
+// - System Management Functions
+        
+CYG_UIT_FUNC_INLINE
+ER
+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;
+   
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_sys ( T_RSYS *pk_rsys )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_rsys );
+    if ( ! Cyg_Interrupt::interrupts_enabled() )
+        // CPU is locked
+        pk_rsys->sysstat = TSS_LOC;
+    else
+        pk_rsys->sysstat =
+            (Cyg_Scheduler::get_sched_lock() == 0) ? TSS_TSK : TSS_DDSP;
+    return E_OK;
+}
+
+CYG_UIT_FUNC_INLINE
+ER
+ref_cfg ( T_RCFG *pk_rcfg )
+{
+    CYG_UIT_PARAMCHECK_PTR( pk_rcfg );
+    // no details here yet
+    return E_OK;
+}
+
+#if 0 // NOT SUPPORTED
+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,
+               INT datsz );
+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 );
+#endif
+
+// ========================================================================
+
+#endif // CYGPKG_UITRON
+
+#endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
+
+#endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
+//EOF uit_func.inl