comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3111d98ba7b3
1 //==========================================================================
2 //
3 // common/kapi.cxx
4 //
5 // C API Implementation
6 //
7 //==========================================================================
8 //####COPYRIGHTBEGIN####
9 //
10 // -------------------------------------------
11 // The contents of this file are subject to the Cygnus eCos Public License
12 // Version 1.0 (the "License"); you may not use this file except in
13 // compliance with the License. You may obtain a copy of the License at
14 // http://sourceware.cygnus.com/ecos
15 //
16 // Software distributed under the License is distributed on an "AS IS"
17 // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
18 // License for the specific language governing rights and limitations under
19 // the License.
20 //
21 // The Original Code is eCos - Embedded Cygnus Operating System, released
22 // September 30, 1998.
23 //
24 // The Initial Developer of the Original Code is Cygnus. Portions created
25 // by Cygnus are Copyright (C) 1998 Cygnus Solutions. All Rights Reserved.
26 // -------------------------------------------
27 //
28 //####COPYRIGHTEND####
29 //==========================================================================
30 //#####DESCRIPTIONBEGIN####
31 //
32 // Author(s): nickg, dsm
33 // Contributors: nickg
34 // Date: 1998-03-02
35 // Purpose: C API Implementation
36 // Description: C++ implementation of the C API
37 //
38 //
39 //####DESCRIPTIONEND####
40 //
41 //==========================================================================
42
43 #include <pkgconf/kernel.h>
44
45 #ifdef CYGFUN_KERNEL_API_C
46
47 #include <cyg/kernel/ktypes.h> // base kernel types
48 #include <cyg/infra/cyg_trac.h> // tracing macros
49 #include <cyg/infra/cyg_ass.h> // assertion macros
50 #include <cyg/kernel/instrmnt.h> // instrumentation
51 #include <cyg/kernel/diag.h>
52
53 #include <cyg/kernel/thread.hxx>
54 #include <cyg/kernel/thread.inl> // thread inlines
55 #include <cyg/kernel/sched.hxx>
56 #include <cyg/kernel/intr.hxx>
57 #include <cyg/kernel/clock.hxx>
58
59 #include <cyg/kernel/memfixed.hxx>
60 #include <cyg/kernel/memvar.hxx>
61
62 #include <cyg/kernel/sema.hxx>
63 #include <cyg/kernel/flag.hxx>
64 #include <cyg/kernel/mutex.hxx>
65 #include <cyg/kernel/mbox.hxx>
66
67 #include <cyg/kernel/sched.inl> // scheduler inlines
68 #include <cyg/kernel/clock.inl> // clock inlines
69
70 #include <cyg/kernel/kapi.h> // C API
71
72 // -------------------------------------------------------------------------
73 // Magic new function
74
75 inline void *operator new(size_t size, void *ptr)
76 {
77 CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );
78 return ptr;
79 }
80
81 // -------------------------------------------------------------------------
82
83 #ifdef CYGDBG_USE_ASSERTS
84
85 #define CYG_ASSERT_SIZES(cstruct, cxxstruct) \
86 CYG_MACRO_START \
87 char *msg = "Size of C struct " #cstruct \
88 " != size of C++ struct " #cxxstruct ; \
89 CYG_ASSERT( sizeof(cstruct) == sizeof(cxxstruct) , msg ); \
90 CYG_MACRO_END
91
92 #else
93
94 #define CYG_ASSERT_SIZES(cstruct, cxxstruct)
95
96 #endif
97
98 /*---------------------------------------------------------------------------*/
99 /* Scheduler operations */
100
101 /* Starts scheduler with created threads. Never returns. */
102 externC void cyg_scheduler_start(void)
103 {
104 Cyg_Scheduler::start();
105 }
106
107 /* Lock the scheduler. We only allow this to take the lock from */
108 /* zero to 1. Any other transition implies that this function */
109 /* is being called from an ISR/DSR or some other illegal place. */
110 externC void cyg_scheduler_lock(void)
111 {
112 Cyg_Scheduler::lock();
113
114 CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
115 "Cannot nest calls to cyg_scheduler_lock");
116
117 if( Cyg_Scheduler::get_sched_lock() != 1 )
118 Cyg_Scheduler::unlock();
119 }
120
121 /* Unlock the scheduler. Like lock, we only allow a 1->0 */
122 /* transition. */
123 externC void cyg_scheduler_unlock(void)
124 {
125 CYG_ASSERT( Cyg_Scheduler::get_sched_lock() == 1 ,
126 "Bad call to cyg_scheduler_unlock");
127
128 if( Cyg_Scheduler::get_sched_lock() == 1 )
129 Cyg_Scheduler::unlock();
130
131 }
132
133 /*---------------------------------------------------------------------------*/
134 /* Thread operations */
135
136 externC void cyg_thread_create(
137 cyg_addrword_t sched_info, /* scheduling info (eg pri) */
138 cyg_thread_entry_t *entry, /* entry point function */
139 cyg_addrword_t entry_data, /* entry data */
140 char *name, /* optional thread name */
141 void *stack_base, /* stack base, NULL = alloc */
142 cyg_ucount32 stack_size, /* stack size, 0 = default */
143 cyg_handle_t *handle, /* returned thread handle */
144 cyg_thread *thread /* put thread here */
145 )
146 {
147 CYG_ASSERT_SIZES( cyg_thread, Cyg_Thread );
148
149 Cyg_Thread *t = new((void *)thread) Cyg_Thread (
150 (CYG_ADDRWORD) sched_info,
151 (cyg_thread_entry *)entry,
152 (CYG_ADDRWORD) entry_data,
153 name,
154 (CYG_ADDRWORD) stack_base,
155 stack_size
156 );
157 t=t;
158
159 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
160 *handle = (cyg_handle_t)thread;
161 }
162
163 externC void cyg_thread_exit()
164 {
165 Cyg_Thread::exit();
166 }
167
168 externC void cyg_thread_suspend(cyg_handle_t thread)
169 {
170 ((Cyg_Thread *)thread)->suspend();
171 }
172
173 externC void cyg_thread_resume(cyg_handle_t thread)
174 {
175 Cyg_Thread *th = (Cyg_Thread *)thread;
176
177 // If we are resuming an exited thread then
178 // reinitialize it.
179
180 if( th->get_state() == Cyg_Thread::EXITED )
181 th->reinitialize();
182
183 th->resume();
184 }
185
186 externC void cyg_thread_kill( cyg_handle_t thread)
187 {
188 ((Cyg_Thread *)thread)->kill();
189 }
190
191 externC void cyg_thread_yield()
192 {
193 Cyg_Thread::yield();
194 }
195
196 externC cyg_handle_t cyg_thread_self()
197 {
198 return (cyg_handle_t)Cyg_Thread::self();
199 }
200
201 /* Priority manipulation */
202 externC void cyg_thread_set_priority(
203 cyg_handle_t thread, cyg_priority_t priority )
204 {
205 ((Cyg_Thread *)thread)->set_priority(priority);
206 }
207
208 externC cyg_priority_t cyg_thread_get_priority(cyg_handle_t thread)
209 {
210 return ((Cyg_Thread *)thread)->get_priority();
211 }
212
213 /* Deadline scheduling control (optional) */
214
215 externC void cyg_thread_deadline_wait(
216 cyg_tick_count_t start_time, /* abs earliest start time */
217 cyg_tick_count_t run_time, /* worst case execution time */
218 cyg_tick_count_t deadline /* absolute deadline */
219 )
220 {
221 CYG_ASSERT(0,"Not implemented");
222 }
223
224 externC void cyg_thread_delay(cyg_tick_count_t delay)
225 {
226 Cyg_Thread::self()->delay(delay);
227 }
228
229
230 /*---------------------------------------------------------------------------*/
231 /* Exception handling. */
232
233 #ifdef CYGPKG_KERNEL_EXCEPTIONS
234 externC void cyg_exception_set_handler(
235 cyg_code_t exception_number,
236 cyg_exception_handler_t *new_handler,
237 cyg_addrword_t new_data,
238 cyg_exception_handler_t **old_handler,
239 cyg_addrword_t *old_data
240 )
241 {
242 Cyg_Thread::register_exception(
243 exception_number,
244 (cyg_exception_handler *)new_handler,
245 (CYG_ADDRWORD)new_data,
246 (cyg_exception_handler **)old_handler,
247 (CYG_ADDRWORD *)old_data
248 );
249 }
250
251 /* Clear exception handler to default */
252 externC void cyg_exception_clear_handler(
253 cyg_code_t exception_number
254 )
255 {
256 Cyg_Thread::deregister_exception( exception_number );
257 }
258
259 /* Invoke exception handler */
260 externC void cyg_exception_call_handler(
261 cyg_handle_t thread,
262 cyg_code_t exception_number,
263 cyg_code_t error_code
264 )
265 {
266 Cyg_Thread *t = (Cyg_Thread *)thread;
267
268 t->deliver_exception( exception_number, error_code );
269 }
270 #endif
271
272 /*---------------------------------------------------------------------------*/
273 /* Interrupt handling */
274
275 externC void cyg_interrupt_create(
276 cyg_vector_t vector, /* Vector to attach to */
277 cyg_priority_t priority, /* Queue priority */
278 cyg_addrword_t data, /* Data pointer */
279 cyg_ISR_t *isr, /* Interrupt Service Routine */
280 cyg_DSR_t *dsr, /* Deferred Service Routine */
281 cyg_handle_t *handle, /* returned handle */
282 cyg_interrupt *intr /* put interrupt here */
283 )
284 {
285 CYG_ASSERT_SIZES( cyg_interrupt, Cyg_Interrupt );
286
287 Cyg_Interrupt *t = new((void *)intr) Cyg_Interrupt (
288 (cyg_vector)vector,
289 (cyg_priority)priority,
290 (CYG_ADDRWORD)data,
291 (cyg_ISR *)isr,
292 (cyg_DSR *)dsr );
293 t=t;
294
295 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
296 *handle = (cyg_handle_t)intr;
297 }
298
299 externC void cyg_interrupt_delete( cyg_handle_t interrupt)
300 {
301 ((Cyg_Interrupt *)interrupt)->~Cyg_Interrupt();
302 }
303
304 void cyg_interrupt_attach( cyg_handle_t interrupt )
305 {
306 ((Cyg_Interrupt *)interrupt)->attach();
307 }
308
309 void cyg_interrupt_detach( cyg_handle_t interrupt )
310 {
311 ((Cyg_Interrupt *)interrupt)->detach();
312 }
313
314 /* VSR manipulation */
315
316 externC void cyg_interrupt_get_vsr(
317 cyg_vector_t vector, /* vector to get */
318 cyg_VSR_t **vsr /* vsr got */
319 )
320 {
321 Cyg_Interrupt::get_vsr( (cyg_vector)vector, (cyg_VSR **)vsr);
322 }
323
324 externC void cyg_interrupt_set_vsr(
325 cyg_vector_t vector, /* vector to set */
326 cyg_VSR_t *vsr /* vsr to set */
327 )
328 {
329 Cyg_Interrupt::set_vsr( (cyg_vector)vector, (cyg_VSR *)vsr);
330 }
331
332 /* CPU level interrupt mask */
333 externC void cyg_interrupt_disable()
334 {
335 Cyg_Interrupt::disable_interrupts();
336 }
337
338 externC void cyg_interrupt_enable()
339 {
340 Cyg_Interrupt::enable_interrupts();
341 }
342
343 /* Interrupt controller access */
344 externC void cyg_interrupt_mask(cyg_vector_t vector)
345 {
346 Cyg_Interrupt::mask_interrupt( (cyg_vector)vector);
347 }
348
349 externC void cyg_interrupt_unmask(cyg_vector_t vector)
350 {
351 Cyg_Interrupt::unmask_interrupt( (cyg_vector)vector);
352 }
353
354
355 externC void cyg_interrupt_acknowledge(cyg_vector_t vector)
356 {
357 Cyg_Interrupt::acknowledge_interrupt( (cyg_vector)vector);
358 }
359
360
361 externC void cyg_interrupt_configure(
362 cyg_vector_t vector, /* vector to configure */
363 cyg_bool_t level, /* level or edge triggered */
364 cyg_bool_t up /* rising/faling edge, high/low level*/
365 )
366 {
367 Cyg_Interrupt::configure_interrupt( (cyg_vector)vector, level, up );
368 }
369
370
371 /*---------------------------------------------------------------------------*/
372 /* Counters, Clocks and Alarms */
373
374 externC void cyg_counter_create(
375 cyg_handle_t *handle, /* returned counter handle */
376 cyg_counter *counter /* put counter here */
377 )
378 {
379 CYG_ASSERT_SIZES( cyg_counter, Cyg_Counter );
380
381 Cyg_Counter *t = new((void *)counter) Cyg_Counter ();
382 t=t;
383
384 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
385 *handle = (cyg_handle_t)counter;
386 }
387
388 externC void cyg_counter_delete(cyg_handle_t counter)
389 {
390 ((Cyg_Counter *)counter)->~Cyg_Counter();
391 }
392
393 /* Return current value of counter */
394 externC cyg_tick_count_t cyg_counter_current_value(cyg_handle_t counter)
395 {
396 return ((Cyg_Counter *)counter)->current_value();
397 }
398
399 /* Set new current value */
400 externC void cyg_counter_set_value(
401 cyg_handle_t counter,
402 cyg_tick_count_t new_value
403 )
404 {
405 ((Cyg_Counter *)counter)->set_value( new_value );
406 }
407
408 /* Advance counter by one tick */
409 externC void cyg_counter_tick(cyg_handle_t counter)
410 {
411 ((Cyg_Counter *)counter)->tick();
412 }
413
414 /* Create a clock object */
415 externC void cyg_clock_create(
416 cyg_resolution_t resolution, /* Initial resolution */
417 cyg_handle_t *handle, /* Returned clock handle */
418 cyg_clock *clock /* put clock here */
419 )
420 {
421 CYG_ASSERT_SIZES( cyg_clock, Cyg_Clock );
422
423 Cyg_Clock::cyg_resolution res;
424
425 res.dividend = resolution.dividend;
426 res.divisor = resolution.divisor;
427
428 Cyg_Clock *t = new((void *)clock) Cyg_Clock ( res );
429 t=t;
430
431 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
432 *handle = (cyg_handle_t)clock;
433 }
434
435 externC void cyg_clock_delete(cyg_handle_t clock)
436 {
437 ((Cyg_Clock *)clock)->~Cyg_Clock();
438 }
439
440 /* convert a clock handle to a counter handle so we can use the */
441 /* counter API on it. */
442 externC void cyg_clock_to_counter(
443 cyg_handle_t clock,
444 cyg_handle_t *counter
445 )
446 {
447 CYG_CHECK_DATA_PTR( counter, "Bad counter handle pointer" );
448 *counter = (cyg_handle_t)(Cyg_Counter *)clock;
449 }
450
451 externC void cyg_clock_set_resolution(
452 cyg_handle_t clock,
453 cyg_resolution_t resolution /* New resolution */
454 )
455 {
456 Cyg_Clock::cyg_resolution res;
457
458 res.dividend = resolution.dividend;
459 res.divisor = resolution.divisor;
460
461 ((Cyg_Clock *)clock)->set_resolution( res );
462 }
463
464 externC cyg_resolution_t cyg_clock_get_resolution(cyg_handle_t clock)
465 {
466 Cyg_Clock::cyg_resolution res =
467 ((Cyg_Clock *)clock)->get_resolution();
468
469 cyg_resolution_t resolution;
470
471 resolution.dividend = res.dividend;
472 resolution.divisor = res.divisor;
473
474 return resolution;
475 }
476
477 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
478 externC cyg_handle_t cyg_real_time_clock(void)
479 {
480 return (cyg_handle_t)Cyg_Clock::real_time_clock;
481 }
482
483 externC cyg_tick_count_t cyg_current_time(void)
484 {
485 return Cyg_Clock::real_time_clock->current_value();
486 }
487 #endif
488
489 externC void cyg_alarm_create(
490 cyg_handle_t counter, /* Attached to this counter */
491 cyg_alarm_t *alarmfn, /* Call-back function */
492 cyg_addrword_t data, /* Call-back data */
493 cyg_handle_t *handle, /* Returned alarm object */
494 cyg_alarm *alarm /* put alarm here */
495 )
496 {
497 CYG_ASSERT_SIZES( cyg_alarm, Cyg_Alarm );
498
499 Cyg_Alarm *t = new((void *)alarm) Cyg_Alarm (
500 (Cyg_Counter *)counter,
501 (cyg_alarm_fn *)alarmfn,
502 (CYG_ADDRWORD)data
503 );
504 t=t;
505
506 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
507 *handle = (cyg_handle_t)alarm;
508 }
509
510 /* Disable alarm, detach from counter and invalidate handles */
511 externC void cyg_alarm_delete( cyg_handle_t alarm)
512 {
513 ((Cyg_Alarm *)alarm)->~Cyg_Alarm();
514 }
515
516 externC void cyg_alarm_initialize(
517 cyg_handle_t alarm,
518 cyg_tick_count_t trigger, /* Absolute trigger time */
519 cyg_tick_count_t interval /* Relative retrigger interval */
520 )
521 {
522 ((Cyg_Alarm *)alarm)->initialize(
523 (cyg_tick_count)trigger,
524 (cyg_tick_count)interval);
525 }
526
527 externC void cyg_alarm_enable( cyg_handle_t alarm )
528 {
529 ((Cyg_Alarm *)alarm)->enable();
530 }
531
532 externC void cyg_alarm_disable( cyg_handle_t alarm )
533 {
534 ((Cyg_Alarm *)alarm)->disable();
535 }
536
537 /*---------------------------------------------------------------------------*/
538 /* Mail boxes */
539
540 externC void cyg_mbox_create(
541 cyg_handle_t *handle,
542 cyg_mbox *mbox
543 )
544 {
545 CYG_ASSERT_SIZES( cyg_mbox, Cyg_Mbox );
546
547 Cyg_Mbox *t = new((void *)mbox) Cyg_Mbox();
548 t=t;
549
550 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
551 *handle = (cyg_handle_t)mbox;
552 }
553
554 externC void cyg_mbox_delete(cyg_handle_t mbox)
555 {
556 ((Cyg_Mbox *)mbox)->~Cyg_Mbox();
557 }
558
559 externC void *cyg_mbox_get(cyg_handle_t mbox)
560 {
561 return ((Cyg_Mbox *)mbox)->get();
562 }
563
564 #ifdef CYGFUN_KERNEL_THREADS_TIMER
565 void *cyg_mbox_timed_get(
566 cyg_handle_t mbox,
567 cyg_tick_count_t abstime
568 )
569 {
570 return ((Cyg_Mbox *)mbox)->get(abstime);
571 }
572 #endif
573
574 externC void *cyg_mbox_tryget(cyg_handle_t mbox)
575 {
576 return ((Cyg_Mbox *)mbox)->tryget();
577 }
578
579 externC void *cyg_mbox_peek_item(cyg_handle_t mbox)
580 {
581 return ((Cyg_Mbox *)mbox)->peek_item();
582 }
583
584 #ifdef CYGMFN_KERNEL_SYNCH_MBOXT_PUT_CAN_WAIT
585 externC cyg_bool_t cyg_mbox_put(cyg_handle_t mbox, void *item)
586 {
587 return ((Cyg_Mbox *)mbox)->put(item);
588 }
589
590 #ifdef CYGFUN_KERNEL_THREADS_TIMER
591 externC cyg_bool_t cyg_mbox_timed_put(
592 cyg_handle_t mbox,
593 void *item,
594 cyg_tick_count_t abstime
595 )
596 {
597 return ((Cyg_Mbox *)mbox)->put(item, abstime);
598 }
599 #endif
600 #endif
601
602 externC cyg_bool_t cyg_mbox_tryput(cyg_handle_t mbox, void *item)
603 {
604 return ((Cyg_Mbox *)mbox)->tryput(item);
605 }
606
607 externC cyg_count32 cyg_mbox_peek(cyg_handle_t mbox)
608 {
609 return ((Cyg_Mbox *)mbox)->peek();
610 }
611
612 externC cyg_bool_t cyg_mbox_waiting_to_get(cyg_handle_t mbox)
613 {
614 return ((Cyg_Mbox *)mbox)->waiting_to_get();
615 }
616
617 externC cyg_bool_t cyg_mbox_waiting_to_put(cyg_handle_t mbox)
618 {
619 return ((Cyg_Mbox *)mbox)->waiting_to_put();
620 }
621
622
623 /*-----------------------------------------------------------------------*/
624 /* Memory pools */
625
626 /* Create a variable size memory pool */
627 externC void cyg_mempool_var_create(
628 void *base, /* base of memory to use for pool */
629 cyg_int32 size, /* size of memory in bytes */
630 cyg_handle_t *handle, /* returned handle of memory pool */
631 cyg_mempool_var *var /* space to put pool structure in */
632 )
633 {
634 CYG_ASSERT_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
635
636 Cyg_Mempool_Variable *t = new((void *)var) Cyg_Mempool_Variable (
637 (cyg_uint8 *)base,
638 size
639 );
640 t=t;
641
642 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
643 *handle = (cyg_handle_t)var;
644 }
645
646 /* Delete variable size memory pool */
647 externC void cyg_mempool_var_delete(cyg_handle_t varpool)
648 {
649 ((Cyg_Mempool_Variable *)varpool)->~Cyg_Mempool_Variable();
650 }
651
652 /* Allocates a block of length size. This waits if the memory is not
653 currently available. */
654 externC void *cyg_mempool_var_alloc(cyg_handle_t varpool, cyg_int32 size)
655 {
656 return ((Cyg_Mempool_Variable *)varpool)->alloc(size);
657 }
658
659 #ifdef CYGFUN_KERNEL_THREADS_TIMER
660
661 /* Allocates a block of length size. This waits for up to delay
662 ticks, if the memory is not already available. NULL is returned if
663 no memory is available. */
664 externC void *cyg_mempool_var_timed_alloc(
665 cyg_handle_t varpool,
666 cyg_int32 size,
667 cyg_tick_count_t abstime)
668 {
669 return ((Cyg_Mempool_Variable *)varpool)->alloc(size, abstime);
670 }
671
672 #endif
673
674 /* Allocates a block of length size. NULL is returned if no memory is
675 available. */
676 externC void *cyg_mempool_var_try_alloc(
677 cyg_handle_t varpool,
678 cyg_int32 size)
679 {
680 return ((Cyg_Mempool_Variable *)varpool)->try_alloc(size);
681 }
682
683 /* Frees memory back into variable size pool. */
684 externC void cyg_mempool_var_free(cyg_handle_t varpool, void *p)
685 {
686 cyg_bool b;
687 b = ((Cyg_Mempool_Variable *)varpool)->free((cyg_uint8 *)p, 0);
688 CYG_ASSERT( b, "Bad free");
689 }
690
691
692 /* Returns true if there are any threads waiting for memory in the
693 given memory pool. */
694 externC cyg_bool_t cyg_mempool_var_waiting(cyg_handle_t varpool)
695 {
696 return ((Cyg_Mempool_Variable *)varpool)->waiting();
697 }
698
699 /* Puts information about a variable memory pool into the structure
700 provided. */
701 externC void cyg_mempool_var_get_info(
702 cyg_handle_t varpool,
703 cyg_mempool_info *info)
704 {
705 Cyg_Mempool_Variable *v = (Cyg_Mempool_Variable *)varpool;
706 cyg_uint8 *base;
707 CYG_ADDRWORD maxfree;
708
709 info->totalmem = v->get_totalmem();
710 info->freemem = v->get_freemem();
711 v->get_arena(base, info->size, maxfree);
712 info->base = (void *)base;
713 info->blocksize = -1;
714 info->maxfree = maxfree;
715 }
716
717
718 /* Create a fixed size memory pool */
719 externC void cyg_mempool_fix_create(
720 void *base, // base of memory to use for pool
721 cyg_int32 size, // size of memory in byte
722 cyg_int32 blocksize, // size of allocation in bytes
723 cyg_handle_t *handle, // handle of memory pool
724 cyg_mempool_fix *fix // space to put pool structure in
725 )
726 {
727 CYG_ASSERT_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
728
729 Cyg_Mempool_Fixed *t = new((void *)fix) Cyg_Mempool_Fixed (
730 (cyg_uint8 *)base,
731 size,
732 blocksize
733 );
734 t=t;
735
736 CYG_CHECK_DATA_PTR( handle, "Bad handle pointer" );
737 *handle = (cyg_handle_t)fix;
738 }
739
740 /* Delete fixed size memory pool */
741 externC void cyg_mempool_fix_delete(cyg_handle_t fixpool)
742 {
743 ((Cyg_Mempool_Fixed *)fixpool)->~Cyg_Mempool_Fixed();
744 }
745
746 /* Allocates a block. This waits if the memory is not
747 currently available. */
748 externC void *cyg_mempool_fix_alloc(cyg_handle_t fixpool)
749 {
750 return ((Cyg_Mempool_Fixed *)fixpool)->alloc();
751 }
752
753 #ifdef CYGFUN_KERNEL_THREADS_TIMER
754
755 /* Allocates a block. This waits for up to delay ticks, if the memory
756 is not already available. NULL is returned if no memory is
757 available. */
758 externC void *cyg_mempool_fix_timed_alloc(
759 cyg_handle_t fixpool,
760 cyg_tick_count_t abstime)
761 {
762 return ((Cyg_Mempool_Fixed *)fixpool)->alloc(abstime);
763 }
764
765 #endif
766
767 /* Allocates a block. NULL is returned if no memory is available. */
768 externC void *cyg_mempool_fix_try_alloc(cyg_handle_t fixpool)
769 {
770 return ((Cyg_Mempool_Fixed *)fixpool)->try_alloc();
771 }
772
773 /* Frees memory back into fixed size pool. */
774 externC void cyg_mempool_fix_free(cyg_handle_t fixpool, void *p)
775 {
776 cyg_bool b;
777 b = ((Cyg_Mempool_Fixed *)fixpool)->free((cyg_uint8 *)p);
778 CYG_ASSERT( b, "Bad free");
779 }
780
781 /* Returns true if there are any threads waiting for memory in the
782 given memory pool. */
783 externC cyg_bool_t cyg_mempool_fix_waiting(cyg_handle_t fixpool)
784 {
785 return ((Cyg_Mempool_Fixed *)fixpool)->waiting();
786 }
787
788 /* Puts information about a variable memory pool into the structure
789 provided. */
790 externC void cyg_mempool_fix_get_info(
791 cyg_handle_t fixpool,
792 cyg_mempool_info *info)
793 {
794 Cyg_Mempool_Fixed *f = (Cyg_Mempool_Fixed *)fixpool;
795 cyg_uint8 *base;
796 cyg_addrword_t blocksize;
797
798 info->totalmem = f->get_totalmem();
799 info->freemem = f->get_freemem();
800 f->get_arena(base, info->size, blocksize);
801 info->base = (void *)base;
802 info->maxfree = info->blocksize = (cyg_int32)blocksize;
803 }
804
805 /*---------------------------------------------------------------------------*/
806 /* Semaphores */
807
808 externC void cyg_semaphore_init(
809 cyg_sem_t *sem, /* Semaphore to init */
810 cyg_ucount32 val /* Initial semaphore value */
811 )
812 {
813 CYG_ASSERT_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
814
815 Cyg_Counting_Semaphore *t = new((void *)sem) Cyg_Counting_Semaphore(val);
816 t=t;
817 }
818
819 externC void cyg_semaphore_destroy( cyg_sem_t *sem )
820 {
821 ((Cyg_Counting_Semaphore *)sem)->~Cyg_Counting_Semaphore();
822 }
823
824 externC void cyg_semaphore_wait( cyg_sem_t *sem )
825 {
826 ((Cyg_Counting_Semaphore *)sem)->wait();
827 }
828
829 #ifdef CYGFUN_KERNEL_THREADS_TIMER
830 externC cyg_bool_t cyg_semaphore_timed_wait(
831 cyg_sem_t *sem,
832 cyg_tick_count_t abstime
833 )
834 {
835 return ((Cyg_Counting_Semaphore *)sem)->wait(abstime);
836 }
837 #endif
838
839
840 externC int cyg_semaphore_trywait( cyg_sem_t *sem )
841 {
842 return ((Cyg_Counting_Semaphore *)sem)->trywait();
843 }
844
845 externC void cyg_semaphore_post( cyg_sem_t *sem )
846 {
847 ((Cyg_Counting_Semaphore *)sem)->post();
848 }
849
850 externC void cyg_semaphore_peek( cyg_sem_t *sem, cyg_ucount32 *val )
851 {
852 CYG_CHECK_DATA_PTR( val, "Bad val parameter" );
853
854 *val = ((Cyg_Counting_Semaphore *)sem)->peek();
855 }
856
857
858 /*---------------------------------------------------------------------------*/
859 /* Flags */
860
861 void cyg_flag_init(
862 cyg_flag_t *flag /* Flag to init */
863 )
864 {
865 CYG_ASSERT_SIZES( cyg_flag_t, Cyg_Flag );
866 CYG_ASSERT(
867 ( Cyg_Flag::AND == CYG_FLAG_WAITMODE_AND ) &&
868 ( Cyg_Flag::OR == CYG_FLAG_WAITMODE_OR ) &&
869 ( Cyg_Flag::CLR == CYG_FLAG_WAITMODE_CLR ),
870 "CYG_FLAG_WAITMODE_xxx definition != C++ Cyg_Flag::xxx" );
871
872 Cyg_Flag *t = new((void *)flag) Cyg_Flag();
873 t=t;
874 }
875
876 void cyg_flag_destroy( cyg_flag_t *flag )
877 {
878 ((Cyg_Flag *)flag)->~Cyg_Flag();
879 }
880
881 void cyg_flag_setbits( cyg_flag_t *flag, cyg_flag_value_t value)
882 {
883 ((Cyg_Flag *)flag)->setbits( value );
884 }
885
886 void cyg_flag_maskbits( cyg_flag_t *flag, cyg_flag_value_t value)
887 {
888 ((Cyg_Flag *)flag)->maskbits( value );
889 }
890
891 cyg_flag_value_t cyg_flag_wait( cyg_flag_t *flag,
892 cyg_flag_value_t pattern,
893 cyg_flag_mode_t mode )
894 {
895 if ( 0 == pattern || 0 != (mode & ~3) )
896 return 0;
897 return ((Cyg_Flag *)flag)->wait( pattern, mode );
898
899 }
900
901 #ifdef CYGFUN_KERNEL_THREADS_TIMER
902 cyg_flag_value_t cyg_flag_timed_wait( cyg_flag_t *flag,
903 cyg_flag_value_t pattern,
904 cyg_flag_mode_t mode,
905 cyg_tick_count_t abstime )
906 {
907 if ( 0 == pattern || 0 != (mode & ~3) )
908 return 0;
909 return ((Cyg_Flag *)flag)->wait( pattern, mode, abstime );
910
911 }
912 #endif
913
914 cyg_flag_value_t cyg_flag_poll( cyg_flag_t *flag,
915 cyg_flag_value_t pattern,
916 cyg_flag_mode_t mode )
917 {
918 if ( 0 == pattern || 0 != (mode & ~3) )
919 return 0;
920 return ((Cyg_Flag *)flag)->poll( pattern, mode );
921
922 }
923
924 cyg_flag_value_t cyg_flag_peek( cyg_flag_t *flag )
925 {
926 return ((Cyg_Flag *)flag)->peek();
927 }
928
929 cyg_bool_t cyg_flag_waiting( cyg_flag_t *flag )
930 {
931 return ((Cyg_Flag *)flag)->waiting();
932 }
933
934 /*---------------------------------------------------------------------------*/
935 /* Mutex */
936
937 externC void cyg_mutex_init(
938 cyg_mutex_t *mutex /* Mutex to init */
939 )
940 {
941 CYG_ASSERT_SIZES( cyg_mutex_t, Cyg_Mutex );
942
943 Cyg_Mutex *m = new((void *)mutex) Cyg_Mutex;
944
945 m=m;
946 }
947
948 externC void cyg_mutex_destroy( cyg_mutex_t *mutex )
949 {
950 // no need to do anything here
951 }
952
953 externC void cyg_mutex_lock( cyg_mutex_t *mutex )
954 {
955 ((Cyg_Mutex *)mutex)->lock();
956 }
957
958 externC cyg_bool_t cyg_mutex_trylock( cyg_mutex_t *mutex )
959 {
960 return ((Cyg_Mutex *)mutex)->trylock();
961 }
962
963 externC void cyg_mutex_unlock( cyg_mutex_t *mutex )
964 {
965 ((Cyg_Mutex *)mutex)->unlock();
966 }
967
968 /*---------------------------------------------------------------------------*/
969 /* Condition Variables */
970
971 externC void cyg_cond_init(
972 cyg_cond_t *cond, /* condition variable to init */
973 cyg_mutex_t *mutex /* associated mutex */
974 )
975 {
976 CYG_ASSERT_SIZES( cyg_cond_t, Cyg_Condition_Variable );
977
978 Cyg_Condition_Variable *t = new((void *)cond) Cyg_Condition_Variable(
979 *(Cyg_Mutex *)mutex);
980 t=t;
981 }
982
983 externC void cyg_cond_destroy( cyg_cond_t *cond )
984 {
985 ((Cyg_Counting_Semaphore *)cond)->~Cyg_Counting_Semaphore();
986 }
987
988 externC void cyg_cond_wait( cyg_cond_t *cond )
989 {
990 ((Cyg_Condition_Variable *)cond)->wait();
991 }
992
993 externC void cyg_cond_signal( cyg_cond_t *cond )
994 {
995 ((Cyg_Condition_Variable *)cond)->signal();
996 }
997
998 externC void cyg_cond_broadcast( cyg_cond_t *cond )
999 {
1000 ((Cyg_Condition_Variable *)cond)->broadcast();
1001 }
1002
1003 #ifdef CYGMFN_KERNEL_SYNCH_CONDVAR_TIMED_WAIT
1004 externC cyg_bool_t cyg_cond_timed_wait(
1005 cyg_cond_t *cond,
1006 cyg_tick_count_t abstime
1007 )
1008 {
1009 return ((Cyg_Condition_Variable *)cond)->wait(abstime);
1010 }
1011
1012 #endif
1013
1014 // -------------------------------------------------------------------------
1015 // Check structure sizes.
1016 // This class and constructor get run automatically in debug versions
1017 // of the kernel and check that the structures configured in the C
1018 // code are the same size as the C++ classes they should match.
1019
1020 #ifdef CYGPKG_INFRA_DEBUG
1021
1022 class Cyg_Check_Structure_Sizes
1023 {
1024 int dummy;
1025 public:
1026 Cyg_Check_Structure_Sizes( int x );
1027
1028 };
1029
1030 #define CYG_CHECK_SIZES(cstruct, cxxstruct) \
1031 if( sizeof(cstruct) != sizeof(cxxstruct) ) \
1032 { \
1033 char *fmt = "Size of C struct " #cstruct \
1034 " != size of C++ struct " #cxxstruct ; \
1035 CYG_TRACE2(1, fmt, sizeof(cstruct) , sizeof(cxxstruct) ); \
1036 fail = true; \
1037 fmt = fmt; \
1038 }
1039
1040 Cyg_Check_Structure_Sizes::Cyg_Check_Structure_Sizes(int x)
1041 {
1042 cyg_bool fail = false;
1043
1044 dummy = x+1;
1045
1046 CYG_CHECK_SIZES( cyg_thread, Cyg_Thread );
1047 CYG_CHECK_SIZES( cyg_interrupt, Cyg_Interrupt );
1048 CYG_CHECK_SIZES( cyg_counter, Cyg_Counter );
1049 CYG_CHECK_SIZES( cyg_clock, Cyg_Clock );
1050 CYG_CHECK_SIZES( cyg_alarm, Cyg_Alarm );
1051 CYG_CHECK_SIZES( cyg_mbox, Cyg_Mbox );
1052 CYG_CHECK_SIZES( cyg_mempool_var, Cyg_Mempool_Variable );
1053 CYG_CHECK_SIZES( cyg_mempool_fix, Cyg_Mempool_Fixed );
1054 CYG_CHECK_SIZES( cyg_sem_t, Cyg_Counting_Semaphore );
1055 CYG_CHECK_SIZES( cyg_flag_t, Cyg_Flag );
1056 CYG_CHECK_SIZES( cyg_mutex_t, Cyg_Mutex );
1057 CYG_CHECK_SIZES( cyg_cond_t, Cyg_Condition_Variable );
1058
1059 CYG_ASSERT( !fail, "Size checks failed");
1060 }
1061
1062 Cyg_Check_Structure_Sizes check_structure_sizes(1);
1063
1064 #endif
1065
1066
1067 // -------------------------------------------------------------------------
1068
1069 #endif
1070 // EOF common/kapi.cxx