diff packages/kernel/current/src/common/kapi.cxx @ 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/src/common/kapi.cxx
@@ -0,0 +1,1070 @@
+//==========================================================================
+//
+//	common/kapi.cxx
+//
+//	C API Implementation
+//
+//==========================================================================
+//####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, 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/memfixed.hxx>
+#include <cyg/kernel/memvar.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)
+{
+    Cyg_Scheduler::start();
+}
+
+/* Lock the scheduler. We only allow this to take the lock from */
+/* zero to 1. Any other transition implies that this function   */
+/* is being called from an ISR/DSR or some other illegal place. */
+externC void cyg_scheduler_lock(void)
+{
+    Cyg_Scheduler::lock();
+    
+    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
+                "Cannot nest calls to cyg_scheduler_lock");
+
+    if( Cyg_Scheduler::get_sched_lock() != 1 )
+        Cyg_Scheduler::unlock();        
+}
+
+/* Unlock the scheduler. Like lock, we only allow a 1->0        */
+/* transition.                                                  */
+externC void cyg_scheduler_unlock(void)
+{
+    CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
+                "Bad call to cyg_scheduler_unlock");
+
+    if( Cyg_Scheduler::get_sched_lock() == 1 )
+        Cyg_Scheduler::unlock();
+    
+}
+
+/*---------------------------------------------------------------------------*/
+/* 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           */
+)
+{
+    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()
+{
+    Cyg_Thread::exit();
+}
+
+externC void cyg_thread_suspend(cyg_handle_t thread)
+{
+    ((Cyg_Thread *)thread)->suspend();
+}
+
+externC void cyg_thread_resume(cyg_handle_t thread)
+{
+    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)
+{
+    ((Cyg_Thread *)thread)->kill();    
+}
+
+externC void cyg_thread_yield()
+{
+    Cyg_Thread::yield();
+}
+
+externC cyg_handle_t cyg_thread_self()
+{
+    return (cyg_handle_t)Cyg_Thread::self();
+}
+
+/* Priority manipulation */
+externC void cyg_thread_set_priority(
+    cyg_handle_t thread, cyg_priority_t priority )
+{
+    ((Cyg_Thread *)thread)->set_priority(priority);
+}
+
+externC cyg_priority_t cyg_thread_get_priority(cyg_handle_t thread)
+{
+    return ((Cyg_Thread *)thread)->get_priority();
+}
+
+/* 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         */
+)
+{
+    CYG_ASSERT(0,"Not implemented");
+} 
+
+externC void cyg_thread_delay(cyg_tick_count_t delay)
+{
+    Cyg_Thread::self()->delay(delay);
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Exception handling.                                                       */
+
+#ifdef CYGPKG_KERNEL_EXCEPTIONS    
+externC void cyg_exception_set_handler(
+    cyg_code_t                  exception_number,
+    cyg_exception_handler_t     *new_handler,
+    cyg_addrword_t                new_data,
+    cyg_exception_handler_t     **old_handler,
+    cyg_addrword_t                *old_data
+)
+{
+    Cyg_Thread::register_exception(
+        exception_number,
+        (cyg_exception_handler *)new_handler,
+        (CYG_ADDRWORD)new_data,
+        (cyg_exception_handler **)old_handler,
+        (CYG_ADDRWORD *)old_data
+        );
+}
+
+/* Clear exception handler to default                                        */
+externC void cyg_exception_clear_handler(
+    cyg_code_t                  exception_number
+)
+{
+    Cyg_Thread::deregister_exception( exception_number );
+}
+
+/* Invoke exception handler                                                  */
+externC void cyg_exception_call_handler(
+    cyg_handle_t                thread,
+    cyg_code_t                  exception_number,
+    cyg_code_t                  error_code
+)
+{
+    Cyg_Thread *t = (Cyg_Thread *)thread;
+
+    t->deliver_exception( exception_number, error_code );
+}
+#endif    
+
+/*---------------------------------------------------------------------------*/
+/* Interrupt handling                                                        */
+
+externC void cyg_interrupt_create(
+    cyg_vector_t        vector,         /* Vector to attach to               */
+    cyg_priority_t      priority,       /* Queue priority                    */
+    cyg_addrword_t        data,           /* Data pointer                      */
+    cyg_ISR_t           *isr,           /* Interrupt Service Routine         */
+    cyg_DSR_t           *dsr,           /* Deferred Service Routine          */
+    cyg_handle_t        *handle,        /* returned handle                   */
+    cyg_interrupt       *intr           /* put interrupt here                */
+)
+{
+    CYG_ASSERT_SIZES( cyg_interrupt, Cyg_Interrupt );
+
+    Cyg_Interrupt *t = new((void *)intr) Cyg_Interrupt (
+        (cyg_vector)vector,
+        (cyg_priority)priority,
+        (CYG_ADDRWORD)data,
+        (cyg_ISR *)isr,
+        (cyg_DSR *)dsr );
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)intr;
+}
+
+externC void cyg_interrupt_delete( cyg_handle_t interrupt)
+{
+    ((Cyg_Interrupt *)interrupt)->~Cyg_Interrupt();
+}
+
+void cyg_interrupt_attach( cyg_handle_t interrupt )
+{
+    ((Cyg_Interrupt *)interrupt)->attach();
+}
+
+void cyg_interrupt_detach( cyg_handle_t interrupt )
+{
+    ((Cyg_Interrupt *)interrupt)->detach();
+}
+
+/* VSR manipulation */
+
+externC void cyg_interrupt_get_vsr(
+    cyg_vector_t        vector,         /* vector to get                     */
+    cyg_VSR_t           **vsr           /* vsr got                           */
+)
+{
+    Cyg_Interrupt::get_vsr( (cyg_vector)vector, (cyg_VSR **)vsr);
+}
+
+externC void cyg_interrupt_set_vsr(
+    cyg_vector_t        vector,         /* vector to set                     */
+    cyg_VSR_t           *vsr            /* vsr to set                        */
+)
+{
+    Cyg_Interrupt::set_vsr( (cyg_vector)vector, (cyg_VSR *)vsr);
+}
+
+/* CPU level interrupt mask                                                  */
+externC void cyg_interrupt_disable()
+{
+    Cyg_Interrupt::disable_interrupts();
+}
+
+externC void cyg_interrupt_enable()
+{
+    Cyg_Interrupt::enable_interrupts();
+}
+
+/* Interrupt controller access                                               */
+externC void cyg_interrupt_mask(cyg_vector_t vector)
+{
+    Cyg_Interrupt::mask_interrupt( (cyg_vector)vector);
+}
+
+externC void cyg_interrupt_unmask(cyg_vector_t vector)
+{
+    Cyg_Interrupt::unmask_interrupt( (cyg_vector)vector);
+}
+
+
+externC void cyg_interrupt_acknowledge(cyg_vector_t vector)
+{
+    Cyg_Interrupt::acknowledge_interrupt( (cyg_vector)vector);
+}
+
+
+externC void cyg_interrupt_configure(
+    cyg_vector_t        vector,         /* vector to configure               */
+    cyg_bool_t          level,          /* level or edge triggered           */
+    cyg_bool_t          up              /* rising/faling edge, high/low level*/
+)
+{
+    Cyg_Interrupt::configure_interrupt( (cyg_vector)vector, level, up );
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Counters, Clocks and Alarms                                               */
+
+externC void cyg_counter_create(
+    cyg_handle_t        *handle,        /* returned counter handle           */
+    cyg_counter         *counter        /* put counter here                  */
+)
+{
+    CYG_ASSERT_SIZES( cyg_counter, Cyg_Counter );
+
+    Cyg_Counter *t = new((void *)counter) Cyg_Counter ();
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)counter;
+}
+
+externC void cyg_counter_delete(cyg_handle_t counter)
+{
+    ((Cyg_Counter *)counter)->~Cyg_Counter();
+}
+
+/* Return current value of counter                                           */
+externC cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter)
+{
+    return ((Cyg_Counter *)counter)->current_value();
+}
+
+/* Set new current value                                                     */
+externC void cyg_counter_set_value(
+    cyg_handle_t        counter,
+    cyg_tick_count_t new_value
+)
+{
+    ((Cyg_Counter *)counter)->set_value( new_value );
+}
+
+/* Advance counter by one tick                                               */
+externC void cyg_counter_tick(cyg_handle_t counter)
+{
+    ((Cyg_Counter *)counter)->tick(); 
+}
+
+/* Create a clock object                */
+externC void cyg_clock_create(
+    cyg_resolution_t    resolution,     /* Initial resolution                */
+    cyg_handle_t        *handle,        /* Returned clock handle             */
+    cyg_clock           *clock          /* put clock here                    */
+)
+{
+    CYG_ASSERT_SIZES( cyg_clock, Cyg_Clock );
+
+    Cyg_Clock::cyg_resolution res;
+
+    res.dividend = resolution.dividend;
+    res.divisor  = resolution.divisor;
+
+    Cyg_Clock *t = new((void *)clock) Cyg_Clock ( res );
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)clock;
+}
+
+externC void cyg_clock_delete(cyg_handle_t clock)
+{
+    ((Cyg_Clock *)clock)->~Cyg_Clock();
+}
+
+/* convert a clock handle to a counter handle so we can use the              */
+/* counter API on it.                                                        */
+externC void cyg_clock_to_counter(
+    cyg_handle_t        clock,
+    cyg_handle_t        *counter
+)
+{
+    CYG_CHECK_DATA_PTR( counter, "Bad counter handle pointer" );
+    *counter = (cyg_handle_t)(Cyg_Counter *)clock;
+}
+
+externC void cyg_clock_set_resolution(
+    cyg_handle_t        clock,
+    cyg_resolution_t    resolution      /* New resolution                    */
+)
+{
+    Cyg_Clock::cyg_resolution res;
+
+    res.dividend = resolution.dividend;
+    res.divisor  = resolution.divisor;
+
+    ((Cyg_Clock *)clock)->set_resolution( res );
+}
+
+externC cyg_resolution_t cyg_clock_get_resolution(cyg_handle_t clock)
+{
+    Cyg_Clock::cyg_resolution res =
+        ((Cyg_Clock *)clock)->get_resolution();    
+
+    cyg_resolution_t resolution;
+
+    resolution.dividend = res.dividend;
+    resolution.divisor  = res.divisor;
+
+    return resolution;
+}
+
+#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
+externC cyg_handle_t cyg_real_time_clock(void)
+{
+    return (cyg_handle_t)Cyg_Clock::real_time_clock;
+}
+
+externC cyg_tick_count_t cyg_current_time(void)
+{
+    return Cyg_Clock::real_time_clock->current_value();
+}
+#endif
+
+externC void cyg_alarm_create(
+    cyg_handle_t        counter,        /* Attached to this counter          */
+    cyg_alarm_t         *alarmfn,       /* Call-back function                */
+    cyg_addrword_t        data,           /* Call-back data                    */
+    cyg_handle_t        *handle,        /* Returned alarm object             */
+    cyg_alarm           *alarm          /* put alarm here                    */
+)
+{
+    CYG_ASSERT_SIZES( cyg_alarm, Cyg_Alarm );
+
+    Cyg_Alarm *t = new((void *)alarm) Cyg_Alarm (
+        (Cyg_Counter *)counter,
+	(cyg_alarm_fn *)alarmfn,
+	(CYG_ADDRWORD)data
+    );
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)alarm;
+}
+
+/* Disable alarm, detach from counter and invalidate handles                 */
+externC void cyg_alarm_delete( cyg_handle_t alarm)
+{
+    ((Cyg_Alarm *)alarm)->~Cyg_Alarm();
+}
+
+externC void cyg_alarm_initialize(
+    cyg_handle_t        alarm,
+    cyg_tick_count_t    trigger,        /* Absolute trigger time             */
+    cyg_tick_count_t    interval        /* Relative retrigger interval       */
+)
+{
+    ((Cyg_Alarm *)alarm)->initialize(
+	(cyg_tick_count)trigger,
+	(cyg_tick_count)interval);
+}
+
+externC void cyg_alarm_enable( cyg_handle_t alarm )
+{
+    ((Cyg_Alarm *)alarm)->enable();
+}
+
+externC void cyg_alarm_disable( cyg_handle_t alarm )
+{
+    ((Cyg_Alarm *)alarm)->disable();
+}
+
+/*---------------------------------------------------------------------------*/
+/* Mail boxes                                                                */
+
+externC void cyg_mbox_create(
+    cyg_handle_t        *handle,
+    cyg_mbox            *mbox
+)
+{
+    CYG_ASSERT_SIZES( cyg_mbox, Cyg_Mbox );
+    
+    Cyg_Mbox *t = new((void *)mbox) Cyg_Mbox();
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)mbox;
+}
+
+externC void cyg_mbox_delete(cyg_handle_t mbox)
+{
+    ((Cyg_Mbox *)mbox)->~Cyg_Mbox();
+}
+
+externC void *cyg_mbox_get(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->get();
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+void *cyg_mbox_timed_get(
+    cyg_handle_t mbox,
+    cyg_tick_count_t abstime
+    )
+{
+    return ((Cyg_Mbox *)mbox)->get(abstime);
+}
+#endif
+
+externC void *cyg_mbox_tryget(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->tryget();
+}
+
+externC void *cyg_mbox_peek_item(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->peek_item();
+}
+
+#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
+externC cyg_bool_t cyg_mbox_put(cyg_handle_t mbox, void *item)
+{
+    return ((Cyg_Mbox *)mbox)->put(item);
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+externC cyg_bool_t cyg_mbox_timed_put(
+    cyg_handle_t mbox,
+    void *item,
+    cyg_tick_count_t abstime
+    )
+{
+    return ((Cyg_Mbox *)mbox)->put(item, abstime);
+}
+#endif
+#endif
+
+externC cyg_bool_t cyg_mbox_tryput(cyg_handle_t mbox, void *item)
+{
+    return ((Cyg_Mbox *)mbox)->tryput(item);
+}
+
+externC cyg_count32 cyg_mbox_peek(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->peek();
+}
+
+externC cyg_bool_t cyg_mbox_waiting_to_get(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->waiting_to_get();
+}
+
+externC cyg_bool_t cyg_mbox_waiting_to_put(cyg_handle_t mbox)
+{
+    return ((Cyg_Mbox *)mbox)->waiting_to_put();
+}
+
+
+/*-----------------------------------------------------------------------*/
+/* Memory pools                                                          */
+
+/* Create a variable size memory pool */
+externC void cyg_mempool_var_create(
+    void            *base,              /* base of memory to use for pool */
+    cyg_int32       size,               /* size of memory in bytes        */
+    cyg_handle_t    *handle,            /* returned handle of memory pool */
+    cyg_mempool_var *var                /* space to put pool structure in */
+    )
+{
+    CYG_ASSERT_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
+
+    Cyg_Mempool_Variable *t = new((void *)var) Cyg_Mempool_Variable (
+        (cyg_uint8 *)base,
+	size
+    );
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)var;
+}
+
+/* Delete variable size memory pool */
+externC void cyg_mempool_var_delete(cyg_handle_t varpool)
+{
+    ((Cyg_Mempool_Variable *)varpool)->~Cyg_Mempool_Variable();
+}
+
+/* Allocates a block of length size.  This waits if the memory is not
+   currently available.  */
+externC void *cyg_mempool_var_alloc(cyg_handle_t varpool, cyg_int32 size)
+{
+    return ((Cyg_Mempool_Variable *)varpool)->alloc(size);
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+/* Allocates a block of length size.  This waits for up to delay
+   ticks, if the memory is not already available.  NULL is returned if
+   no memory is available. */
+externC void *cyg_mempool_var_timed_alloc(
+    cyg_handle_t     varpool,
+    cyg_int32        size,
+    cyg_tick_count_t abstime)
+{
+    return ((Cyg_Mempool_Variable *)varpool)->alloc(size, abstime);
+}
+
+#endif
+
+/* Allocates a block of length size.  NULL is returned if no memory is
+   available. */
+externC void *cyg_mempool_var_try_alloc(
+    cyg_handle_t varpool,
+    cyg_int32    size)
+{
+    return ((Cyg_Mempool_Variable *)varpool)->try_alloc(size);
+}
+
+/* Frees memory back into variable size pool. */
+externC void cyg_mempool_var_free(cyg_handle_t varpool, void *p)
+{
+    cyg_bool b;
+    b = ((Cyg_Mempool_Variable *)varpool)->free((cyg_uint8 *)p, 0);
+    CYG_ASSERT( b, "Bad free");
+}
+
+
+/* Returns true if there are any threads waiting for memory in the
+   given memory pool. */
+externC cyg_bool_t cyg_mempool_var_waiting(cyg_handle_t varpool)
+{
+    return ((Cyg_Mempool_Variable *)varpool)->waiting();
+}
+
+/* Puts information about a variable memory pool into the structure
+   provided. */
+externC void cyg_mempool_var_get_info(
+    cyg_handle_t varpool,
+    cyg_mempool_info *info)
+{
+    Cyg_Mempool_Variable *v = (Cyg_Mempool_Variable *)varpool;
+    cyg_uint8 *base;
+    CYG_ADDRWORD maxfree;
+    
+    info->totalmem = v->get_totalmem();
+    info->freemem  = v->get_freemem();
+    v->get_arena(base, info->size, maxfree);
+    info->base = (void *)base;
+    info->blocksize  = -1;
+    info->maxfree = maxfree;
+}
+
+
+/* Create a fixed size memory pool */
+externC void cyg_mempool_fix_create(
+    void            *base,              // base of memory to use for pool
+    cyg_int32       size,               // size of memory in byte
+    cyg_int32       blocksize,          // size of allocation in bytes
+    cyg_handle_t    *handle,            // handle of memory pool
+    cyg_mempool_fix *fix                // space to put pool structure in
+    )
+{
+    CYG_ASSERT_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
+
+    Cyg_Mempool_Fixed *t = new((void *)fix) Cyg_Mempool_Fixed (
+        (cyg_uint8 *)base,
+	size,
+        blocksize
+    );
+    t=t;
+
+    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
+    *handle = (cyg_handle_t)fix;
+}
+
+/* Delete fixed size memory pool */
+externC void cyg_mempool_fix_delete(cyg_handle_t fixpool)
+{
+    ((Cyg_Mempool_Fixed *)fixpool)->~Cyg_Mempool_Fixed();
+}
+
+/* Allocates a block.  This waits if the memory is not
+   currently available.  */
+externC void *cyg_mempool_fix_alloc(cyg_handle_t fixpool)
+{
+    return ((Cyg_Mempool_Fixed *)fixpool)->alloc();
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+
+/* Allocates a block.  This waits for up to delay ticks, if the memory
+   is not already available.  NULL is returned if no memory is
+   available. */
+externC void *cyg_mempool_fix_timed_alloc(
+    cyg_handle_t     fixpool,
+    cyg_tick_count_t abstime)
+{
+    return ((Cyg_Mempool_Fixed *)fixpool)->alloc(abstime);
+}
+
+#endif
+
+/* Allocates a block.  NULL is returned if no memory is available. */
+externC void *cyg_mempool_fix_try_alloc(cyg_handle_t fixpool)
+{
+    return ((Cyg_Mempool_Fixed *)fixpool)->try_alloc();
+}
+
+/* Frees memory back into fixed size pool. */
+externC void cyg_mempool_fix_free(cyg_handle_t fixpool, void *p)
+{
+    cyg_bool b;
+    b = ((Cyg_Mempool_Fixed *)fixpool)->free((cyg_uint8 *)p);
+    CYG_ASSERT( b, "Bad free");
+}
+
+/* Returns true if there are any threads waiting for memory in the
+   given memory pool. */
+externC cyg_bool_t cyg_mempool_fix_waiting(cyg_handle_t fixpool)
+{
+    return ((Cyg_Mempool_Fixed *)fixpool)->waiting();
+}
+
+/* Puts information about a variable memory pool into the structure
+   provided. */
+externC void cyg_mempool_fix_get_info(
+    cyg_handle_t fixpool,
+    cyg_mempool_info *info)
+{
+    Cyg_Mempool_Fixed *f = (Cyg_Mempool_Fixed *)fixpool;
+    cyg_uint8 *base;
+    cyg_addrword_t blocksize;
+    
+    info->totalmem = f->get_totalmem();
+    info->freemem  = f->get_freemem();
+    f->get_arena(base, info->size, blocksize);
+    info->base = (void *)base;
+    info->maxfree = info->blocksize = (cyg_int32)blocksize;
+}
+
+/*---------------------------------------------------------------------------*/
+/* Semaphores                                                                */
+
+externC void      cyg_semaphore_init(
+    cyg_sem_t           *sem,            /* Semaphore to init                */
+    cyg_ucount32        val              /* Initial semaphore value          */
+)
+{
+    CYG_ASSERT_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
+    
+    Cyg_Counting_Semaphore *t = new((void *)sem) Cyg_Counting_Semaphore(val);
+    t=t;
+}
+
+externC void cyg_semaphore_destroy( cyg_sem_t *sem )
+{
+    ((Cyg_Counting_Semaphore *)sem)->~Cyg_Counting_Semaphore();
+}
+
+externC void cyg_semaphore_wait( cyg_sem_t *sem )
+{
+    ((Cyg_Counting_Semaphore *)sem)->wait();
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+externC cyg_bool_t cyg_semaphore_timed_wait(
+    cyg_sem_t          *sem,
+    cyg_tick_count_t   abstime
+    )
+{
+    return ((Cyg_Counting_Semaphore *)sem)->wait(abstime);
+}
+#endif
+
+
+externC int cyg_semaphore_trywait( cyg_sem_t *sem )
+{
+    return ((Cyg_Counting_Semaphore *)sem)->trywait();
+}
+
+externC void cyg_semaphore_post( cyg_sem_t *sem )
+{
+    ((Cyg_Counting_Semaphore *)sem)->post();
+}
+
+externC void cyg_semaphore_peek( cyg_sem_t *sem, cyg_ucount32 *val )
+{
+    CYG_CHECK_DATA_PTR( val, "Bad val parameter" );
+
+    *val = ((Cyg_Counting_Semaphore *)sem)->peek();
+}
+
+
+/*---------------------------------------------------------------------------*/
+/* Flags                                                                     */
+
+void cyg_flag_init(
+    cyg_flag_t        *flag             /* Flag to init                      */
+)
+{
+    CYG_ASSERT_SIZES( cyg_flag_t, Cyg_Flag );
+    CYG_ASSERT(
+        ( Cyg_Flag::AND == CYG_FLAG_WAITMODE_AND ) &&
+        ( Cyg_Flag::OR  == CYG_FLAG_WAITMODE_OR  ) &&
+        ( Cyg_Flag::CLR == CYG_FLAG_WAITMODE_CLR ),
+        "CYG_FLAG_WAITMODE_xxx definition != C++ Cyg_Flag::xxx" );
+    
+    Cyg_Flag *t = new((void *)flag) Cyg_Flag();
+    t=t;
+}
+
+void cyg_flag_destroy( cyg_flag_t *flag )
+{
+    ((Cyg_Flag *)flag)->~Cyg_Flag();
+}
+
+void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value)
+{
+    ((Cyg_Flag *)flag)->setbits( value ); 
+}
+
+void cyg_flag_maskbits( cyg_flag_t *flag, cyg_flag_value_t value)
+{
+    ((Cyg_Flag *)flag)->maskbits( value ); 
+}
+
+cyg_flag_value_t cyg_flag_wait( cyg_flag_t        *flag,
+                                cyg_flag_value_t   pattern, 
+                                cyg_flag_mode_t    mode )
+{
+    if ( 0 == pattern || 0 != (mode & ~3) )
+        return 0;
+    return ((Cyg_Flag *)flag)->wait( pattern, mode );
+
+}
+
+#ifdef CYGFUN_KERNEL_THREADS_TIMER
+cyg_flag_value_t cyg_flag_timed_wait( cyg_flag_t        *flag,
+                                      cyg_flag_value_t   pattern, 
+                                      cyg_flag_mode_t    mode,
+                                      cyg_tick_count_t   abstime )
+{
+    if ( 0 == pattern || 0 != (mode & ~3) )
+        return 0;
+    return ((Cyg_Flag *)flag)->wait( pattern, mode, abstime );
+
+}
+#endif
+
+cyg_flag_value_t cyg_flag_poll( cyg_flag_t         *flag,
+                                cyg_flag_value_t    pattern, 
+                                cyg_flag_mode_t     mode )
+{
+    if ( 0 == pattern || 0 != (mode & ~3) )
+        return 0;
+    return ((Cyg_Flag *)flag)->poll( pattern, mode );
+
+}
+
+cyg_flag_value_t cyg_flag_peek( cyg_flag_t *flag )
+{
+    return ((Cyg_Flag *)flag)->peek();
+}
+
+cyg_bool_t cyg_flag_waiting( cyg_flag_t *flag )
+{
+    return ((Cyg_Flag *)flag)->waiting();
+}
+
+/*---------------------------------------------------------------------------*/
+/* Mutex                                                                     */
+
+externC void cyg_mutex_init(
+    cyg_mutex_t        *mutex          /* Mutex to init                      */
+)
+{
+    CYG_ASSERT_SIZES( cyg_mutex_t, Cyg_Mutex );
+    
+    Cyg_Mutex *m = new((void *)mutex) Cyg_Mutex;
+
+    m=m;
+}
+
+externC void cyg_mutex_destroy( cyg_mutex_t *mutex )
+{
+    // no need to do anything here
+}
+
+externC void cyg_mutex_lock( cyg_mutex_t *mutex )
+{
+    ((Cyg_Mutex *)mutex)->lock();
+}
+
+externC cyg_bool_t cyg_mutex_trylock( cyg_mutex_t *mutex )
+{
+    return ((Cyg_Mutex *)mutex)->trylock();
+}
+
+externC void cyg_mutex_unlock( cyg_mutex_t *mutex )
+{
+    ((Cyg_Mutex *)mutex)->unlock();
+}
+
+/*---------------------------------------------------------------------------*/
+/* Condition Variables                                                       */
+
+externC void cyg_cond_init(
+    cyg_cond_t          *cond,          /* condition variable to init        */
+    cyg_mutex_t         *mutex          /* associated mutex                  */
+)
+{
+    CYG_ASSERT_SIZES( cyg_cond_t, Cyg_Condition_Variable );
+    
+    Cyg_Condition_Variable *t = new((void *)cond) Cyg_Condition_Variable(
+        *(Cyg_Mutex *)mutex);
+    t=t;
+}
+
+externC void cyg_cond_destroy( cyg_cond_t *cond )
+{
+    ((Cyg_Counting_Semaphore *)cond)->~Cyg_Counting_Semaphore();
+}
+
+externC void cyg_cond_wait( cyg_cond_t *cond )
+{
+    ((Cyg_Condition_Variable *)cond)->wait();
+}
+
+externC void cyg_cond_signal( cyg_cond_t *cond )
+{
+    ((Cyg_Condition_Variable *)cond)->signal();
+}
+
+externC void cyg_cond_broadcast( cyg_cond_t *cond )
+{
+    ((Cyg_Condition_Variable *)cond)->broadcast();
+}
+
+#ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
+externC cyg_bool_t cyg_cond_timed_wait(
+    cyg_cond_t        *cond,
+    cyg_tick_count_t  abstime
+    )
+{
+    return ((Cyg_Condition_Variable *)cond)->wait(abstime);
+}
+
+#endif
+
+// -------------------------------------------------------------------------
+// Check structure sizes.
+// This class and constructor get run automatically in debug versions
+// of the kernel and check that the structures configured in the C
+// code are the same size as the C++ classes they should match.
+
+#ifdef CYGPKG_INFRA_DEBUG
+
+class Cyg_Check_Structure_Sizes
+{
+    int dummy;
+public:    
+    Cyg_Check_Structure_Sizes( int x );
+
+};
+
+#define CYG_CHECK_SIZES(cstruct, cxxstruct)                               \
+if( sizeof(cstruct) != sizeof(cxxstruct) )                                \
+{                                                                         \
+    char *fmt = "Size of C struct " #cstruct                              \
+                " != size of C++ struct " #cxxstruct ;                    \
+    CYG_TRACE2(1, fmt, sizeof(cstruct) , sizeof(cxxstruct) );             \
+    fail = true;                                                          \
+    fmt = fmt;                                                            \
+}
+
+Cyg_Check_Structure_Sizes::Cyg_Check_Structure_Sizes(int x)
+{
+    cyg_bool fail = false;
+
+    dummy = x+1;
+    
+    CYG_CHECK_SIZES( cyg_thread, Cyg_Thread );
+    CYG_CHECK_SIZES( cyg_interrupt, Cyg_Interrupt );
+    CYG_CHECK_SIZES( cyg_counter, Cyg_Counter );
+    CYG_CHECK_SIZES( cyg_clock, Cyg_Clock );
+    CYG_CHECK_SIZES( cyg_alarm, Cyg_Alarm );
+    CYG_CHECK_SIZES( cyg_mbox, Cyg_Mbox );
+    CYG_CHECK_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
+    CYG_CHECK_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
+    CYG_CHECK_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
+    CYG_CHECK_SIZES( cyg_flag_t, Cyg_Flag );
+    CYG_CHECK_SIZES( cyg_mutex_t, Cyg_Mutex );
+    CYG_CHECK_SIZES( cyg_cond_t, Cyg_Condition_Variable );
+    
+    CYG_ASSERT( !fail, "Size checks failed");
+}
+
+Cyg_Check_Structure_Sizes check_structure_sizes(1);
+
+#endif
+
+
+// -------------------------------------------------------------------------
+
+#endif
+// EOF common/kapi.cxx