OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [kernel/] [v2_0/] [src/] [common/] [kapi.cxx] - Blame information for rev 174

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//      common/kapi.cxx
4
//
5
//      C API Implementation
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
// Copyright (C) 2002 Nick Garnett
13
// Copyright (C) 2003 Jonathan Larmour
14
//
15
// eCos is free software; you can redistribute it and/or modify it under
16
// the terms of the GNU General Public License as published by the Free
17
// Software Foundation; either version 2 or (at your option) any later version.
18
//
19
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
21
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22
// for more details.
23
//
24
// You should have received a copy of the GNU General Public License along
25
// with eCos; if not, write to the Free Software Foundation, Inc.,
26
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27
//
28
// As a special exception, if other files instantiate templates or use macros
29
// or inline functions from this file, or you compile this file and link it
30
// with other works to produce a work based on this file, this file does not
31
// by itself cause the resulting work to be covered by the GNU General Public
32
// License. However the source code for this file must still be made available
33
// in accordance with section (3) of the GNU General Public License.
34
//
35
// This exception does not invalidate any other reasons why a work based on
36
// this file might be covered by the GNU General Public License.
37
//
38
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39
// at http://sources.redhat.com/ecos/ecos-license/
40
// -------------------------------------------
41
//####ECOSGPLCOPYRIGHTEND####
42
//==========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):   nickg, dsm
46
// Contributors:        nickg
47
// Date:        1998-03-02
48
// Purpose:     C API Implementation
49
// Description: C++ implementation of the C API
50
//              
51
//
52
//####DESCRIPTIONEND####
53
//
54
//==========================================================================
55
 
56
#include <pkgconf/kernel.h>
57
 
58
#ifdef CYGFUN_KERNEL_API_C
59
 
60
#include <cyg/kernel/ktypes.h>         // base kernel types
61
#include <cyg/infra/cyg_trac.h>        // tracing macros
62
#include <cyg/infra/cyg_ass.h>         // assertion macros
63
#include <cyg/kernel/instrmnt.h>       // instrumentation
64
#include <cyg/kernel/diag.h>
65
 
66
#include <cyg/kernel/thread.hxx>
67
#include <cyg/kernel/thread.inl>       // thread inlines
68
#include <cyg/kernel/sched.hxx>
69
#include <cyg/kernel/intr.hxx>
70
#include <cyg/kernel/clock.hxx>
71
 
72
#include <cyg/kernel/sema.hxx>
73
#include <cyg/kernel/flag.hxx>
74
#include <cyg/kernel/mutex.hxx>
75
#include <cyg/kernel/mbox.hxx>
76
 
77
#include <cyg/kernel/sched.inl>        // scheduler inlines
78
#include <cyg/kernel/clock.inl>        // clock inlines
79
 
80
#include <cyg/kernel/kapi.h>           // C API
81
 
82
// -------------------------------------------------------------------------
83
// Magic new function
84
 
85
inline void *operator new(size_t size, void *ptr)
86
{
87
    CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
88
    return ptr;
89
}
90
 
91
// -------------------------------------------------------------------------
92
 
93
#ifdef CYGDBG_USE_ASSERTS
94
 
95
#define CYG_ASSERT_SIZES(cstruct, cxxstruct)                      \
96
CYG_MACRO_START                                                   \
97
    char *msg = "Size of C struct " #cstruct                      \
98
                       " != size of C++ struct " #cxxstruct ;     \
99
    CYG_ASSERT( sizeof(cstruct) == sizeof(cxxstruct) , msg );     \
100
CYG_MACRO_END
101
 
102
#else
103
 
104
#define CYG_ASSERT_SIZES(cstruct, cxxstruct)
105
 
106
#endif
107
 
108
/*---------------------------------------------------------------------------*/
109
/* Scheduler operations */
110
 
111
/* Starts scheduler with created threads.  Never returns. */
112
externC void cyg_scheduler_start(void)
113
{
114
    Cyg_Scheduler::start();
115
}
116
 
117
/* Lock the scheduler. */
118
externC void cyg_scheduler_lock(void)
119
{
120
    Cyg_Scheduler::lock();
121
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
122
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
123
                "Scheduler overlocked" );
124
}
125
 
126
/* Lock the scheduler, but never more than level=1. */
127
externC void cyg_scheduler_safe_lock(void)
128
{
129
    Cyg_Scheduler::lock();
130
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
131
    if (slock > 1)
132
        Cyg_Scheduler::unlock();
133
    // get_sched_lock() is unsigned, see below "cyg_ucount32 lock"
134
    CYG_ASSERT( (0xff000000 & (Cyg_Scheduler::get_sched_lock())) == 0,
135
                "Scheduler overlocked" );
136
}
137
 
138
/* Unlock the scheduler. */
139
externC void cyg_scheduler_unlock(void)
140
{
141
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
142
    CYG_ASSERT( 0 < slock, "Scheduler not locked" );
143
    // And program defensively too:
144
    if ( 0 < slock )
145
        Cyg_Scheduler::unlock();
146
}
147
 
148
/* Read the scheduler lock value. */
149
externC cyg_ucount32 cyg_scheduler_read_lock(void)
150
{
151
    cyg_ucount32 slock = Cyg_Scheduler::get_sched_lock();
152
    return slock;
153
}
154
 
155
/*---------------------------------------------------------------------------*/
156
/* Thread operations */
157
 
158
externC void cyg_thread_create(
159
    cyg_addrword_t      sched_info,             /* scheduling info (eg pri)  */
160
    cyg_thread_entry_t  *entry,                 /* entry point function      */
161
    cyg_addrword_t      entry_data,             /* entry data                */
162
    char                *name,                  /* optional thread name      */
163
    void                *stack_base,            /* stack base, NULL = alloc  */
164
    cyg_ucount32        stack_size,             /* stack size, 0 = default   */
165
    cyg_handle_t        *handle,                /* returned thread handle    */
166
    cyg_thread          *thread                 /* put thread here           */
167
)
168
{
169
    CYG_ASSERT_SIZES( cyg_thread, Cyg_Thread );
170
 
171
    Cyg_Thread *t = new((void *)thread) Cyg_Thread (
172
        (CYG_ADDRWORD) sched_info,
173
        (cyg_thread_entry *)entry,
174
        (CYG_ADDRWORD) entry_data,
175
        name,
176
        (CYG_ADDRWORD) stack_base,
177
        stack_size
178
        );
179
    t=t;
180
 
181
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
182
    *handle = (cyg_handle_t)thread;
183
}
184
 
185
externC void cyg_thread_exit()
186
{
187
    Cyg_Thread::exit();
188
}
189
 
190
externC cyg_bool_t cyg_thread_delete( cyg_handle_t thread )
191
{
192
    Cyg_Thread *th = (Cyg_Thread *)thread;
193
    if( th->get_state() != Cyg_Thread::EXITED )
194
        th->kill(); // encourage it to terminate
195
    if( th->get_state() != Cyg_Thread::EXITED )
196
        return false; // it didn't run yet, leave it up to the app to fix
197
    th->~Cyg_Thread();
198
    return true;
199
}
200
 
201
externC void cyg_thread_suspend(cyg_handle_t thread)
202
{
203
    ((Cyg_Thread *)thread)->suspend();
204
}
205
 
206
externC void cyg_thread_resume(cyg_handle_t thread)
207
{
208
    Cyg_Thread *th = (Cyg_Thread *)thread;
209
 
210
    // If we are resuming an exited thread then
211
    // reinitialize it.
212
 
213
    if( th->get_state() == Cyg_Thread::EXITED )
214
        th->reinitialize();
215
 
216
    th->resume();
217
}
218
 
219
externC void cyg_thread_kill( cyg_handle_t thread)
220
{
221
    ((Cyg_Thread *)thread)->kill();
222
}
223
 
224
externC void cyg_thread_release( cyg_handle_t thread)
225
{
226
    ((Cyg_Thread *)thread)->release();
227
}
228
 
229
externC void cyg_thread_yield()
230
{
231
    Cyg_Thread::yield();
232
}
233
 
234
externC cyg_handle_t cyg_thread_self()
235
{
236
    return (cyg_handle_t)Cyg_Thread::self();
237
}
238
 
239
// idle thread is not really a plain CygThread; danger.
240
externC cyg_handle_t cyg_thread_idle_thread()
241
{
242
    extern Cyg_Thread idle_thread;
243
    return (cyg_handle_t)&idle_thread;
244
}
245
 
246
/* Priority manipulation */
247
externC void cyg_thread_set_priority(
248
    cyg_handle_t thread, cyg_priority_t priority )
249
{
250
#ifdef CYGIMP_THREAD_PRIORITY
251
    ((Cyg_Thread *)thread)->set_priority(priority);
252
#endif
253
}
254
 
255
 
256
/* Get the normal priority, ie without any applied mutex inheritance or
257
 * ceiling protocol. */
258
externC cyg_priority_t cyg_thread_get_priority(cyg_handle_t thread)
259
{
260
#ifdef CYGIMP_THREAD_PRIORITY
261
    return ((Cyg_Thread *)thread)->get_priority();
262
#else
263
    return 0;
264
#endif
265
}
266
 
267
 
268
/* Get the current priority, ie any applied mutex inheritance or
269
 * ceiling protocol. */
270
externC cyg_priority_t cyg_thread_get_current_priority(cyg_handle_t thread)
271
{
272
#ifdef CYGIMP_THREAD_PRIORITY
273
    return ((Cyg_Thread *)thread)->get_current_priority();
274
#else
275
    return 0;
276
#endif
277
}
278
 
279
/* Deadline scheduling control (optional) */
280
 
281
externC void cyg_thread_deadline_wait(
282
    cyg_tick_count_t    start_time,             /* abs earliest start time   */
283
    cyg_tick_count_t    run_time,               /* worst case execution time */
284
    cyg_tick_count_t    deadline                /* absolute deadline         */
285
)
286
{
287
    CYG_ASSERT(0,"Not implemented");
288
}
289
 
290
externC void cyg_thread_delay(cyg_tick_count_t delay)
291
{
292
    Cyg_Thread::self()->delay(delay);
293
}
294
 
295
/* Stack information */
296
externC cyg_addrword_t cyg_thread_get_stack_base(cyg_handle_t thread)
297
{
298
    return ((Cyg_Thread *)thread)->get_stack_base();
299
}
300
 
301
externC cyg_uint32 cyg_thread_get_stack_size(cyg_handle_t thread)
302
{
303
    return ((Cyg_Thread *)thread)->get_stack_size();
304
}
305
 
306
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
307
externC cyg_uint32 cyg_thread_measure_stack_usage(cyg_handle_t thread)
308
{
309
    return ((Cyg_Thread *)thread)->measure_stack_usage();
310
}
311
#endif
312
 
313
/*---------------------------------------------------------------------------*/
314
/* Thread enumeration and information                                        */
315
 
316
#ifdef CYGVAR_KERNEL_THREADS_LIST
317
 
