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

📄 kapi.cxx

📁 eCos/RedBoot for勤研ARM AnywhereII(4510) 含全部源代码
💻 CXX
📖 第 1 页 / 共 3 页
字号:
//==========================================================================
//
//      common/kapi.cxx
//
//      C API Implementation
//
//==========================================================================
//####ECOSGPLCOPYRIGHTBEGIN####
// -------------------------------------------
// This file is part of eCos, the Embedded Configurable Operating System.
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
// Copyright (C) 2002 Nick Garnett
// Copyright (C) 2003 Jonathan Larmour
//
// 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, dsm
// Contributors:        nickg
// Date:        1998-03-02
// Purpose:     C API Implementation
// Description: C++ implementation of the C API
//              
//
//####DESCRIPTIONEND####
//
//==========================================================================

#include <pkgconf/kernel.h>

#ifdef CYGFUN_KERNEL_API_C

#include <cyg/kernel/ktypes.h>         // base kernel types
#include <cyg/infra/cyg_trac.h>        // tracing macros
#include <cyg/infra/cyg_ass.h>         // assertion macros
#include <cyg/kernel/instrmnt.h>       // instrumentation
#include <cyg/kernel/diag.h>

#include <cyg/kernel/thread.hxx>
#include <cyg/kernel/thread.inl>       // thread inlines
#include <cyg/kernel/sched.hxx>
#include <cyg/kernel/intr.hxx>
#include <cyg/kernel/clock.hxx>

#include <cyg/kernel/sema.hxx>
#include <cyg/kernel/flag.hxx>
#include <cyg/kernel/mutex.hxx>
#include <cyg/kernel/mbox.hxx>

#include <cyg/kernel/sched.inl>        // scheduler inlines
#include <cyg/kernel/clock.inl>        // clock inlines

#include <cyg/kernel/kapi.h>           // C API

// -------------------------------------------------------------------------
// Magic new function

inline void *operator new(size_t size, void *ptr)
{
    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
    return ptr;
}

// -------------------------------------------------------------------------

#ifdef CYGDBG_USE_ASSERTS

#define CYG_ASSERT_SIZES(cstruct, cxxstruct)                      \CYG_MACRO_START                                                   \    char *msg = "Size of C struct " #cstruct                      \                       " != size of C++ struct " #cxxstruct ;     \    CYG_ASSERT( sizeof(cstruct) == sizeof(cxxstruct) , msg );     \CYG_MACRO_END

#else

#define CYG_ASSERT_SIZES(cstruct, cxxstruct)

#endif

/*---------------------------------------------------------------------------*/
/* Scheduler operations */

/* Starts scheduler with created threads.  Never returns. */
externC void cyg_scheduler_start(void) __THROW
{
    Cyg_Scheduler::start();
}

/* Lock the scheduler. */
externC void cyg_scheduler_lock(void) __THROW
{
    Cyg_Scheduler::lock();
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
                "Scheduler overlocked" );
}

/* Lock the scheduler, but never more than level=1. */
externC void cyg_scheduler_safe_lock(void) __THROW
{
    Cyg_Scheduler::lock();
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
    if (slock > 1)
        Cyg_Scheduler::unlock();
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
                "Scheduler overlocked" );
}

/* Unlock the scheduler. */
externC void cyg_scheduler_unlock(void) __THROW
{
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
    CYG_ASSERT( 0 < slock, "Scheduler not locked" );
    // And program defensively too:
    if ( 0 < slock )
        Cyg_Scheduler::unlock();
}

/* Read the scheduler lock value. */
externC cyg_ucount32 cyg_scheduler_read_lock(void) __THROW
{
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
    return slock;
}

/*---------------------------------------------------------------------------*/
/* Thread operations */

externC void cyg_thread_create(
    cyg_addrword_t      sched_info,             /* scheduling info (eg pri)  */
    cyg_thread_entry_t  *entry,                 /* entry point function      */
    cyg_addrword_t      entry_data,             /* entry data                */
    char                *name,                  /* optional thread name      */
    void                *stack_base,            /* stack base, NULL = alloc  */
    cyg_ucount32        stack_size,             /* stack size, 0 = default   */
    cyg_handle_t        *handle,                /* returned thread handle    */
    cyg_thread          *thread                 /* put thread here           */
) __THROW
{
    CYG_ASSERT_SIZES( cyg_thread, Cyg_Thread );

    Cyg_Thread *t = new((void *)thread) Cyg_Thread (
        (CYG_ADDRWORD) sched_info,
        (cyg_thread_entry *)entry,
        (CYG_ADDRWORD) entry_data,
        name,
        (CYG_ADDRWORD) stack_base,
        stack_size
        );
    t=t;
    
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
    *handle = (cyg_handle_t)thread;
}

externC void cyg_thread_exit() __THROW
{
    Cyg_Thread::exit();
}

externC cyg_bool_t cyg_thread_delete( cyg_handle_t thread ) __THROW
{
    Cyg_Thread *th = (Cyg_Thread *)thread;
    if( th->get_state() != Cyg_Thread::EXITED )
        th->kill(); // encourage it to terminate
    if( th->get_state() != Cyg_Thread::EXITED )
        return false; // it didn't run yet, leave it up to the app to fix
    th->~Cyg_Thread();
    return true;
}

externC void cyg_thread_suspend(cyg_handle_t thread) __THROW
{
    ((Cyg_Thread *)thread)->suspend();
}

externC void cyg_thread_resume(cyg_handle_t thread) __THROW
{
    Cyg_Thread *th = (Cyg_Thread *)thread;

    // If we are resuming an exited thread then
    // reinitialize it.
    
    if( th->get_state() == Cyg_Thread::EXITED )
        th->reinitialize();

    th->resume();
}

externC void cyg_thread_kill( cyg_handle_t thread) __THROW
{
    ((Cyg_Thread *)thread)->kill();
}

externC void cyg_thread_release( cyg_handle_t thread) __THROW
{
    ((Cyg_Thread *)thread)->release();    
}

externC void cyg_thread_yield() __THROW
{
    Cyg_Thread::yield();
}

externC cyg_handle_t cyg_thread_self() __THROW
{
    return (cyg_handle_t)Cyg_Thread::self();
}

externC cyg_uint16 cyg_thread_get_id( cyg_handle_t thread) __THROW
{
    return ((Cyg_Thread *)thread)->get_unique_id();
}

// idle thread is not really a plain CygThread; danger.
externC cyg_handle_t cyg_thread_idle_thread() __THROW
{
    extern Cyg_Thread idle_thread;
    return (cyg_handle_t)&idle_thread;
}

/* Priority manipulation */
externC void cyg_thread_set_priority(
    cyg_handle_t thread, cyg_priority_t priority ) __THROW
{
#ifdef CYGIMP_THREAD_PRIORITY
    ((Cyg_Thread *)thread)->set_priority(priority);
#endif
}


/* Get the normal priority, ie without any applied mutex inheritance or
 * ceiling protocol. */
externC cyg_priority_t cyg_thread_get_priority(cyg_handle_t thread) __THROW
{
#ifdef CYGIMP_THREAD_PRIORITY
    return ((Cyg_Thread *)thread)->get_priority();
#else
    return 0;
#endif
}


/* Get the current priority, ie any applied mutex inheritance or
 * ceiling protocol. */
externC cyg_priority_t cyg_thread_get_current_priority(cyg_handle_t thread) __THROW
{
#ifdef CYGIMP_THREAD_PRIORITY
    return ((Cyg_Thread *)thread)->get_current_priority();
#else
    return 0;
#endif
}

/* Deadline scheduling control (optional) */

externC void cyg_thread_deadline_wait( 
    cyg_tick_count_t    start_time,             /* abs earliest start time   */
    cyg_tick_count_t    run_time,               /* worst case execution time */
    cyg_tick_count_t    deadline                /* absolute deadline         */
) __THROW
{
    CYG_ASSERT(0,"Not implemented");
} 

externC void cyg_thread_delay(cyg_tick_count_t delay) __THROW
{
    Cyg_Thread::self()->delay(delay);
}

/* Stack information */
externC cyg_addrword_t cyg_thread_get_stack_base(cyg_handle_t thread) __THROW
{
    return ((Cyg_Thread *)thread)->get_stack_base();
}

externC cyg_uint32 cyg_thread_get_stack_size(cyg_handle_t thread) __THROW
{
    return ((Cyg_Thread *)thread)->get_stack_size();
}

#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
externC cyg_uint32 cyg_thread_measure_stack_usage(cyg_handle_t thread) __THROW
{
    return ((Cyg_Thread *)thread)->measure_stack_usage();
}
#endif

/*---------------------------------------------------------------------------*/
/* Thread enumeration and information                                        */

#ifdef CYGVAR_KERNEL_THREADS_LIST

cyg_bool_t cyg_thread_get_next( cyg_handle_t *current, cyg_uint16 *id ) __THROW
{
    cyg_bool_t result = true;

    // There is a minute but finite chance that the thread could have
    // exitted since the previous cyg_thread_get_next() call, and we can't
    // detect the ID mismatch further down. So be quite zealous with checking.

    CYG_CHECK_DATA_PTRC( current );
    CYG_CHECK_DATA_PTRC( id );
    if ( *current != 0 )
        CYG_CHECK_DATA_PTRC( *current );

    Cyg_Scheduler::lock();

    Cyg_Thread *thread = (Cyg_Thread *)*current;
    CYG_ASSERT_ZERO_OR_CLASSC( thread );
    if( *current == 0 )
    {
        thread = Cyg_Thread::get_list_head();
        *current = (cyg_handle_t)thread;
        *id = thread->get_unique_id();
    }
    else if( (thread->get_unique_id() == *id) &&
             (thread = thread->get_list_next()) != NULL )
    {
        CYG_CHECK_DATA_PTRC( thread );
        CYG_ASSERT_CLASSC( thread );
        *current = (cyg_handle_t)thread;
        *id = thread->get_unique_id();
    }
    else
    {
        *current = 0;
        *id = 0;
        result = false;
    }
    
    Cyg_Scheduler::unlock();

    return result;
}

cyg_handle_t cyg_thread_find( cyg_uint16 id ) __THROW
{
    Cyg_Scheduler::lock();

    Cyg_Thread *thread = Cyg_Thread::get_list_head();

    while( thread != NULL )
    {
        if( thread->get_unique_id() == id )
            break;
        
        thread = thread->get_list_next();
    }

    Cyg_Scheduler::unlock();
    
    return (cyg_handle_t)thread;
}

#endif

cyg_bool_t cyg_thread_get_info( cyg_handle_t threadh,
                                cyg_uint16 id,
                                cyg_thread_info *info ) __THROW
{
    cyg_bool_t result = true;
    Cyg_Thread *thread = (Cyg_Thread *)threadh;
    CYG_CHECK_DATA_PTRC( thread );
    if ( NULL != info )
        CYG_CHECK_DATA_PTRC( info );
    
    Cyg_Scheduler::lock();
    
    if( thread->get_unique_id() == id && info != NULL )
    {
        CYG_ASSERT_CLASSC( thread );
        info->handle = threadh;
        info->id = id;
        info->state = thread->get_state();
#ifdef CYGVAR_KERNEL_THREADS_NAME
        info->name = thread->get_name();
#else
        info->name = NULL;
#endif
        info->set_pri = thread->get_priority();
        info->cur_pri = thread->get_current_priority();
        info->stack_base = thread->get_stack_base();
        info->stack_size = thread->get_stack_size();
        
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
        info->stack_used = thread->measure_stack_usage();
#else
        info->stack_used = 0;
#endif
    }
    else result = false;
    

⌨️ 快捷键说明

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