Mercurial > ecos
diff packages/kernel/current/include/thread.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/kernel/current/include/thread.inl @@ -0,0 +1,473 @@ +#ifndef CYGONCE_KERNEL_THREAD_INL +#define CYGONCE_KERNEL_THREAD_INL + +//========================================================================== +// +// thread.inl +// +// Thread class inlines +// +//========================================================================== +//####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): nickg +// Contributors: nickg +// Date: 1997-09-09 +// Purpose: Define inlines for thread classes +// Description: Inline implementations of various member functions defined +// in various Thread classes. +// Usage: +// #include <cyg/kernel/thread.hxx> +// ... +// #include <cyg/kernel/thread.inl> +// ... + +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include <cyg/kernel/thread.hxx> +#include <cyg/hal/hal_arch.h> + +#include <cyg/kernel/clock.inl> + +//========================================================================== +// Inlines for Cyg_HardwareThread + +// ------------------------------------------------------------------------- +// Attach a stack to this thread. If there is a HAL defined macro to +// do this, then we use that, otherwise assume a falling stack. +inline void Cyg_HardwareThread::attach_stack(CYG_ADDRESS s_base, cyg_uint32 s_size) +{ + stack_base = s_base; + stack_size = s_size; +#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT + stack_limit = s_base; +#endif + +#ifdef HAL_THREAD_ATTACH_STACK + + HAL_THREAD_ATTACH_STACK(stack_ptr, stack_base, stack_size); + +#else + + stack_ptr = stack_base + stack_size; + +#endif +} + +// ------------------------------------------------------------------------- + +inline Cyg_HardwareThread::Cyg_HardwareThread( + cyg_thread_entry *e_point, // entry point function + CYG_ADDRWORD e_data, // entry data + cyg_ucount32 s_size, // stack size, 0 = use default + CYG_ADDRESS s_base // stack base, NULL = allocate +) +{ + entry_point = e_point; + entry_data = e_data; +#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT + saved_context = 0; +#endif + + attach_stack( s_base, s_size ); +}; + +// ------------------------------------------------------------------------- +// get the size/base of this thread's stack + +inline CYG_ADDRESS +Cyg_HardwareThread::get_stack_base() +{ + return stack_base; +} + +inline cyg_uint32 +Cyg_HardwareThread::get_stack_size() +{ + return stack_size; +} + +// ------------------------------------------------------------------------- + +#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT + +// Return the current saved state for this thread. +inline HAL_SavedRegisters *Cyg_HardwareThread::get_saved_context() +{ + HAL_SavedRegisters *regs; + if( saved_context != 0 ) regs = saved_context; + else HAL_THREAD_GET_SAVED_REGISTERS( stack_ptr, regs ); + return regs; +} + +inline void Cyg_HardwareThread::set_saved_context(HAL_SavedRegisters *ctx) +{ + saved_context = ctx; +} + +#endif + +// ------------------------------------------------------------------------- +// (declare this inline before its first use) + +inline cyg_uint16 Cyg_Thread::get_unique_id() +{ + return unique_id; +} + +// ------------------------------------------------------------------------- +// Initialize the context of this thread. + +inline void Cyg_HardwareThread::init_context(Cyg_Thread *thread) +{ +#ifdef CYGPKG_INFRA_DEBUG + cyg_uint32 threadid = thread->get_unique_id()*0x01010000; +#else + cyg_uint32 threadid = 0x11110000; +#endif + HAL_THREAD_INIT_CONTEXT( stack_ptr, thread, thread_entry, threadid ); +} + + + +// ------------------------------------------------------------------------- +// Load thread context without saving current context. +// This function is only really here for completeness, the +// kernel generally calls the HAL macros directly. + +inline void Cyg_HardwareThread::load_context() +{ + CYG_ADDRESS dummy_stack_ptr; + + HAL_THREAD_SWITCH_CONTEXT( &dummy_stack_ptr, &stack_ptr ); +} + +// ------------------------------------------------------------------------- +// Save current thread's context and load that of the given next thread. +// This function is only really here for completeness, the +// kernel generally calls the HAL macros directly. + +inline void Cyg_HardwareThread::switch_context(Cyg_HardwareThread *next) +{ + HAL_THREAD_SWITCH_CONTEXT( &stack_ptr, &next->stack_ptr ); +} + +// ------------------------------------------------------------------------- +// Get and set entry_data. + +inline void Cyg_HardwareThread::set_entry_data( CYG_ADDRWORD data ) +{ + entry_data = data; +} + +inline CYG_ADDRWORD Cyg_HardwareThread::get_entry_data() +{ + return entry_data; +} + +// ------------------------------------------------------------------------- +// Allocate some memory at the lower end of the stack +// by moving the stack limit pointer. + +#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT + +inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size) +{ + stack_limit += size; + return (void *)(stack_limit - size); +} + + +inline CYG_ADDRESS +Cyg_HardwareThread::get_stack_limit() +{ + return stack_limit; +} + +#endif + +//========================================================================== +// Inlines for Cyg_Thread class + +inline Cyg_Thread *Cyg_Thread::self() +{ + return Cyg_Scheduler::get_current_thread(); +} + +// ------------------------------------------------------------------------- + +inline void Cyg_Thread::yield() +{ + self()->Cyg_SchedThread::yield(); +} + +// ------------------------------------------------------------------------- + +#ifdef CYGSEM_KERNEL_SCHED_MLQUEUE +inline void +Cyg_Thread::rotate_queue( cyg_priority pri ) +{ + self()->Cyg_SchedThread::rotate_queue( pri ); +} +#endif + +// ------------------------------------------------------------------------- + +#ifdef CYGIMP_THREAD_PRIORITY + +inline cyg_priority Cyg_Thread::get_priority() +{ +#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INHERITANCE_SIMPLE + + // If we have an inherited priority, return our original + // priority rather than the current one. + + if( priority_inherited ) return original_priority; + +#endif + + return priority; +} + +// Return the actual dispatching priority of the thread +// regardless of inheritance or scheduling concerns. +inline cyg_priority Cyg_Thread::get_current_priority() +{ + return priority; +} + +#endif + +// ------------------------------------------------------------------------- + +inline void Cyg_Thread::set_sleep_reason( cyg_reason reason) +{ + self()->sleep_reason = reason; + self()->wake_reason = NONE; +} + +// ------------------------------------------------------------------------- + +inline Cyg_Thread::cyg_reason Cyg_Thread::get_sleep_reason() +{ + return sleep_reason; +} + +// ------------------------------------------------------------------------- + +inline void Cyg_Thread::set_wake_reason( cyg_reason reason ) +{ + sleep_reason = NONE; + wake_reason = reason; +} + +// ------------------------------------------------------------------------- + +inline Cyg_Thread::cyg_reason Cyg_Thread::get_wake_reason() +{ + return wake_reason; +} + +// ------------------------------------------------------------------------- + +inline void Cyg_Thread::set_timer( + cyg_tick_count trigger, + cyg_reason reason +) +{ +#ifdef CYGFUN_KERNEL_THREADS_TIMER + self()->sleep_reason = reason; + self()->wake_reason = NONE; + self()->timer.initialize( trigger); +#endif +} + +// ------------------------------------------------------------------------- + +inline void Cyg_Thread::clear_timer() +{ +#ifdef CYGFUN_KERNEL_THREADS_TIMER + self()->timer.disable(); +#endif +} + +// ------------------------------------------------------------------------- + +#ifdef CYGVAR_KERNEL_THREADS_DATA + +inline CYG_ADDRWORD Cyg_Thread::get_data( cyg_ucount32 index ) +{ + CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, + "Per thread data index out of bounds"); + CYG_ASSERT( (thread_data_map & (1<<index)) == 0, + "Unallocated index used"); + + return self()->thread_data[index]; +} + +inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( cyg_ucount32 index ) +{ + CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, + "Per thread data index out of bounds"); + CYG_ASSERT( (thread_data_map & (1<<index)) == 0, + "Unallocated index used"); + + return &(self()->thread_data[index]); +} + +inline void Cyg_Thread::set_data( cyg_ucount32 index, CYG_ADDRWORD data ) +{ + CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX, + "Per thread data index out of bounds"); + CYG_ASSERT( (thread_data_map & (1<<index)) == 0, + "Unallocated index used"); + + thread_data[index] = data; +} + +#endif + +// ------------------------------------------------------------------------- + +#ifdef CYGVAR_KERNEL_THREADS_NAME + +inline char *Cyg_Thread::get_name() +{ + return name; +} + +#endif + +// ------------------------------------------------------------------------- + +#ifdef CYGVAR_KERNEL_THREADS_LIST + +inline Cyg_Thread *Cyg_Thread::get_list_head() +{ + return thread_list?thread_list->list_next:0; +} + +inline Cyg_Thread *Cyg_Thread::get_list_next() +{ + return (this==thread_list)?0:list_next; +} + +#endif + + +// ------------------------------------------------------------------------- + +#ifdef CYGPKG_KERNEL_EXCEPTIONS + +inline void Cyg_Thread::register_exception( + cyg_code exception_number, // exception number + cyg_exception_handler handler, // handler function + CYG_ADDRWORD data, // data argument + cyg_exception_handler **old_handler, // handler function + CYG_ADDRWORD *old_data // data argument + ) +{ + self()->exception_control.register_exception( + exception_number, + handler, + data, + old_handler, + old_data + ); +} + +inline void Cyg_Thread::deregister_exception( + cyg_code exception_number // exception number + ) +{ + self()->exception_control.deregister_exception( + exception_number + ); +} + +#endif + +//========================================================================== +// Inlines for Cyg_ThreadTimer class + +// ------------------------------------------------------------------------- +#if defined(CYGFUN_KERNEL_THREADS_TIMER) && defined(CYGVAR_KERNEL_COUNTERS_CLOCK) + +inline Cyg_ThreadTimer::Cyg_ThreadTimer( + Cyg_Thread *th + ) + : Cyg_Alarm(Cyg_Clock::real_time_clock, + &alarm, + CYG_ADDRWORD(this) + ) +{ + thread = th; +} + +#endif + +//========================================================================== +// Inlines for Cyg_ThreadQueue class + + +inline void Cyg_ThreadQueue::enqueue(Cyg_Thread *thread) +{ + Cyg_ThreadQueue_Implementation::enqueue(thread); +} + +// ------------------------------------------------------------------------- + +inline Cyg_Thread *Cyg_ThreadQueue::highpri() +{ + return Cyg_ThreadQueue_Implementation::highpri(); +} + +// ------------------------------------------------------------------------- + +inline Cyg_Thread *Cyg_ThreadQueue::dequeue() +{ + return Cyg_ThreadQueue_Implementation::dequeue(); +} + +// ------------------------------------------------------------------------- + +inline void Cyg_ThreadQueue::remove(Cyg_Thread *thread) +{ + Cyg_ThreadQueue_Implementation::remove(thread); +} + +// ------------------------------------------------------------------------- + +inline cyg_bool Cyg_ThreadQueue::empty() +{ + return Cyg_ThreadQueue_Implementation::empty(); +} + +// ------------------------------------------------------------------------- +#endif // ifndef CYGONCE_KERNEL_THREAD_INL +// EOF thread.inl