318
cyg_bool_t cyg_thread_get_next( cyg_handle_t *current, cyg_uint16 *id )
319
{
320
    cyg_bool_t result = true;
321
 
322
    // There is a minute but finite chance that the thread could have
323
    // exitted since the previous cyg_thread_get_next() call, and we can't
324
    // detect the ID mismatch further down. So be quite zealous with checking.
325
 
326
    CYG_CHECK_DATA_PTRC( current );
327
    CYG_CHECK_DATA_PTRC( id );
328
    if ( *current != 0 )
329
        CYG_CHECK_DATA_PTRC( *current );
330
 
331
    Cyg_Scheduler::lock();
332
 
333
    Cyg_Thread *thread = (Cyg_Thread *)*current;
334
    CYG_ASSERT_CLASSC( thread );
335
    if( *current == 0 )
336
    {
337
        thread = Cyg_Thread::get_list_head();
338
        *current = (cyg_handle_t)thread;
339
        *id = thread->get_unique_id();
340
    }
341
    else if( (thread->get_unique_id() == *id) &&
342
             (thread = thread->get_list_next()) != NULL )
343
    {
344
        CYG_CHECK_DATA_PTRC( thread );
345
        CYG_ASSERT_CLASSC( thread );
346
        *current = (cyg_handle_t)thread;
347
        *id = thread->get_unique_id();
348
    }
349
    else
350
    {
351
        *current = 0;
352
        *id = 0;
353
        result = false;
354
    }
355
 
356
    Cyg_Scheduler::unlock();
357
 
358
    return result;
359
}
360
 
361
cyg_handle_t cyg_thread_find( cyg_uint16 id )
362
{
363
    Cyg_Scheduler::lock();
364
 
365
    Cyg_Thread *thread = Cyg_Thread::get_list_head();
366
 
367
    while( thread != NULL )
368
    {
369
        if( thread->get_unique_id() == id )
370
            break;
371
 
372
        thread = thread->get_list_next();
373
    }
374
 
375
    Cyg_Scheduler::unlock();
376
 
377
    return (cyg_handle_t)thread;
378
}
379
 
380
#endif
381
 
382
cyg_bool_t cyg_thread_get_info( cyg_handle_t threadh,
383
                                cyg_uint16 id,
384
                                cyg_thread_info *info )
385
{
386
    cyg_bool_t result = true;
387
    Cyg_Thread *thread = (Cyg_Thread *)threadh;
388
    CYG_CHECK_DATA_PTRC( thread );
389
    if ( NULL != info )
390
        CYG_CHECK_DATA_PTRC( info );
391
 
392
    Cyg_Scheduler::lock();
393
 
394
    if( thread->get_unique_id() == id && info != NULL )
395
    {
396
        CYG_ASSERT_CLASSC( thread );
397
        info->handle = threadh;
398
        info->id = id;
399
        info->state = thread->get_state();
400
#ifdef CYGVAR_KERNEL_THREADS_NAME
401
        info->name = thread->get_name();
402
#else
403
        info->name = NULL;
404
#endif
405
        info->set_pri = thread->get_priority();
406
        info->cur_pri = thread->get_current_priority();
407
        info->stack_base = thread->get_stack_base();
408
        info->stack_size = thread->get_stack_size();
409
 
410
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
411
        info->stack_used = thread->measure_stack_usage();
412
#else
413
        info->stack_used = 0;
414
#endif
415
    }
416
    else result = false;
417
 
418
    Cyg_Scheduler::unlock();
419
 
420
    return result;
421
}
422
 
423
/*---------------------------------------------------------------------------*/
424
/* Per-thread data                                                           */
425
 
426
#ifdef CYGVAR_KERNEL_THREADS_DATA
427
 
428
externC cyg_ucount32 cyg_thread_new_data_index()
429
{
430
    Cyg_Thread::cyg_data_index index = Cyg_Thread::new_data_index();
431
    CYG_ASSERT(index >= 0, "failed to allocate data index" );
432
    return index;
433
}
434
 
435
externC void cyg_thread_free_data_index(cyg_ucount32 index)
436
{
437
    Cyg_Thread::free_data_index(index);
438
}
439
 
440
externC CYG_ADDRWORD cyg_thread_get_data(cyg_ucount32 index)
441
{
442
    return Cyg_Thread::get_data(index);
443
}
444
 
445
externC CYG_ADDRWORD *cyg_thread_get_data_ptr(cyg_ucount32 index)
446
{
447
    return Cyg_Thread::get_data_ptr(index);
448
}
449
 
450
externC void cyg_thread_set_data(cyg_ucount32 index, CYG_ADDRWORD
451
data)
452
{
453
    Cyg_Thread::self()->set_data(index, data);
454
}
455
#endif
456
 
457
/*---------------------------------------------------------------------------*/
458
/* Thread destructors                                                        */
459
 
460
#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
461
__externC cyg_bool_t
462
cyg_thread_add_destructor( cyg_thread_destructor_fn fn,
463
                           cyg_addrword_t data )
464
{
465
        return Cyg_Thread::self()->add_destructor( fn, data );
466
}
467
 
468
__externC cyg_bool_t
469
cyg_thread_rem_destructor( cyg_thread_destructor_fn fn,
470
                           cyg_addrword_t data )
471
{
472
        return Cyg_Thread::self()->rem_destructor( fn, data );
473
}
474
#endif
475
 
476
/*---------------------------------------------------------------------------*/
477
/* Exception handling.                                                       */
478
 
479
#ifdef CYGPKG_KERNEL_EXCEPTIONS    
480
externC void cyg_exception_set_handler(
481
    cyg_code_t                  exception_number,
482
    cyg_exception_handler_t     *new_handler,
483
    cyg_addrword_t              new_data,
484
    cyg_exception_handler_t     **old_handler,
485
    cyg_addrword_t              *old_data
486
)
487
{
488
    Cyg_Thread::register_exception(
489
        exception_number,
490
        (cyg_exception_handler *)new_handler,
491
        (CYG_ADDRWORD)new_data,
492
        (cyg_exception_handler **)old_handler,
493
        (CYG_ADDRWORD *)old_data
494
        );
495
}
496
 
497
/* Clear exception handler to default                                        */
498
externC void cyg_exception_clear_handler(
499
    cyg_code_t                  exception_number
500
)
501
{
502
    Cyg_Thread::deregister_exception( exception_number );
503
}
504
 
505
/* Invoke exception handler                                                  */
506
externC void cyg_exception_call_handler(
507
    cyg_handle_t                thread,
508
    cyg_code_t                  exception_number,
509
    cyg_addrword_t              error_code
510
)
511
{
512
    Cyg_Thread *t = (Cyg_Thread *)thread;
513
 
514
    t->deliver_exception( exception_number, error_code );
515
}
516
#endif    
517
 
518
/*---------------------------------------------------------------------------*/
519
/* Interrupt handling                                                        */
520
 
521
externC void cyg_interrupt_create(
522
    cyg_vector_t        vector,         /* Vector to attach to               */
523
    cyg_priority_t      priority,       /* Queue priority                    */
524
    cyg_addrword_t      data,           /* Data pointer                      */
525
    cyg_ISR_t           *isr,           /* Interrupt Service Routine         */
526
    cyg_DSR_t           *dsr,           /* Deferred Service Routine          */
527
    cyg_handle_t        *handle,        /* returned handle                   */
528
    cyg_interrupt       *intr           /* put interrupt here                */
529
)
530
{
531
    CYG_ASSERT_SIZES( cyg_interrupt, Cyg_Interrupt );
532
 
533
    Cyg_Interrupt *t = new((void *)intr) Cyg_Interrupt (
534
        (cyg_vector)vector,
535
        (cyg_priority)priority,
536
        (CYG_ADDRWORD)data,
537
        (cyg_ISR *)isr,
538
        (cyg_DSR *)dsr );
539
    t=t;
540
 
541
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
542
    *handle = (cyg_handle_t)intr;
543
}
544
 
545
externC void cyg_interrupt_delete( cyg_handle_t interrupt)
546
{
547
    ((Cyg_Interrupt *)interrupt)->~Cyg_Interrupt();
548
}
549
 
550
void cyg_interrupt_attach( cyg_handle_t interrupt )
551
{
552
    ((Cyg_Interrupt *)interrupt)->attach();
553
}
554
 
555
void cyg_interrupt_detach( cyg_handle_t interrupt )
556
{
557
    ((Cyg_Interrupt *)interrupt)->detach();
558
}
559
 
560
/* VSR manipulation */
561
 
562
externC void cyg_interrupt_get_vsr(
563
    cyg_vector_t        vector,         /* vector to get                     */
564
    cyg_VSR_t           **vsr           /* vsr got                           */
565
)
566
{
567
    Cyg_Interrupt::get_vsr( (cyg_vector)vector, (cyg_VSR **)vsr);
568
}
569
 
570
externC void cyg_interrupt_set_vsr(
571
    cyg_vector_t        vector,         /* vector to set                     */
572
    cyg_VSR_t           *vsr            /* vsr to set                        */
573
)
574
{
575
    Cyg_Interrupt::set_vsr( (cyg_vector)vector, (cyg_VSR *)vsr);
576
}
577
 
578
/* CPU level interrupt mask                                                  */
579
externC void cyg_interrupt_disable()
580
{
581
    Cyg_Interrupt::disable_interrupts();
582
}
583
 
584
externC void cyg_interrupt_enable()
585
{
586
    Cyg_Interrupt::enable_interrupts();
587
}
588
 
589
/* Interrupt controller access                                               */
590
externC void cyg_interrupt_mask(cyg_vector_t vector)
591
{
592
    Cyg_Interrupt::mask_interrupt( (cyg_vector)vector);
593
}
594
 
595
externC void cyg_interrupt_mask_intunsafe(cyg_vector_t vector)
596
{
597
    Cyg_Interrupt::mask_interrupt_intunsafe( (cyg_vector)vector);
598
}
599
 
600
externC void cyg_interrupt_unmask(cyg_vector_t vector)
601
{
602
    Cyg_Interrupt::unmask_interrupt( (cyg_vector)vector);
603
}
604
 
605
externC void cyg_interrupt_unmask_intunsafe(cyg_vector_t vector)
606
{
607
    Cyg_Interrupt::unmask_interrupt_intunsafe( (cyg_vector)vector);
608
}
609
 
610
externC void cyg_interrupt_acknowledge(cyg_vector_t vector)
611
{
612
    Cyg_Interrupt::acknowledge_interrupt( (cyg_vector)vector);
613
}
614
 
615
 
616
externC void cyg_interrupt_configure(
617
    cyg_vector_t        vector,         /* vector to configure               */
618
    cyg_bool_t          level,          /* level or edge triggered           */
619
    cyg_bool_t          up              /* rising/faling edge, high/low level*/
620
)
621
{
622
    Cyg_Interrupt::configure_interrupt( (cyg_vector)vector, level, up );
623
}
624
 
625
externC void cyg_interrupt_set_cpu(
626
    cyg_vector_t        vector,         /* vector to control                 */
627
    cyg_cpu_t           cpu             /* CPU to set                        */
628
)
629
{
630
#ifdef CYGPKG_KERNEL_SMP_SUPPORT    
631
    Cyg_Interrupt::set_cpu( vector, cpu );
632
#endif    
633
}
634
 
635
externC cyg_cpu_t cyg_interrupt_get_cpu(
636
    cyg_vector_t        vector          /* vector to control                 */
637
)
638
{
639
#ifdef CYGPKG_KERNEL_SMP_SUPPORT        
640
    return Cyg_Interrupt::get_cpu( vector );
641
#else
642
    return CYG_KERNEL_CPU_THIS();
643
#endif    
644
 
645
}
646
 
647
/*---------------------------------------------------------------------------*/
648
/* Counters, Clocks and Alarms                                               */
649
 
650
externC void cyg_counter_create(
651
    cyg_handle_t        *handle,        /* returned counter handle           */
652
    cyg_counter         *counter        /* put counter here                  */
653
)
654
{
655
    CYG_ASSERT_SIZES( cyg_counter, Cyg_Counter );
656
 
657
    Cyg_Counter *t = new((void *)counter) Cyg_Counter ();
658
    t=t;
659
 
660
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
661
    *handle = (cyg_handle_t)counter;
662
}
663
 
664
externC void cyg_counter_delete(cyg_handle_t counter)
665
{
666
    ((Cyg_Counter *)counter)->~Cyg_Counter();
667
}
668
 
669
/* Return current value of counter                                           */
670
externC cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter)
671
{
672
    return ((Cyg_Counter *)counter)->current_value();
673
}
674
 
675
/* Set new current value                                                     */
676
externC void cyg_counter_set_value(
677
    cyg_handle_t        counter,
678
    cyg_tick_count_t new_value
679
)
680
{
681
    ((Cyg_Counter *)counter)->set_value( new_value );
682
}
683
 
684
/* Advance counter by one tick                                               */
685
externC void cyg_counter_tick(cyg_handle_t counter)
686
{
687
    ((Cyg_Counter *)counter)->tick();
688
}
689
 
690
/* Advance counter by multiple ticks                                         */
691
externC void cyg_counter_multi_tick(cyg_handle_t counter, cyg_tick_count_t ticks)
692
{
693
    ((Cyg_Counter *)counter)->tick(ticks);
694
}
695
 
696
/* Create a clock object                */
697
externC void cyg_clock_create(
698
    cyg_resolution_t    resolution,     /* Initial resolution                */
699
    cyg_handle_t        *handle,        /* Returned clock handle             */
700
    cyg_clock           *clock          /* put clock here                    */
701
)
702
{
703
    CYG_ASSERT_SIZES( cyg_clock, Cyg_Clock );
704
 
705
    Cyg_Clock::cyg_resolution res;
706
 
707
    res.dividend = resolution.dividend;
708
    res.divisor  = resolution.divisor;
709
 
710
    Cyg_Clock *t = new((void *)clock) Cyg_Clock ( res );
711
    t=t;
712
 
713
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
714
    *handle = (cyg_handle_t)clock;
715
}
716
 
717
externC void cyg_clock_delete(cyg_handle_t clock)
718
{
719
    ((Cyg_Clock *)clock)->~Cyg_Clock();
720
}
721
 
722
/* convert a clock handle to a counter handle so we can use the              */
723
/* counter API on it.                                                        */
724
externC void cyg_clock_to_counter(
725
    cyg_handle_t        clock,
726
    cyg_handle_t        *counter
727
)
728
{
729
    CYG_CHECK_DATA_PTR( counter, "Bad counter handle pointer" );
730
    *counter = (cyg_handle_t)(Cyg_Counter *)clock;
731
}
732
 
733
externC void cyg_clock_set_resolution(
734
    cyg_handle_t        clock,
735
    cyg_resolution_t    resolution      /* New resolution                    */
736
)
737
{
738
    Cyg_Clock::cyg_resolution res;
739
 
740
    res.dividend = resolution.dividend;
741
    res.divisor  = resolution.divisor;
742
 
743
    ((Cyg_Clock *)clock)->set_resolution( res );
744
}
745
 
746
externC cyg_resolution_t cyg_clock_get_resolution(cyg_handle_t clock)
747
{
748
    Cyg_Clock::cyg_resolution res =
749
        ((Cyg_Clock *)clock)->get_resolution();
750
 
751
    cyg_resolution_t resolution;
752
 
753
    resolution.dividend = res.dividend;
754
    resolution.divisor  = res.divisor;
755
 
756
    return resolution;
757
}
758
 
759
#ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
760
externC cyg_handle_t cyg_real_time_clock(void)
761
{
762
    return (cyg_handle_t)Cyg_Clock::real_time_clock;
763
}
764
 
765
externC cyg_tick_count_t cyg_current_time(void)
766
{
767
    return Cyg_Clock::real_time_clock->current_value();
768
}
769
#endif
770
 
771
externC void cyg_alarm_create(
772
    cyg_handle_t        counter,        /* Attached to this counter          */
773
    cyg_alarm_t         *alarmfn,       /* Call-back function                */
774
    cyg_addrword_t      data,           /* Call-back data                    */
775
    cyg_handle_t        *handle,        /* Returned alarm object             */
776
    cyg_alarm           *alarm          /* put alarm here                    */
777
)
778
{
779
    CYG_ASSERT_SIZES( cyg_alarm, Cyg_Alarm );
780
 
781
    Cyg_Alarm *t = new((void *)alarm) Cyg_Alarm (
782
        (Cyg_Counter *)counter,
783
        (cyg_alarm_fn *)alarmfn,
784
        (CYG_ADDRWORD)data
785
    );
786
    t=t;
787
 
788
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
789
    *handle = (cyg_handle_t)alarm;
790
}
791
 
792
/* Disable alarm, detach from counter and invalidate handles                 */
793
externC void cyg_alarm_delete( cyg_handle_t alarm)
794
{
795
    ((Cyg_Alarm *)alarm)->~Cyg_Alarm();
796
}
797
 
798
externC void cyg_alarm_initialize(
799
    cyg_handle_t        alarm,
800
    cyg_tick_count_t    trigger,        /* Absolute trigger time             */
801
    cyg_tick_count_t    interval        /* Relative retrigger interval       */
802
)
803
{
804
    ((Cyg_Alarm *)alarm)->initialize(
805
        (cyg_tick_count)trigger,
806
        (cyg_tick_count)interval);
807
}
808
 
809
externC void cyg_alarm_get_times(
810
    cyg_handle_t        alarm,
811
    cyg_tick_count_t    *trigger,       /* Next trigger time                 */
812
    cyg_tick_count_t    *interval       /* Current interval                  */
813
)
814
{
815
    ((Cyg_Alarm *)alarm)->get_times(
816
        (cyg_tick_count*)trigger,
817
        (cyg_tick_count*)interval);
818
}
819
 
820
externC void cyg_alarm_enable( cyg_handle_t alarm )
821
{
822
    ((Cyg_Alarm *)alarm)->enable();
823
}
824
 
825
externC void cyg_alarm_disable( cyg_handle_t alarm )
826
{
827
    ((Cyg_Alarm *)alarm)->disable();
828
}
829
 
830
/*---------------------------------------------------------------------------*/
831
/* Mail boxes                                                                */
832
 
833
externC void cyg_mbox_create(
834
    cyg_handle_t        *handle,
835
    cyg_mbox            *mbox
836
)
837
{
838
    CYG_ASSERT_SIZES( cyg_mbox, Cyg_Mbox );
839
 
840
    Cyg_Mbox *t = new((void *)mbox) Cyg_Mbox();
841
    t=t;
842
 
843
    CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
844
    *handle = (cyg_handle_t)mbox;
845
}
846
 
847
externC void cyg_mbox_delete(cyg_handle_t mbox)
848
{
849
    ((Cyg_Mbox *)mbox)->~Cyg_Mbox();
850
}
851
 
852
externC void *cyg_mbox_get(cyg_handle_t mbox)
853
{
854
    return ((Cyg_Mbox *)mbox)->get();
855
}
856
 
857
#ifdef CYGFUN_KERNEL_THREADS_TIMER
858
void *cyg_mbox_timed_get(
859
    cyg_handle_t mbox,
860
    cyg_tick_count_t abstime
861
    )
862
{
863
    return ((Cyg_Mbox *)mbox)->get(abstime);
864
}
865
#endif
866
 
867
externC void *cyg_mbox_tryget(cyg_handle_t mbox)
868
{
869
    return ((Cyg_Mbox *)mbox)->tryget();
870
}
871
 
872
externC void *cyg_mbox_peek_item(cyg_handle_t mbox)
873
{
874
    return ((Cyg_Mbox *)mbox)->peek_item();
875
}
876
 
877
#ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
878
externC cyg_bool_t cyg_mbox_put(cyg_handle_t mbox, void *item)
879
{
880
    return ((Cyg_Mbox *)mbox)->put(item);
881
}
882
 
883
#ifdef CYGFUN_KERNEL_THREADS_TIMER
884
externC cyg_bool_t cyg_mbox_timed_put(
885
    cyg_handle_t mbox,
886
    void *item,
887
    cyg_tick_count_t abstime
888
    )
889
{
890
    return ((Cyg_Mbox *)mbox)->put(item, abstime);
891
}
892
#endif
893
#endif
894
 
895
externC cyg_bool_t cyg_mbox_tryput(cyg_handle_t mbox, void *item)
896
{
897
    return ((Cyg_Mbox *)mbox)->tryput(item);
898
}
899
 
900
externC cyg_count32 cyg_mbox_peek(cyg_handle_t mbox)
901
{
902
    return ((Cyg_Mbox *)mbox)->peek();
903
}
904
 
905
externC cyg_bool_t cyg_mbox_waiting_to_get(cyg_handle_t mbox)
906
{
907
    return ((Cyg_Mbox *)mbox)->waiting_to_get();
908
}
909
 
910
externC cyg_bool_t cyg_mbox_waiting_to_put(cyg_handle_t mbox)
911
{
912
    return ((Cyg_Mbox *)mbox)->waiting_to_put();
913
}
914
 
915
 
916
/*---------------------------------------------------------------------------*/
917
/* Semaphores                                                                */
918
 
919
externC void      cyg_semaphore_init(
920
    cyg_sem_t           *sem,            /* Semaphore to init                */
921
    cyg_count32         val              /* Initial semaphore value          */
922
)
923
{
924
    CYG_ASSERT_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
925
 
926
    Cyg_Counting_Semaphore *t = new((void *)sem) Cyg_Counting_Semaphore(val);
927
    t=t;
928
}
929
 
930
externC void cyg_semaphore_destroy( cyg_sem_t *sem )
931
{
932
    ((Cyg_Counting_Semaphore *)sem)->~Cyg_Counting_Semaphore();
933
}
934
 
935
externC cyg_bool_t cyg_semaphore_wait( cyg_sem_t *sem )
936
{
937
    return ((Cyg_Counting_Semaphore *)sem)->wait();
938
}
939
 
940
#ifdef CYGFUN_KERNEL_THREADS_TIMER
941
externC cyg_bool_t cyg_semaphore_timed_wait(
942
    cyg_sem_t          *sem,
943
    cyg_tick_count_t   abstime
944
    )
945
{
946
    return ((Cyg_Counting_Semaphore *)sem)->wait(abstime);
947
}
948
#endif
949
 
950
 
951
externC int cyg_semaphore_trywait( cyg_sem_t *sem )
952
{
953
    return ((Cyg_Counting_Semaphore *)sem)->trywait();
954
}
955
 
956
externC void cyg_semaphore_post( cyg_sem_t *sem )
957
{
958
    ((Cyg_Counting_Semaphore *)sem)->post();
959
}
960
 
961
externC void cyg_semaphore_peek( cyg_sem_t *sem, cyg_count32 *val )
962
{
963
    CYG_CHECK_DATA_PTR( val, "Bad val parameter" );
964
 
965
    *val = ((Cyg_Counting_Semaphore *)sem)->peek();
966
}
967
 
968
 
969
/*---------------------------------------------------------------------------*/
970
/* Flags                                                                     */
971
 
972
void cyg_flag_init(
973
    cyg_flag_t        *flag             /* Flag to init                      */
974
)
975
{
976
    CYG_ASSERT_SIZES( cyg_flag_t, Cyg_Flag );
977
    CYG_ASSERT(
978
        ( Cyg_Flag::AND == CYG_FLAG_WAITMODE_AND ) &&
979
        ( Cyg_Flag::OR  == CYG_FLAG_WAITMODE_OR  ) &&
980
        ( Cyg_Flag::CLR == CYG_FLAG_WAITMODE_CLR ),
981
        "CYG_FLAG_WAITMODE_xxx definition != C++ Cyg_Flag::xxx" );
982
 
983
    Cyg_Flag *t = new((void *)flag) Cyg_Flag();
984
    t=t;
985
}
986
 
987
void cyg_flag_destroy( cyg_flag_t *flag )
988
{
989
    ((Cyg_Flag *)flag)->~Cyg_Flag();
990
}
991
 
992
void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value)
993
{
994
    ((Cyg_Flag *)flag)->setbits( value );
995
}
996
 
997
void cyg_flag_maskbits( cyg_flag_t *flag, cyg_flag_value_t value)
998
{
999
    ((Cyg_Flag *)flag)->maskbits( value );
1000
}
1001
 
1002
cyg_flag_value_t cyg_flag_wait( cyg_flag_t        *flag,
1003
                                cyg_flag_value_t   pattern,
1004
                                cyg_flag_mode_t    mode )
1005
{
1006
    if ( 0 == pattern || 0 != (mode & ~3) )
1007
        return 0;
1008
    return ((Cyg_Flag *)flag)->wait( pattern, mode );
1009
 
1010
}
1011
 
1012
#ifdef CYGFUN_KERNEL_THREADS_TIMER
1013
cyg_flag_value_t cyg_flag_timed_wait( cyg_flag_t        *flag,
1014
                                      cyg_flag_value_t   pattern,
1015
                                      cyg_flag_mode_t    mode,
1016
                                      cyg_tick_count_t   abstime )
1017
{
1018
    if ( 0 == pattern || 0 != (mode & ~3) )
1019
        return 0;
1020
    return ((Cyg_Flag *)flag)->wait( pattern, mode, abstime );
1021
 
1022
}
1023
#endif
1024
 
1025
cyg_flag_value_t cyg_flag_poll( cyg_flag_t         *flag,
1026
                                cyg_flag_value_t    pattern,
1027
                                cyg_flag_mode_t     mode )
1028
{
1029
    if ( 0 == pattern || 0 != (mode & ~3) )
1030
        return 0;
1031
    return ((Cyg_Flag *)flag)->poll( pattern, mode );
1032
 
1033
}
1034
 
1035
cyg_flag_value_t cyg_flag_peek( cyg_flag_t *flag )
1036
{
1037
    return ((Cyg_Flag *)flag)->peek();
1038
}
1039
 
1040
cyg_bool_t cyg_flag_waiting( cyg_flag_t *flag )
1041
{
1042
    return ((Cyg_Flag *)flag)->waiting();
1043
}
1044
 
1045
/*---------------------------------------------------------------------------*/
1046
/* Mutex                                                                     */
1047
 
1048
externC void cyg_mutex_init(
1049
    cyg_mutex_t        *mutex          /* Mutex to init                      */
1050
)
1051
{
1052
    CYG_ASSERT_SIZES( cyg_mutex_t, Cyg_Mutex );
1053
 
1054
    Cyg_Mutex *m = new((void *)mutex) Cyg_Mutex;
1055
 
1056
    m=m;
1057
}
1058
 
1059
externC void cyg_mutex_destroy( cyg_mutex_t *mutex )
1060
{
1061
    ((Cyg_Mutex *)mutex)->~Cyg_Mutex();
1062
}
1063
 
1064
externC cyg_bool_t cyg_mutex_lock( cyg_mutex_t *mutex )
1065
{
1066
    return ((Cyg_Mutex *)mutex)->lock();
1067
}
1068
 
1069
externC cyg_bool_t cyg_mutex_trylock( cyg_mutex_t *mutex )
1070
{
1071
    return ((Cyg_Mutex *)mutex)->trylock();
1072
}
1073
 
1074
externC void cyg_mutex_unlock( cyg_mutex_t *mutex )
1075
{
1076
    ((Cyg_Mutex *)mutex)->unlock();
1077
}
1078
 
1079
externC void cyg_mutex_release( cyg_mutex_t *mutex )
1080
{
1081
    ((Cyg_Mutex *)mutex)->release();
1082
}
1083
 
1084
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_CEILING
1085
externC void cyg_mutex_set_ceiling(
1086
    cyg_mutex_t *mutex,
1087
    cyg_priority_t priority )
1088
{
1089
    ((Cyg_Mutex *)mutex)->set_ceiling(priority);
1090
}
1091
#endif
1092
 
1093
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_DYNAMIC
1094
externC void cyg_mutex_set_protocol(
1095
    cyg_mutex_t *mutex,
1096
    enum cyg_mutex_protocol protocol )
1097
{
1098
    ((Cyg_Mutex *)mutex)->set_protocol((Cyg_Mutex::cyg_protcol)protocol);
1099
}
1100
#endif
1101
 
1102
/*---------------------------------------------------------------------------*/
1103
/* Condition Variables                                                       */
1104
 
1105
externC void cyg_cond_init(
1106
    cyg_cond_t          *cond,          /* condition variable to init        */
1107
    cyg_mutex_t         *mutex          /* associated mutex                  */
1108
)
1109
{
1110
    CYG_ASSERT_SIZES( cyg_cond_t, Cyg_Condition_Variable );
1111
 
1112
    Cyg_Condition_Variable *t = new((void *)cond) Cyg_Condition_Variable(
1113
        *(Cyg_Mutex *)mutex);
1114
    t=t;
1115
}
1116
 
1117
externC void cyg_cond_destroy( cyg_cond_t *cond )
1118
{
1119
    ((Cyg_Condition_Variable *)cond)->~Cyg_Condition_Variable();
1120
}
1121
 
1122
externC cyg_bool_t cyg_cond_wait( cyg_cond_t *cond )
1123
{
1124
    return ((Cyg_Condition_Variable *)cond)->wait();
1125
}
1126
 
1127
externC void cyg_cond_signal( cyg_cond_t *cond )
1128
{
1129
    ((Cyg_Condition_Variable *)cond)->signal();
1130
}
1131
 
1132
externC void cyg_cond_broadcast( cyg_cond_t *cond )
1133
{
1134
    ((Cyg_Condition_Variable *)cond)->broadcast();
1135
}
1136
 
1137
#ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
1138
externC cyg_bool_t cyg_cond_timed_wait(
1139
    cyg_cond_t        *cond,
1140
    cyg_tick_count_t  abstime
1141
    )
1142
{
1143
    return ((Cyg_Condition_Variable *)cond)->wait(abstime);
1144
}
1145
 
1146
#endif
1147
 
1148
/*---------------------------------------------------------------------------*/
1149
/* Spinlocks                                                                 */
1150
 
1151
externC void cyg_spinlock_init(
1152
    cyg_spinlock_t      *lock,          /* spinlock to initialize            */
1153
    cyg_bool_t          locked          /* init locked or unlocked           */
1154
)
1155
{
1156
    CYG_ASSERT_SIZES( cyg_spinlock_t, Cyg_SpinLock );
1157
 
1158
    // Create the spinlock in cleared state
1159
    Cyg_SpinLock *t = new((void *)lock) Cyg_SpinLock();
1160
 
1161
    // If the lock is to start locked, then lock it now.
1162
    if( locked )
1163
        t->spin();
1164
}
1165
 
1166
externC void cyg_spinlock_destroy( cyg_spinlock_t *lock )
1167
{
1168
    ((Cyg_SpinLock *)lock)->~Cyg_SpinLock();
1169
}
1170
 
1171
externC void cyg_spinlock_spin( cyg_spinlock_t *lock )
1172
{
1173
    ((Cyg_SpinLock *)lock)->spin();
1174
}
1175
 
1176
externC void cyg_spinlock_clear( cyg_spinlock_t *lock )
1177
{
1178
    ((Cyg_SpinLock *)lock)->clear();
1179
}
1180
 
1181
externC cyg_bool_t cyg_spinlock_try( cyg_spinlock_t *lock )
1182
{
1183
    return ((Cyg_SpinLock *)lock)->trylock();
1184
}
1185
 
1186
externC cyg_bool_t cyg_spinlock_test( cyg_spinlock_t *lock )
1187
{
1188
    return ((Cyg_SpinLock *)lock)->test();
1189
}
1190
 
1191
externC void cyg_spinlock_spin_intsave( cyg_spinlock_t *lock,
1192
                                cyg_addrword_t *istate )
1193
{
1194
    ((Cyg_SpinLock *)lock)->spin_intsave((CYG_INTERRUPT_STATE *)istate);
1195
}
1196
 
1197
externC void cyg_spinlock_clear_intsave( cyg_spinlock_t *lock,
1198
                                 cyg_addrword_t istate )
1199
{
1200
    ((Cyg_SpinLock *)lock)->clear_intsave((CYG_INTERRUPT_STATE)istate);
1201
}
1202
 
1203
 
1204
// -------------------------------------------------------------------------
1205
// Check structure sizes.
1206
// This class and constructor get run automatically in debug versions
1207
// of the kernel and check that the structures configured in the C
1208
// code are the same size as the C++ classes they should match.
1209
 
1210
#ifdef CYGPKG_INFRA_DEBUG
1211
 
1212
class Cyg_Check_Structure_Sizes
1213
{
1214
    int dummy;
1215
public:
1216
    Cyg_Check_Structure_Sizes( int x );
1217
 
1218
};
1219
 
1220
#define CYG_CHECK_SIZES(cstruct, cxxstruct)                               \
1221
if( sizeof(cstruct) != sizeof(cxxstruct) )                                \
1222
{                                                                         \
1223
    char *fmt = "Size of C struct " #cstruct                              \
1224
                " != size of C++ struct " #cxxstruct ;                    \
1225
    CYG_TRACE2(1, fmt, sizeof(cstruct) , sizeof(cxxstruct) );             \
1226
    fail = true;                                                          \
1227
    fmt = fmt;                                                            \
1228
}
1229
 
1230
Cyg_Check_Structure_Sizes::Cyg_Check_Structure_Sizes(int x)
1231
{
1232
    cyg_bool fail = false;
1233
 
1234
    dummy = x+1;
1235
 
1236
    CYG_CHECK_SIZES( cyg_thread, Cyg_Thread );
1237
    CYG_CHECK_SIZES( cyg_interrupt, Cyg_Interrupt );
1238
    CYG_CHECK_SIZES( cyg_counter, Cyg_Counter );
1239
    CYG_CHECK_SIZES( cyg_clock, Cyg_Clock );
1240
    CYG_CHECK_SIZES( cyg_alarm, Cyg_Alarm );
1241
    CYG_CHECK_SIZES( cyg_mbox, Cyg_Mbox );
1242
    CYG_CHECK_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
1243
    CYG_CHECK_SIZES( cyg_flag_t, Cyg_Flag );
1244
    CYG_CHECK_SIZES( cyg_mutex_t, Cyg_Mutex );
1245
    CYG_CHECK_SIZES( cyg_cond_t, Cyg_Condition_Variable );
1246
    CYG_CHECK_SIZES( cyg_spinlock_t, Cyg_SpinLock );
1247
 
1248
    CYG_ASSERT( !fail, "Size checks failed");
1249
}
1250
 
1251
static Cyg_Check_Structure_Sizes cyg_kapi_check_structure_sizes(1);
1252
 
1253
#endif
1254
 
1255
 
1256
// -------------------------------------------------------------------------
1257
 
1258
#endif
1259
// EOF common/kapi.cxx

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.