⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 thread.inl

📁 ecos实时嵌入式操作系统
💻 INL
📖 第 1 页 / 共 2 页
字号:
#ifndef CYGONCE_KERNEL_THREAD_INL#define CYGONCE_KERNEL_THREAD_INL//==========================================================================////      thread.inl////      Thread class inlines////==========================================================================//####ECOSGPLCOPYRIGHTBEGIN####// -------------------------------------------// This file is part of eCos, the Embedded Configurable Operating System.// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.// Copyright (C) 2003 Gary Thomas//// 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):   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>#include <cyg/infra/diag.h>#ifndef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE#define CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE (0)#endif//==========================================================================// Inlines for Cyg_HardwareThread// -------------------------------------------------------------------------// get the size/base of this thread's stackinline CYG_ADDRESSCyg_HardwareThread::get_stack_base(){    return stack_base - CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;}inline cyg_uint32Cyg_HardwareThread::get_stack_size(){    return stack_size + 2 * CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;}// -------------------------------------------------------------------------// Check the stack bounds of this thread:#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKINGinline void Cyg_HardwareThread::check_stack(void){    cyg_uint32 sig = (cyg_uint32)this;    cyg_uint32 *base = (cyg_uint32 *)get_stack_base();    cyg_uint32 *top =  (cyg_uint32 *)(stack_base + stack_size);    cyg_ucount32 i;    CYG_INSTRUMENT_THREAD(CHECK_STACK, base, top );        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base not word aligned" );    CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top not word aligned" );    CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base,                "Stack_ptr below base" );    CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size),                "Stack_ptr above top" );    for ( i = 0;          i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);          i++ ) {        if ((sig ^ (i * 0x01010101)) != base[i]) {            char *reason = "Stack base corrupt";            diag_printf("%s - i: %d\n", reason, i);            diag_dump_buf(base, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);            CYG_FAIL(reason);        }        if ((sig ^ (i * 0x10101010)) != top[i]) {            char *reason = "Stack top corrupt";            diag_printf("%s - i: %d\n", reason, i);            diag_dump_buf(top, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);            CYG_FAIL(reason);        }    }            #ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT    // we won't have added check data above the stack limit if it hasn't    // been incremented    if (stack_limit != stack_base) {        CYG_ADDRESS limit = stack_limit;        // the limit will be off by the check data size, so lets correct it        limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;                // determine base of check data by rounding up to nearest word aligned        // address if not already aligned        cyg_uint32 *p = (cyg_uint32 *)((limit + 3) & ~3);        // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1);                for ( i = 0;              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);              i++ ) {            if ((sig ^ (i * 0x01010101)) != p[i]) {                char *reason = "Gap between stack limit and base corrupt";                diag_printf("%s - i: %d\n", reason, i);                diag_dump_buf(p, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);                CYG_FAIL(reason);            }        }    }#endif}#endif// -------------------------------------------------------------------------// Measure the stack usage of the thread#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENTinline cyg_uint32 Cyg_HardwareThread::measure_stack_usage(void){#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT    CYG_WORD *base = (CYG_WORD *)stack_limit;    cyg_uint32 size = (stack_size - (stack_limit-stack_base))/sizeof(CYG_WORD);#else    CYG_WORD *base = (CYG_WORD *)stack_base;    cyg_uint32 size = stack_size/sizeof(CYG_WORD);#endif    cyg_ucount32 i;    // Work up the stack comparing with the preset value    // We assume the stack grows downwards, hmm...    for (i=0; i<size; i++) {	if (base[i] != 0xDEADBEEF)	  break;    }    return (size - i)*sizeof(CYG_WORD);}#endif// -------------------------------------------------------------------------// 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){#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM    CYG_ASSERT( s_size >= CYGNUM_HAL_STACK_SIZE_MINIMUM,                "Stack size too small");#endif#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING    {        cyg_uint32 sig = (cyg_uint32)this;        cyg_uint32 *base = (cyg_uint32 *)s_base;        cyg_uint32 *top =  (cyg_uint32 *)(s_base + s_size -            CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);        unsigned int i;        CYG_INSTRUMENT_THREAD(ATTACH_STACK, base, top );                CYG_ASSERT( NULL != base, "stack base non-NULL" );        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base alignment" );        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top alignment" );        for ( i = 0;              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);              i++ ) {            base[i] = (sig ^ (i * 0x01010101));             top[i] = (sig ^ (i * 0x10101010));        }                    // This check for overlap of the two signature areas also detects        // wrap round zero of the size in the unsigned subtraction below.        CYG_ASSERT( &base[i] < &top[0], "Stack is so small size wrapped" );        // Use this 'i' expression to round correctly to whole words.        s_base += i * sizeof(cyg_uint32);        s_size -= i * sizeof(cyg_uint32) * 2;        // This is a complete guess, the 256; the point is to assert early that        // this might go badly wrong.  It would not detect wrap of unsigned size.        CYG_ASSERT( s_size >= 256,                    "Stack size too small after allocating checking buffer");    }#endif#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT    {	CYG_WORD *base = (CYG_WORD *)s_base;	cyg_uint32 size = s_size/sizeof(CYG_WORD);	cyg_ucount32 i;	// initialize all of stack with known value - don't choose 0	// could do with pseudo value as above, but this way, checking	// is faster	for (i=0; i<size; i++) {		base[i] = 0xDEADBEEF;	}	// Don't bother about the case when the stack isn't a multiple of	// CYG_WORD in size. Since it's at the top of the stack, it will	// almost certainly be overwritten the instant the thread starts	// anyway.    }#endif    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#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING    check_stack();#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 );};// -------------------------------------------------------------------------#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 );}// -------------------------------------------------------------------------// 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -