📄 uit_func.inl
字号:
#ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
#define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
//===========================================================================
//
// uit_func.inl
//
// uITRON compatibility functions
//
//===========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
//
// eCos is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 2 or (at your option) any later version.
//
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
// for more details.
//
// You should have received a copy of the GNU General Public License along
// with eCos; if not, write to the Free Software Foundation, Inc.,
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or inline functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. However the source code for this file must still be made available
// in accordance with section (3) of the GNU General Public License.
//
// This exception does not invalidate any other reasons why a work based on
// this file might be covered by the GNU General Public License.
//
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
// at http://sources.redhat.com/ecos/ecos-license/
// -------------------------------------------
//####ECOSGPLCOPYRIGHTEND####
//===========================================================================
//#####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>
// ------------------------------------------------------------------------
// 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_); \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_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_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 )
// ------------------------------------------------------------------------
// Timing: is it in eCos clock ticks or milliSeconds (or something else?)
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
#ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
extern Cyg_Clock::converter uit_clock_to_system;
extern Cyg_Clock::converter uit_clock_from_system;
#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) \Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_to_system )
#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) \Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_from_system )
// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) \Cyg_Clock::convert( (t), &uit_clock_to_system )
#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) \Cyg_Clock::convert( (t), &uit_clock_from_system )
#else // Time is whatever the system clock is doing:
// Straight through - int (cyg_int32) argument versions:
#define CYG_UITRON_TIME_UIT_TO_SYS32( t ) ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT32( t ) ( t )
// long (cyg_uint64) versions:
#define CYG_UITRON_TIME_UIT_TO_SYS64( t ) ( t )
#define CYG_UITRON_TIME_SYS_TO_UIT64( t ) ( t )
#endif
#endif // CYGVAR_KERNEL_COUNTERS_CLOCK - otherwise these should not be used.
// ------------------------------------------------------------------------
// 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();
#ifdef CYGIMP_THREAD_PRIORITY
// and record the initial priority outside the task too.
CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
#endif
}
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();
// 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
CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -