]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/compat/uitron/v2_0/include/uit_func.inl
Initial revision
[karo-tx-redboot.git] / packages / compat / uitron / v2_0 / include / uit_func.inl
1 #ifndef CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
2 #define CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
3 //===========================================================================
4 //
5 //      uit_func.inl
6 //
7 //      uITRON compatibility functions
8 //
9 //===========================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
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):   hmt
46 // Contributors:        hmt
47 // Date:        1998-03-13
48 // Purpose:     uITRON compatibility functions
49 // Description: 
50 //
51 //####DESCRIPTIONEND####
52 //
53 //===========================================================================
54
55 #ifdef CYGPKG_UITRON
56
57 #ifdef CYGPRI_UITRON_FUNCS_HERE_AND_NOW
58
59 #include <cyg/compat/uitron/uit_objs.hxx> // uITRON setup CYGNUM_UITRON_SEMAS
60
61 // kernel facilities only needed here
62 #include <cyg/kernel/intr.hxx>
63 #include <cyg/kernel/sched.hxx>
64
65 // and the implementations of other kernel facilities
66 #include <cyg/kernel/thread.inl>
67 #include <cyg/kernel/sched.inl>
68 #include <cyg/kernel/clock.inl>
69
70
71 // ------------------------------------------------------------------------
72 // The variable where dis_dsp/ena_dsp state is held:
73 extern cyg_uint32 cyg_uitron_dis_dsp_old_priority;
74
75 // ------------------------------------------------------------------------
76 // Parameter checking; either check the expression and return an error code
77 // if not true, or assert the truth with a made-up message.
78
79 #ifdef CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
80 // default: uitron error codes are returned
81 #define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \
82     if ( ! (_true_) ) return (_error_);                                 \
83 CYG_MACRO_END
84 #else
85 // ...but they are asserted if asserts are on
86 #define CYG_UIT_PARAMCHECK( _true_, _error_ ) CYG_MACRO_START           \
87     CYG_ASSERT( (_true_), "CYG_UIT_PARAMCHECK fail: " #_true_ );        \
88 CYG_MACRO_END
89 #endif // else !CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS
90
91 // ------------------------------------------------------------------------
92 // CYG_UITRON_CHECK_AND_GETP
93 // 
94 // Macro to rangecheck and do the addressing of a static uitron system
95 // object; _which_ sort of object is given, and token pasting is used
96 // horribly to get the static array, limits and the like.
97 //
98 // Usage:
99 //   INT snd_msg( ID mbxid, ... ) {
100 //      Cyg_Mbox *p;
101 //      CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
102 //      p->...(...);
103
104 // internal: plain assignment to the object pointer, from static array
105 #define CYG_UIT_SPTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START           \
106         (_ptr_) =  CYG_UITRON_OBJS( _which_ ) + ((_idx_) - 1);          \
107 CYG_MACRO_END
108
109 // internal: plain assignment to the object pointer, from pointer array
110 // with error checking.
111 #define CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ ) CYG_MACRO_START       \
112         (_ptr_) =  CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ];         \
113         if ( NULL == (_ptr_) ) return E_NOEXS;                          \
114 CYG_MACRO_END
115
116 #define CYG_UITRON_CHECK_AND_GETP_DIRECT( _which_, _idx_, _ptr_ )       \
117 CYG_MACRO_START                                                         \
118     CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
119     CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
120     CYG_UIT_SPTR( _which_, _idx_, _ptr_ );                              \
121 CYG_MACRO_END
122
123 #define CYG_UITRON_CHECK_AND_GETP_INDIRECT( _which_, _idx_, _ptr_ )     \
124 CYG_MACRO_START                                                         \
125     CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
126     CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
127     CYG_UIT_SPTR_PTR( _which_, _idx_, _ptr_ );                          \
128 CYG_MACRO_END
129
130 // As above but for handler numbers which return E_PAR when out of range
131 #define CYG_UITRON_CHECK_AND_GETHDLR( _which_, _num_, _ptr_ )           \
132 CYG_MACRO_START                                                         \
133     CYG_UIT_PARAMCHECK( 0 < (_num_), E_PAR );                           \
134     CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_num_), E_PAR );  \
135     CYG_UIT_SPTR( _which_, _num_, _ptr_ );                              \
136 CYG_MACRO_END
137
138 // And a macro to check that creation of an object is OK
139 #define CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( _which_, _idx_ )            \
140 CYG_MACRO_START                                                         \
141     CYG_UIT_PARAMCHECK( 0 < (_idx_), E_ID );                            \
142     CYG_UIT_PARAMCHECK( CYG_UITRON_NUM( _which_ ) >= (_idx_), E_ID );   \
143     Cyg_Scheduler::lock();                                              \
144     if ( NULL != CYG_UITRON_PTRS( _which_ )[ ((_idx_) - 1) ] ) {        \
145         Cyg_Scheduler::unlock();                                        \
146         return E_OBJ;                                                   \
147     }                                                                   \
148 CYG_MACRO_END
149
150 // define a magic new operator in order to call constructors
151 #define CYG_UITRON_NEWFUNCTION( _class_ )                               \
152 inline void *operator new(size_t size, _class_ *ptr)                    \
153 {                                                                       \
154     CYG_CHECK_DATA_PTR( ptr, "Bad pointer" );                           \
155     return ptr;                                                         \
156 }
157
158 // now configury to support selectable create/delete support ie. an
159 // array of pointers to the objects themselves.
160 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
161 #define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \
162     CYG_UITRON_CHECK_AND_GETP_INDIRECT( TASKS, _idx_, _ptr_ )
163 #else
164 #define CYG_UITRON_CHECK_AND_GETP_TASKS( _idx_, _ptr_ )                 \
165     CYG_UITRON_CHECK_AND_GETP_DIRECT( TASKS, _idx_, _ptr_ )
166 #endif
167
168 #ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
169 #define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \
170     CYG_UITRON_CHECK_AND_GETP_INDIRECT( SEMAS, _idx_, _ptr_ )
171 #else
172 #define CYG_UITRON_CHECK_AND_GETP_SEMAS( _idx_, _ptr_ )                 \
173     CYG_UITRON_CHECK_AND_GETP_DIRECT( SEMAS, _idx_, _ptr_ )
174 #endif
175
176 #ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
177 #define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \
178     CYG_UITRON_CHECK_AND_GETP_INDIRECT( MBOXES, _idx_, _ptr_ )
179 #else
180 #define CYG_UITRON_CHECK_AND_GETP_MBOXES( _idx_, _ptr_ )                \
181     CYG_UITRON_CHECK_AND_GETP_DIRECT( MBOXES, _idx_, _ptr_ )
182 #endif
183
184 #ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
185 #define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \
186     CYG_UITRON_CHECK_AND_GETP_INDIRECT( FLAGS, _idx_, _ptr_ )
187 #else
188 #define CYG_UITRON_CHECK_AND_GETP_FLAGS( _idx_, _ptr_ )                 \
189     CYG_UITRON_CHECK_AND_GETP_DIRECT( FLAGS, _idx_, _ptr_ )
190 #endif
191
192 #ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
193 #define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \
194     CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
195 #else
196 #define CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( _idx_, _ptr_ )          \
197     CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLFIXED, _idx_, _ptr_ )
198 #endif
199
200 #ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
201 #define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \
202     CYG_UITRON_CHECK_AND_GETP_INDIRECT( MEMPOOLVAR, _idx_, _ptr_ )
203 #else
204 #define CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( _idx_, _ptr_ )            \
205     CYG_UITRON_CHECK_AND_GETP_DIRECT( MEMPOOLVAR, _idx_, _ptr_ )
206 #endif
207
208 // ------------------------------------------------------------------------
209 // Common error checking macros
210
211 #if !defined( CYGSEM_UITRON_BAD_PARAMS_RETURN_ERRORS ) && \
212     !defined( CYGDBG_USE_ASSERTS )
213 // if not checking and not asserted, these are removed to avoid usused
214 // variable warnings.
215 #define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ )     CYG_EMPTY_STATEMENT
216 #define CYG_UITRON_CHECK_TASK_CONTEXT()                  CYG_EMPTY_STATEMENT
217 #define CYG_UITRON_CHECK_DISPATCH_ENABLED()              CYG_EMPTY_STATEMENT
218 #define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( _tmout_ ) CYG_EMPTY_STATEMENT
219
220 #else
221 // the default:
222 // Check a task is actually a uITRON task
223 #define CYG_UITRON_CHECK_TASK_CONTEXT_SELF( _self_ ) CYG_MACRO_START    \
224     CYG_UIT_PARAMCHECK(                                                 \
225         (&cyg_uitron_TASKS[0] <= (_self_)) &&                           \
226         ((_self_) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]),            \
227                                   E_CTX );                              \
228 CYG_MACRO_END
229
230 #define CYG_UITRON_CHECK_TASK_CONTEXT() CYG_MACRO_START                 \
231     Cyg_Thread *self = Cyg_Thread::self();                              \
232     CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );                         \
233 CYG_MACRO_END
234
235 // Check dispatching is enabled for calls which might wait
236 #define CYG_UITRON_CHECK_DISPATCH_ENABLED()  CYG_MACRO_START            \
237     CYG_UIT_PARAMCHECK( 0 == cyg_uitron_dis_dsp_old_priority, E_CTX );  \
238 CYG_MACRO_END
239
240 #define CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO(_tmout_)  CYG_MACRO_START \
241     CYG_UIT_PARAMCHECK( -1 <= (_tmout_), E_PAR );                       \
242     if ( TMO_POL != (_tmout_) )                                         \
243         CYG_UITRON_CHECK_DISPATCH_ENABLED();                            \
244 CYG_MACRO_END
245
246 #endif
247
248 #ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
249 #define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \
250         CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \
251 CYG_MACRO_END
252 #else // do check for NULL
253 #define CYG_UIT_PARAMCHECK_PTR( _p_ )   CYG_MACRO_START                 \
254         CYG_UIT_PARAMCHECK( NADR != (_p_), E_PAR );                     \
255         CYG_UIT_PARAMCHECK( NULL != (_p_), E_PAR );                     \
256 CYG_MACRO_END
257 #endif // !CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
258
259 // ------------------------------------------------------------------------
260 // CYG_UITRON_FAIL_RETURN
261 //
262 // After a call which waits, it might return with success, or due to a
263 // timeout or a release wait (a forced escape from the waiting condition).
264 // This macro examines context and finds out which, then executes a return
265 // with the correct uITRON condition code.
266
267 #define CYG_UITRON_FAIL_RETURN_SELF( _self_ ) CYG_MACRO_START           \
268     Cyg_Thread::cyg_reason reason = (_self_)->get_wake_reason();        \
269     if ( Cyg_Thread::TIMEOUT  == reason )                               \
270         return E_TMOUT;                                                 \
271     if ( Cyg_Thread::BREAK    == reason )                               \
272         return E_RLWAI;                                                 \
273     if ( Cyg_Thread::DESTRUCT == reason )                               \
274         return E_DLT;                                                   \
275     return E_SYS; /* if no plausible reason was found */                \
276 CYG_MACRO_END
277
278 #define CYG_UITRON_FAIL_RETURN() CYG_MACRO_START                        \
279     Cyg_Thread *self = Cyg_Thread::self();                              \
280     CYG_UITRON_FAIL_RETURN_SELF( self );                                \
281 CYG_MACRO_END
282
283 // ------------------------------------------------------------------------
284 // Interrupts disabled?
285 #define CYG_UITRON_CHECK_CPU_UNLOC()                                    \
286     CYG_UIT_PARAMCHECK( (Cyg_Interrupt::interrupts_enabled()), E_CTX )
287
288 // ------------------------------------------------------------------------
289 // Timing: is it in eCos clock ticks or milliSeconds (or something else?)
290
291 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
292
293 #ifdef CYGSEM_UITRON_TIME_IS_MILLISECONDS
294 extern Cyg_Clock::converter uit_clock_to_system;
295 extern Cyg_Clock::converter uit_clock_from_system;
296
297 #define CYG_UITRON_TIME_UIT_TO_SYS32( t ) \
298 Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_to_system )
299
300 #define CYG_UITRON_TIME_SYS_TO_UIT32( t ) \
301 Cyg_Clock::convert( (cyg_uint64)(t), &uit_clock_from_system )
302
303 // long (cyg_uint64) versions:
304 #define CYG_UITRON_TIME_UIT_TO_SYS64( t ) \
305 Cyg_Clock::convert( (t), &uit_clock_to_system )
306
307 #define CYG_UITRON_TIME_SYS_TO_UIT64( t ) \
308 Cyg_Clock::convert( (t), &uit_clock_from_system )
309
310 #else // Time is whatever the system clock is doing:
311
312 // Straight through - int (cyg_int32) argument versions:
313 #define CYG_UITRON_TIME_UIT_TO_SYS32( t )  ( t )
314 #define CYG_UITRON_TIME_SYS_TO_UIT32( t )  ( t )
315 // long (cyg_uint64) versions:
316 #define CYG_UITRON_TIME_UIT_TO_SYS64( t )  ( t )
317 #define CYG_UITRON_TIME_SYS_TO_UIT64( t )  ( t )
318 #endif
319
320 #endif // CYGVAR_KERNEL_COUNTERS_CLOCK - otherwise these should not be used.
321
322 // ------------------------------------------------------------------------
323 // the function definitions themselves:
324
325 // ******************************************************
326 // ***    6.5 C Language Interfaces                   ***
327 // ******************************************************
328
329 // - Task Management Functions
330
331 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
332 CYG_UITRON_NEWFUNCTION( Cyg_Thread )
333
334 CYG_UIT_FUNC_INLINE
335 ER
336 cre_tsk ( ID tskid, T_CTSK *pk_ctsk )
337 {
338     ER ret = E_OK;
339     CYG_UIT_PARAMCHECK_PTR( pk_ctsk );
340     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( TASKS, tskid );
341
342     Cyg_Thread *p = &(CYG_UITRON_OBJS( TASKS )[ tskid - 1 ]);
343     cyg_uint32 state = p->get_state();
344     if ( 0 == (state & Cyg_Thread::EXITED) )
345         ret = E_OBJ; // how did it get to be running?
346     else if ( ((INT)p->get_stack_size()) < pk_ctsk->stksz )
347         ret = E_NOMEM; // more stack requested than available
348     else {
349         CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] =
350             new( p ) Cyg_Thread(
351                 (CYG_ADDRWORD)      pk_ctsk->itskpri,
352                 (cyg_thread_entry *)pk_ctsk->task,
353                 (CYG_ADDRWORD)      0,
354                 // preserve the original name and stack:
355 #ifdef CYGVAR_KERNEL_THREADS_NAME
356                 p->get_name(),
357 #else
358                 NULL,
359 #endif
360                 p->get_stack_base(),
361                 p->get_stack_size() );
362         // but ensure the task state is dormant:
363         // (it is not constructed dormant, but suspended)
364         p->kill();
365 #ifdef CYGIMP_THREAD_PRIORITY
366         // and record the initial priority outside the task too.
367         CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) = pk_ctsk->itskpri;
368 #endif
369     }
370     Cyg_Scheduler::unlock();
371     return ret;
372 }
373
374 CYG_UIT_FUNC_INLINE
375 ER
376 del_tsk ( ID tskid )
377 {
378     Cyg_Thread *p;
379     ER ret = E_OK;
380     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
381     
382     Cyg_Scheduler::lock();
383     // deal with the race condition here
384     if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] ) {
385         Cyg_Scheduler::unlock();
386         return E_NOEXS;
387     }
388     cyg_uint32 state = p->get_state();
389     if ( state & Cyg_Thread::EXITED )
390         // just disconnect the pointer from its object
391         CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
392     else
393         ret = E_OBJ;
394     Cyg_Scheduler::unlock();
395     return ret;
396 }
397 #endif // CYGPKG_UITRON_TASKS_CREATE_DELETE
398
399 CYG_UIT_FUNC_INLINE
400 ER
401 sta_tsk ( ID tskid, INT stacd )
402 {
403     Cyg_Thread *p;
404     ER ret = E_OK;
405     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
406     
407     Cyg_Scheduler::lock();
408     cyg_uint32 state = p->get_state();
409 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
410     // there is a race condition with deleting the task
411     // so test it now that we have the scheduler locked
412     if ( p != CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] )
413         ret = E_NOEXS;
414     else // NOTE dangling else to the next line:
415 #endif
416     if ( state & Cyg_Thread::EXITED ) {
417         p->reinitialize();
418 #ifdef CYGIMP_THREAD_PRIORITY
419         p->set_priority( CYG_UITRON_TASK_INITIAL_PRIORITY( tskid ) );
420 #endif
421         p->set_entry_data( (CYG_ADDRWORD)stacd );
422         p->force_resume();
423     }
424     else
425         ret = E_OBJ;
426     Cyg_Scheduler::unlock();
427     return ret;
428 }
429
430 CYG_UIT_FUNC_INLINE
431 void
432 ext_tsk ( void )
433 {    
434     Cyg_Thread::exit();
435 }
436
437 CYG_UIT_FUNC_INLINE
438 void
439 exd_tsk ( void )
440 {
441 #ifdef CYGPKG_UITRON_TASKS_CREATE_DELETE
442     Cyg_Thread *p;
443
444     Cyg_Scheduler::lock();
445     p = Cyg_Thread::self();
446     ID tskid = (p - (&cyg_uitron_TASKS[0])) + 1;    
447     // just disconnect the pointer from its object
448     CYG_UITRON_PTRS( TASKS )[ tskid - 1 ] = NULL;
449     // Any associated storage management, and possibly calling the task
450     // destructor, is for future versions.
451 #else
452     // do nothing - deletion not supported so just exit...
453 #endif
454     Cyg_Thread::exit();
455     // does not return, does unlock the scheduler for us
456 }
457
458 CYG_UIT_FUNC_INLINE
459 ER
460 ter_tsk ( ID tskid )
461 {
462     Cyg_Thread *p;
463     ER ret = E_OK;
464     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
465     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
466     Cyg_Scheduler::lock();
467     if ( (0 != (Cyg_Thread::EXITED & p->get_state())) ||
468          (Cyg_Thread::EXIT == p->get_wake_reason()) )
469         // already dormant
470         ret = E_OBJ;
471     else {
472         p->force_resume(); // let it run
473         p->kill(); // and set prio high so it runs RIGHT NOW!!
474 #ifdef CYGIMP_THREAD_PRIORITY
475 #if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES != 0
476         // see if we are already at prio 0:
477         if ( 0 == cyg_uitron_dis_dsp_old_priority )
478             // then dispatch is enabled, we are not at prio 0
479 #endif
480             p->set_priority( (cyg_priority) 0 );
481         // if we do not do this, then we are not running a strictly
482         // uITRON compatible scheduler - so just hope for the best.
483 #endif
484     }
485     Cyg_Scheduler::unlock();
486 #ifdef CYGIMP_THREAD_PRIORITY
487 #if CYGINT_KERNEL_SCHEDULER_UNIQUE_PRIORITIES == 0
488     if ( (E_OK == ret) && (0 != cyg_uitron_dis_dsp_old_priority) ) {
489         // then dispatching is disabled, so our prio is 0 too
490         Cyg_Thread::yield(); // so let the dying thread run;
491         Cyg_Thread::yield(); // no cost here of making sure.
492     }
493 #endif
494 #endif
495     return ret;
496 }
497
498 CYG_UIT_FUNC_INLINE
499 ER
500 dis_dsp ( void )
501 {
502     CYG_UITRON_CHECK_TASK_CONTEXT();
503     CYG_UITRON_CHECK_CPU_UNLOC();
504     Cyg_Scheduler::lock();
505     // Prevent preemption by going up to prio 0
506     if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
507 #ifdef CYGIMP_THREAD_PRIORITY
508         Cyg_Thread *p = Cyg_Thread::self();
509         cyg_uitron_dis_dsp_old_priority = p->get_priority();
510         p->set_priority( 0 );
511 #else
512         cyg_uitron_dis_dsp_old_priority = 1;
513 #endif
514     }
515     Cyg_Scheduler::unlock();
516     return E_OK;
517 }
518
519 CYG_UIT_FUNC_INLINE
520 ER
521 ena_dsp ( void )
522 {
523     CYG_UITRON_CHECK_TASK_CONTEXT();
524     CYG_UITRON_CHECK_CPU_UNLOC();
525     Cyg_Scheduler::lock();
526     // Enable dispatching (if disabled) and maybe switch threads
527     if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
528         // We had prevented preemption by going up to prio 0
529 #ifdef CYGIMP_THREAD_PRIORITY
530         Cyg_Thread *p = Cyg_Thread::self();
531         p->set_priority( cyg_uitron_dis_dsp_old_priority );
532         p->to_queue_head(); // to ensure we continue to run
533                             // if nobody higher pri
534 #endif
535         cyg_uitron_dis_dsp_old_priority = 0;
536     }
537     Cyg_Scheduler::unlock();
538     CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
539     return E_OK;
540 }
541
542
543 CYG_UIT_FUNC_INLINE
544 ER
545 chg_pri ( ID tskid, PRI tskpri )
546 {
547     Cyg_Thread *p;
548     ER ret = E_OK;
549     if ( 0 == tskid ) {
550         p = Cyg_Thread::self();
551         CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
552     }
553     else
554         CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
555
556 #ifdef CYGIMP_THREAD_PRIORITY
557     if ( 0 == tskpri )
558         // then use the initial priority [Level X]
559         tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
560 #endif
561     CYG_UIT_PARAMCHECK( 0 < tskpri, E_PAR );
562 #ifdef CYGIMP_THREAD_PRIORITY
563 #if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
564     CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
565                         tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
566 #else    
567     CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
568                         tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
569 #endif
570     // Handle changing our own prio specially, if dispatch disabled:
571     if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
572         // our actual prio is 0 now and must remain so:
573         if ( Cyg_Thread::self() == p ) {  // by whichever route p was set
574             // set the priority we will return to when dispatch is enabled:
575             cyg_uitron_dis_dsp_old_priority = (cyg_uint32)tskpri;
576             return E_OK;
577         }
578     }
579     Cyg_Scheduler::lock();
580     if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
581          (Cyg_Thread::EXIT == p->get_wake_reason()) )
582         ret = E_OBJ; // task is dormant
583     else
584         p->set_priority( (cyg_priority)tskpri );
585     Cyg_Scheduler::unlock();
586 #endif // CYGIMP_THREAD_PRIORITY got priorities at all?
587     return ret;
588 }
589
590 CYG_UIT_FUNC_INLINE
591 ER
592 rot_rdq ( PRI tskpri )
593 {
594     // zero means our level; easiet way is to yield() the CPU.
595     if ( 0 == tskpri ) {
596         Cyg_Thread::yield();
597         return E_OK;
598     }
599 #ifdef CYGIMP_THREAD_PRIORITY
600 #if CYG_THREAD_MAX_PRIORITY < CYG_THREAD_MIN_PRIORITY
601     CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY <= tskpri &&
602                         tskpri <= CYG_THREAD_MIN_PRIORITY, E_PAR );
603 #else    
604     CYG_UIT_PARAMCHECK( CYG_THREAD_MAX_PRIORITY >= tskpri &&
605                         tskpri >= CYG_THREAD_MIN_PRIORITY, E_PAR );
606 #endif
607     Cyg_Thread::rotate_queue( tskpri );
608 #endif // CYGIMP_THREAD_PRIORITY got priorities at all?
609     return E_OK;
610 }
611
612 CYG_UIT_FUNC_INLINE
613 ER
614 rel_wai ( ID tskid )
615 {
616     Cyg_Thread *p;
617     ER ret = E_OK;
618     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
619     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
620     Cyg_Scheduler::lock();              // get an atomic view of the task
621     if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
622          (Cyg_Thread::EXIT == p->get_wake_reason()) )
623         ret = E_OBJ;                    // task is dormant
624     else {
625         p->release();
626         // return E_OBJ if the thread was not sleeping
627         if ( Cyg_Thread::BREAK != p->get_wake_reason() )
628             ret = E_OBJ;
629     }
630     Cyg_Scheduler::unlock();
631     return ret;
632 }
633
634 CYG_UIT_FUNC_INLINE
635 ER
636 get_tid ( ID *p_tskid )
637 {
638     Cyg_Thread *self = Cyg_Thread::self();
639     CYG_UIT_PARAMCHECK_PTR( p_tskid );
640     if ( (&cyg_uitron_TASKS[0] <= (self)) &&
641         ((self) < &cyg_uitron_TASKS[CYGNUM_UITRON_TASKS]) &&
642         (0 == Cyg_Scheduler::get_sched_lock()) )
643         // then I am a uITRON task and not in an interrupt or DSR
644         *p_tskid = (self - (&cyg_uitron_TASKS[0])) + 1;
645     else
646         *p_tskid = 0; // Otherwise, non-task portion
647     return E_OK;
648 }
649
650 CYG_UIT_FUNC_INLINE
651 ER
652 ref_tsk ( T_RTSK *pk_rtsk, ID tskid )
653 {
654     Cyg_Thread *p;
655     if ( 0 == tskid ) {
656         p = Cyg_Thread::self();
657         CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
658         tskid = (p - (&cyg_uitron_TASKS[0])) + 1; // it gets used below
659     }
660     else
661         CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
662
663     CYG_UIT_PARAMCHECK_PTR( pk_rtsk );
664     pk_rtsk->exinf  = NADR;
665     Cyg_Scheduler::lock();              // get an atomic view of the task
666     cyg_uint32 state = p->get_state();
667     if ( (state & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
668          (Cyg_Thread::EXIT == p->get_wake_reason()) )
669         pk_rtsk->tskstat = TTS_DMT;
670     else if ( state == Cyg_Thread::RUNNING )
671         // If it's us, it's running, else it's ready
672         pk_rtsk->tskstat = (Cyg_Thread::self() == p)
673             ? TTS_RUN                   // RUN state (we are it)
674             : TTS_RDY;                  // READY state
675     else if ( state & Cyg_Thread::SUSPENDED )
676         pk_rtsk->tskstat =
677             (state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
678             ? TTS_WAS                   // WAIT-SUSPEND state
679             : TTS_SUS;                  // SUSPEND state
680     else
681         pk_rtsk->tskstat =
682             (state & (Cyg_Thread::COUNTSLEEP | Cyg_Thread::SLEEPING))
683             ? TTS_WAI                   // WAIT state
684             : 0;                        // Not sure what's happening here!
685 #ifdef CYGIMP_THREAD_PRIORITY
686     if ( TTS_DMT == pk_rtsk->tskstat )
687         pk_rtsk->tskpri = CYG_UITRON_TASK_INITIAL_PRIORITY( tskid );
688     else if ( (TTS_RUN == pk_rtsk->tskstat) && 
689               (0 != cyg_uitron_dis_dsp_old_priority) )
690         // then we are it and dispatching is disabled, so
691         // report our "real" priority - it is 0 in the kernel at the moment
692         pk_rtsk->tskpri = cyg_uitron_dis_dsp_old_priority;
693     else
694         pk_rtsk->tskpri = p->get_priority();
695 #else
696     pk_rtsk->tskpri = -1;  // Not applicable
697 #endif
698     Cyg_Scheduler::unlock();
699     return E_OK;
700 }
701         
702 // - Task-Dependent Synchronization Functions
703         
704 CYG_UIT_FUNC_INLINE
705 ER
706 sus_tsk ( ID tskid )
707 {
708     Cyg_Thread *p;
709     ER ret = E_OK;
710     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
711     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
712     Cyg_Scheduler::lock();              // get an atomic view of the task
713     if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
714          (Cyg_Thread::EXIT == p->get_wake_reason()) )
715         ret = E_OBJ;                    // task is dormant
716     else
717         p->suspend();
718     Cyg_Scheduler::unlock();
719     return ret;
720 }
721
722 CYG_UIT_FUNC_INLINE
723 ER
724 rsm_tsk ( ID tskid )
725 {
726     Cyg_Thread *p;
727     ER ret = E_OK;
728     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
729     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
730     Cyg_Scheduler::lock();              // get an atomic view of the task
731     cyg_uint32 state = p->get_state();
732     if ( 0 == (Cyg_Thread::SUSPENDED & state) )
733         ret = E_OBJ;                    // thread is not suspended
734     else
735         p->resume();
736     Cyg_Scheduler::unlock();
737     return ret;
738 }
739
740 CYG_UIT_FUNC_INLINE
741 ER
742 frsm_tsk ( ID tskid )
743 {
744     Cyg_Thread *p;
745     ER ret = E_OK;
746     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
747     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
748     Cyg_Scheduler::lock();              // get an atomic view of the task
749     cyg_uint32 state = p->get_state();
750     if ( 0 == (Cyg_Thread::SUSPENDED & state) )
751         ret = E_OBJ;                    // thread is not suspended
752     else
753         p->force_resume();
754     Cyg_Scheduler::unlock();
755     return ret;
756 }
757
758 CYG_UIT_FUNC_INLINE
759 ER
760 slp_tsk ( void )
761 {
762     Cyg_Thread *self = Cyg_Thread::self();
763     CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
764     CYG_UITRON_CHECK_DISPATCH_ENABLED();
765     // do this now for the case when no sleeping actually occurs
766     self->set_wake_reason( Cyg_Thread::DONE );
767     Cyg_Thread::counted_sleep();
768     if ( Cyg_Thread::DONE != self->get_wake_reason() )
769         CYG_UITRON_FAIL_RETURN_SELF( self );
770     return E_OK;
771 }
772
773 #ifdef CYGFUN_KERNEL_THREADS_TIMER
774 CYG_UIT_FUNC_INLINE
775 ER
776 tslp_tsk ( TMO tmout )
777 {
778     Cyg_Thread *self = Cyg_Thread::self();
779     CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
780     CYG_UIT_PARAMCHECK( -1 <= tmout, E_PAR );
781     CYG_UITRON_CHECK_DISPATCH_ENABLED();
782     // do this now for the case when no sleeping actually occurs
783     self->set_wake_reason( Cyg_Thread::DONE );
784     // note that TMO_POL is not treated specially, though it
785     // happens to work almost as a poll (some sleeping may occur)
786     if ( TMO_FEVR == tmout )
787         Cyg_Thread::counted_sleep();
788     else
789         Cyg_Thread::counted_sleep(
790             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
791     if ( Cyg_Thread::DONE != self->get_wake_reason() )
792         CYG_UITRON_FAIL_RETURN_SELF( self );
793     return E_OK;
794 }
795 #endif // CYGFUN_KERNEL_THREADS_TIMER
796
797 CYG_UIT_FUNC_INLINE
798 ER
799 wup_tsk ( ID tskid )
800 {
801     Cyg_Thread *p;
802     ER ret = E_OK;
803     CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
804     CYG_UIT_PARAMCHECK( Cyg_Thread::self() != p, E_OBJ );
805     Cyg_Scheduler::lock();              // get an atomic view of the task
806     if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
807          (Cyg_Thread::EXIT == p->get_wake_reason()) )
808         ret = E_OBJ;                    // task is dormant
809     else
810         p->counted_wake();
811     Cyg_Scheduler::unlock();
812     return ret;
813 }
814
815 CYG_UIT_FUNC_INLINE
816 ER
817 can_wup ( INT *p_wupcnt, ID tskid )
818 {
819     Cyg_Thread *p;
820     ER ret = E_OK;
821     if ( 0 == tskid ) {
822         p = Cyg_Thread::self();
823         CYG_UITRON_CHECK_TASK_CONTEXT_SELF( p );
824     }
825     else
826         CYG_UITRON_CHECK_AND_GETP_TASKS( tskid, p );
827     CYG_UIT_PARAMCHECK_PTR( p_wupcnt );
828     Cyg_Scheduler::lock();              // get an atomic view of the task
829     if ( (p->get_state() & (Cyg_Thread::EXITED | Cyg_Thread::CREATING)) ||
830          (Cyg_Thread::EXIT == p->get_wake_reason()) )
831         ret = E_OBJ;                    // task is dormant
832     else {
833         cyg_uint32 result = p->cancel_counted_wake();
834         *p_wupcnt = result;
835     }
836     Cyg_Scheduler::unlock();
837     return ret;
838 }
839         
840 // - Synchronization and Communication Functions
841         
842 #ifdef CYGPKG_UITRON_SEMAS
843 #if 0 < CYG_UITRON_NUM( SEMAS )
844
845 #ifdef CYGPKG_UITRON_SEMAS_CREATE_DELETE
846
847 CYG_UITRON_NEWFUNCTION( Cyg_Counting_Semaphore2 )
848
849 CYG_UIT_FUNC_INLINE
850 ER
851 cre_sem ( ID semid, T_CSEM *pk_csem )
852 {
853     ER ret = E_OK;
854     CYG_UIT_PARAMCHECK_PTR( pk_csem );
855     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( SEMAS, semid );
856     if ( TA_TFIFO != pk_csem->sematr )
857         ret = E_RSATR;
858     else
859         CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] =
860             new( &(CYG_UITRON_OBJS( SEMAS )[ semid - 1 ]) )
861             Cyg_Counting_Semaphore2( (cyg_count32)pk_csem->isemcnt );
862     Cyg_Scheduler::unlock();
863     return ret;
864 }
865
866 CYG_UIT_FUNC_INLINE
867 ER
868 del_sem ( ID semid )
869 {
870     Cyg_Counting_Semaphore2 *p;
871     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
872     Cyg_Scheduler::lock();
873     // deal with the race condition here
874     if ( p != CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] ) {
875         Cyg_Scheduler::unlock();
876         return E_NOEXS;
877     }
878     CYG_UITRON_PTRS( SEMAS )[ semid - 1 ] = NULL;
879     p->~Cyg_Counting_Semaphore2();
880     Cyg_Scheduler::unlock();
881     return E_OK;
882 }
883 #endif // CYGPKG_UITRON_SEMAS_CREATE_DELETE
884
885 CYG_UIT_FUNC_INLINE
886 ER
887 sig_sem( ID semid )
888 {
889     Cyg_Counting_Semaphore2 *p;
890     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
891     p->post();
892     return E_OK;
893 }
894
895 CYG_UIT_FUNC_INLINE
896 ER
897 wai_sem( ID semid )
898 {
899     Cyg_Counting_Semaphore2 *p;
900     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
901     CYG_UITRON_CHECK_DISPATCH_ENABLED();
902     cyg_bool result = p->wait();
903     if ( !result )
904         CYG_UITRON_FAIL_RETURN();
905     return E_OK;
906 }
907
908 CYG_UIT_FUNC_INLINE
909 ER
910 preq_sem ( ID semid )
911 {
912     Cyg_Counting_Semaphore2 *p;
913     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
914     cyg_bool result = p->trywait();
915     if ( !result )
916         return E_TMOUT;
917     return E_OK;
918 }
919
920 #ifdef CYGFUN_KERNEL_THREADS_TIMER
921 CYG_UIT_FUNC_INLINE
922 ER
923 twai_sem ( ID semid, TMO tmout )
924 {
925     Cyg_Counting_Semaphore2 *p;
926     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
927     CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
928     // do this now for the case when no sleeping actually occurs
929     Cyg_Thread *self = Cyg_Thread::self();
930     self->set_wake_reason( Cyg_Thread::TIMEOUT );
931     cyg_bool result;
932     if ( TMO_FEVR == tmout )
933         result = p->wait();
934     else if ( TMO_POL == tmout )
935         result = p->trywait();
936     else
937         result = p->wait(
938             Cyg_Clock::real_time_clock->current_value() +
939             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
940     if ( ! result )
941         CYG_UITRON_FAIL_RETURN_SELF( self );
942     return E_OK;
943
944 }
945 #endif // CYGFUN_KERNEL_THREADS_TIMER
946
947 CYG_UIT_FUNC_INLINE
948 ER
949 ref_sem ( T_RSEM *pk_rsem, ID semid )
950 {
951     Cyg_Counting_Semaphore2 *p;
952     CYG_UITRON_CHECK_AND_GETP_SEMAS( semid, p );
953     CYG_UIT_PARAMCHECK_PTR( pk_rsem );
954     pk_rsem->exinf  = NADR;
955     pk_rsem->wtsk   = p->waiting();
956     pk_rsem->semcnt = p->peek();
957     return E_OK;
958 }
959
960 #endif // 0 < CYG_UITRON_NUM( SEMAS )
961 #endif // CYGPKG_UITRON_SEMAS
962
963 #ifdef CYGPKG_UITRON_FLAGS
964 #if 0 < CYG_UITRON_NUM( FLAGS )
965
966 #ifdef CYGPKG_UITRON_FLAGS_CREATE_DELETE
967
968 CYG_UITRON_NEWFUNCTION( Cyg_Flag )
969
970 CYG_UIT_FUNC_INLINE
971 ER
972 cre_flg ( ID flgid, T_CFLG *pk_cflg )
973 {
974     ER ret = E_OK;
975     CYG_UIT_PARAMCHECK_PTR( pk_cflg );
976     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( FLAGS, flgid );
977     if ( 0 != ((~(TA_WMUL | TA_WSGL)) & pk_cflg->flgatr) )
978         ret = E_RSATR;
979     else
980         CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] =
981             new( &(CYG_UITRON_OBJS( FLAGS )[ flgid - 1 ]) )
982             Cyg_Flag( (Cyg_FlagValue) pk_cflg->iflgptn );
983     Cyg_Scheduler::unlock();
984     return ret;
985 }
986
987 CYG_UIT_FUNC_INLINE
988 ER
989 del_flg ( ID flgid )
990 {
991     Cyg_Flag *p;
992     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
993     Cyg_Scheduler::lock();
994     // deal with the race condition here
995     if ( p != CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] ) {
996         Cyg_Scheduler::unlock();
997         return E_NOEXS;
998     }
999     CYG_UITRON_PTRS( FLAGS )[ flgid - 1 ] = NULL;
1000     p->~Cyg_Flag();
1001     Cyg_Scheduler::unlock();
1002     return E_OK;
1003 }
1004 #endif // CYGPKG_UITRON_FLAGS_CREATE_DELETE
1005
1006 CYG_UIT_FUNC_INLINE
1007 ER
1008 set_flg ( ID flgid, UINT setptn )
1009 {
1010     Cyg_Flag *p;
1011     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1012     p->setbits( setptn );
1013     return E_OK;
1014 }
1015
1016 CYG_UIT_FUNC_INLINE
1017 ER
1018 clr_flg ( ID flgid, UINT clrptn )
1019 {
1020     Cyg_Flag *p;
1021     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1022     p->maskbits( clrptn );
1023     return E_OK;
1024 }
1025
1026 CYG_UIT_FUNC_INLINE
1027 ER
1028 wai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
1029 {
1030     Cyg_Flag *p;
1031     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1032     CYG_UIT_PARAMCHECK_PTR( p_flgptn );
1033     CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
1034     CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
1035     CYG_UITRON_CHECK_DISPATCH_ENABLED();
1036     // check we can use the wfmode value unchanged
1037     CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
1038     CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
1039     CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
1040
1041     UINT result = p->wait( waiptn, wfmode );
1042     if ( ! result )
1043         CYG_UITRON_FAIL_RETURN();
1044     *p_flgptn  = result;
1045     return E_OK;
1046 }
1047
1048 CYG_UIT_FUNC_INLINE
1049 ER
1050 pol_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode )
1051 {
1052     Cyg_Flag *p;
1053     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1054     CYG_UIT_PARAMCHECK_PTR( p_flgptn );
1055     CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
1056     CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
1057     // check we can use the wfmode value unchanged
1058     CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
1059     CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
1060     CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
1061
1062     UINT result = p->poll( waiptn, wfmode );
1063     if ( ! result )
1064         return E_TMOUT;
1065     *p_flgptn  = result;
1066     return E_OK;
1067 }
1068
1069 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1070 CYG_UIT_FUNC_INLINE
1071 ER
1072 twai_flg ( UINT *p_flgptn, ID flgid, UINT waiptn, UINT wfmode,
1073               TMO tmout )
1074 {
1075     Cyg_Flag *p;
1076     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1077     CYG_UIT_PARAMCHECK_PTR( p_flgptn );
1078     CYG_UIT_PARAMCHECK( 0 == (wfmode & ~Cyg_Flag::MASK), E_PAR );
1079     CYG_UIT_PARAMCHECK( 0 != waiptn, E_PAR );
1080     CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
1081     // check we can use the wfmode value unchanged
1082     CYG_ASSERT( Cyg_Flag::AND == TWF_ANDW, "Flag AND value bad" );
1083     CYG_ASSERT( Cyg_Flag::OR  == TWF_ORW,  "Flag OR value bad" );
1084     CYG_ASSERT( Cyg_Flag::CLR == TWF_CLR,  "Flag CLR value bad" );
1085
1086     // do this now for the case when no sleeping actually occurs
1087     Cyg_Thread *self = Cyg_Thread::self();
1088     self->set_wake_reason( Cyg_Thread::TIMEOUT );
1089     UINT result;
1090     if ( TMO_FEVR == tmout )
1091         result = p->wait( waiptn, wfmode );
1092     else if ( TMO_POL == tmout )
1093         result = p->poll( waiptn, wfmode );
1094     else
1095         result = p->wait( waiptn, wfmode,
1096             Cyg_Clock::real_time_clock->current_value() +
1097             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
1098     if ( ! result )
1099         CYG_UITRON_FAIL_RETURN_SELF( self );
1100     *p_flgptn  = result;
1101     return E_OK;
1102 }
1103 #endif // CYGFUN_KERNEL_THREADS_TIMER
1104
1105 CYG_UIT_FUNC_INLINE
1106 ER
1107 ref_flg ( T_RFLG *pk_rflg, ID flgid )
1108 {
1109     Cyg_Flag *p;
1110     CYG_UITRON_CHECK_AND_GETP_FLAGS( flgid, p );
1111     CYG_UIT_PARAMCHECK_PTR( pk_rflg );
1112     pk_rflg->exinf  = NADR;
1113     pk_rflg->wtsk   = p->waiting();
1114     pk_rflg->flgptn = p->peek();
1115     return E_OK;
1116 }
1117
1118 #endif // 0 < CYG_UITRON_NUM( FLAGS )
1119 #endif // CYGPKG_UITRON_FLAGS
1120
1121 #ifdef CYGPKG_UITRON_MBOXES
1122 #if 0 < CYG_UITRON_NUM( MBOXES )
1123
1124 #ifdef CYGPKG_UITRON_MBOXES_CREATE_DELETE
1125 CYG_UITRON_NEWFUNCTION( Cyg_Mbox )
1126
1127 CYG_UIT_FUNC_INLINE
1128 ER
1129 cre_mbx ( ID mbxid, T_CMBX* pk_cmbx )
1130 {
1131     ER ret = E_OK;
1132     CYG_UIT_PARAMCHECK_PTR( pk_cmbx );
1133     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MBOXES, mbxid );
1134     if ( ((ATR)(TA_TFIFO + TA_MFIFO)) != pk_cmbx->mbxatr )
1135         ret = E_RSATR;
1136     else
1137         CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] =
1138             new( &(CYG_UITRON_OBJS( MBOXES )[ mbxid - 1 ]) )
1139             Cyg_Mbox();
1140     Cyg_Scheduler::unlock();
1141     return ret;
1142 }
1143
1144 CYG_UIT_FUNC_INLINE
1145 ER
1146 del_mbx ( ID mbxid )
1147 {
1148     Cyg_Mbox *p;
1149     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1150     Cyg_Scheduler::lock();
1151     // deal with the race condition here
1152     if ( p != CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] ) {
1153         Cyg_Scheduler::unlock();
1154         return E_NOEXS;
1155     }
1156     CYG_UITRON_PTRS( MBOXES )[ mbxid - 1 ] = NULL;
1157     p->~Cyg_Mbox();
1158     Cyg_Scheduler::unlock();
1159     return E_OK;
1160 }
1161 #endif // CYGPKG_UITRON_MBOXES_CREATE_DELETE
1162
1163 // This bit of unpleasantness is to allow uITRON programs to send a NULL
1164 // message - if permitted by the parameter checking.
1165 // 
1166 // NULL is used internally to mean no message; but -1 is fine.  So we send
1167 // a NULL as a NADR and if we see a NULL coming back, change it to a NADR.
1168 //
1169 // One hopes that often this will be optimized out, since the one or both
1170 // of these being true has been detected and errored out just above.
1171
1172 #ifdef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
1173 // represent a NULL as NADR internally
1174 #define CYG_UIT_TMSG_FIXUP_IN( _p_ )    CYG_MACRO_START                 \
1175     if ( NULL == (_p_) )                                                \
1176         (_p_) = (T_MSG *)NADR;                                          \
1177 CYG_MACRO_END
1178
1179 // we get a NADR back sometimes, meaning NULL
1180 #define CYG_UIT_TMSG_FIXUP_OUT( _p_ )   CYG_MACRO_START                 \
1181     if ( NADR == (_p_) )                                                \
1182         (_p_) = (T_MSG *)NULL;                                          \
1183 CYG_MACRO_END
1184
1185 #else
1186 // NULL is checked for and makes an error
1187 #define CYG_UIT_TMSG_FIXUP_IN( _p_ )    CYG_EMPTY_STATEMENT
1188 #define CYG_UIT_TMSG_FIXUP_OUT( _p_ )   CYG_EMPTY_STATEMENT
1189 #endif
1190
1191 // and sometimes either in status enquiries
1192 #define CYG_UIT_TMSG_FIXUP_ALL( _p_ )   CYG_MACRO_START                 \
1193     if ( NULL == (_p_) )                                                \
1194         (_p_) = (T_MSG *)NADR;                                          \
1195     else if ( NADR == (_p_) )                                           \
1196         (_p_) = (T_MSG *)NULL;                                          \
1197 CYG_MACRO_END
1198
1199 CYG_UIT_FUNC_INLINE
1200 ER
1201 snd_msg ( ID mbxid, T_MSG *pk_msg )
1202 {
1203     Cyg_Mbox *p;
1204     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1205     CYG_UIT_PARAMCHECK_PTR( pk_msg );
1206     CYG_UIT_TMSG_FIXUP_IN( pk_msg );
1207     cyg_bool result = p->tryput( (void *)pk_msg );
1208     if ( ! result )
1209         return E_QOVR;
1210     return E_OK;
1211 }
1212
1213
1214 CYG_UIT_FUNC_INLINE
1215 ER
1216 rcv_msg ( T_MSG **ppk_msg, ID mbxid )
1217 {
1218     Cyg_Mbox *p;
1219     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1220     CYG_UIT_PARAMCHECK_PTR( ppk_msg );
1221     CYG_UITRON_CHECK_DISPATCH_ENABLED();
1222     T_MSG *result = (T_MSG *)p->get();
1223     if ( ! result )
1224         CYG_UITRON_FAIL_RETURN();
1225     CYG_UIT_TMSG_FIXUP_OUT( result );
1226     *ppk_msg = result;
1227     return E_OK;
1228 }
1229
1230 CYG_UIT_FUNC_INLINE
1231 ER
1232 prcv_msg ( T_MSG **ppk_msg, ID mbxid )
1233 {
1234     Cyg_Mbox *p;
1235     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1236     CYG_UIT_PARAMCHECK_PTR( ppk_msg );
1237     T_MSG *result = (T_MSG *)p->tryget();
1238     if ( ! result )
1239         return E_TMOUT;
1240     CYG_UIT_TMSG_FIXUP_OUT( result );
1241     *ppk_msg = result;
1242     return E_OK;
1243 }
1244
1245 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1246 CYG_UIT_FUNC_INLINE
1247 ER
1248 trcv_msg ( T_MSG **ppk_msg, ID mbxid, TMO tmout )
1249 {
1250     Cyg_Mbox *p;
1251     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1252     CYG_UIT_PARAMCHECK_PTR( ppk_msg );
1253     CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
1254     // do this now for the case when no sleeping actually occurs
1255     Cyg_Thread *self = Cyg_Thread::self();
1256     self->set_wake_reason( Cyg_Thread::TIMEOUT );
1257     T_MSG *result;
1258     if ( TMO_FEVR == tmout )
1259         result = (T_MSG *)p->get();
1260     else if ( TMO_POL == tmout )
1261         result = (T_MSG *)p->tryget();
1262     else
1263         result = (T_MSG *)p->get(
1264             Cyg_Clock::real_time_clock->current_value() +
1265             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
1266     if ( ! result )
1267         CYG_UITRON_FAIL_RETURN_SELF( self );
1268     CYG_UIT_TMSG_FIXUP_OUT( result );
1269     *ppk_msg = result;
1270     return E_OK;
1271 }
1272 #endif // CYGFUN_KERNEL_THREADS_TIMER
1273
1274 CYG_UIT_FUNC_INLINE
1275 ER
1276 ref_mbx ( T_RMBX *pk_rmbx, ID mbxid )
1277 {
1278     Cyg_Mbox *p;
1279     CYG_UITRON_CHECK_AND_GETP_MBOXES( mbxid, p );
1280     CYG_UIT_PARAMCHECK_PTR( pk_rmbx );
1281     pk_rmbx->exinf  = NADR;
1282     pk_rmbx->wtsk   = p->waiting_to_get();
1283     pk_rmbx->pk_msg = (T_MSG *)p->peek_item();
1284     CYG_UIT_TMSG_FIXUP_ALL( pk_rmbx->pk_msg );
1285     return E_OK;
1286 }
1287
1288 #undef CYG_UIT_TMSG_FIXUP_IN
1289 #undef CYG_UIT_TMSG_FIXUP_OUT
1290 #undef CYG_UIT_TMSG_FIXUP_ALL
1291         
1292 #endif // 0 < CYG_UITRON_NUM( MBOXES )
1293 #endif // CYGPKG_UITRON_MBOXES
1294
1295 // - Extended Synchronization and Communication Functions
1296         
1297 #if 0 // NOT SUPPORTED
1298 ER      cre_mbf ( ID mbfid, T_CMBF *pk_cmbf );
1299 ER      del_mbf ( ID mbfid );
1300 ER      snd_mbf ( ID mbfid, VP msg, INT msgsz );
1301 ER      psnd_mbf ( ID mbfid, VP msg, INT msgsz );
1302 ER      tsnd_mbf ( ID mbfid, VP msg, INT msgsz, TMO tmout );
1303 ER      rcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
1304 ER      prcv_mbf ( VP msg, INT *p_msgsz, ID mbfid );
1305 ER      trcv_mbf ( VP msg, INT *p_msgsz, ID mbfid, TMO tmout );
1306 ER      ref_mbf ( T_RMBF *pk_rmbf, ID mbfid );
1307 ER      cre_por ( ID porid, T_CPOR *pk_cpor );
1308 ER      del_por ( ID porid );
1309 ER      cal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
1310               cmsgsz );
1311 ER      pcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
1312               cmsgsz );
1313 ER      tcal_por ( VP msg, INT *p_rmsgsz, ID porid, UINT calptn, INT
1314               cmsgsz, TMO tmout );
1315 ER      acp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
1316               acpptn );
1317 ER      pacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
1318               acpptn );
1319 ER      tacp_por ( RNO *p_rdvno, VP msg, INT *p_cmsgsz, ID porid, UINT
1320               acpptn, TMO tmout );
1321 ER      fwd_por ( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz
1322               );
1323 ER      rpl_rdv ( RNO rdvno, VP msg, INT rmsgsz );
1324 ER      ref_por ( T_RPOR *pk_rpor, ID porid );
1325 #endif
1326         
1327 // - Interrupt Management Functions
1328         
1329 #if 0 // NOT SUPPORTED
1330 ER      def_int ( UINT dintno, T_DINT *pk_dint );
1331 void    ret_wup ( ID tskid );
1332 #endif
1333
1334 CYG_UIT_FUNC_INLINE
1335 ER
1336 loc_cpu ( void )
1337 {
1338     CYG_UITRON_CHECK_TASK_CONTEXT();
1339     Cyg_Scheduler::lock();
1340     // Prevent preemption by going up to prio 0
1341     if ( 0 == cyg_uitron_dis_dsp_old_priority ) {
1342 #ifdef CYGIMP_THREAD_PRIORITY
1343         Cyg_Thread *p = Cyg_Thread::self();
1344         cyg_uitron_dis_dsp_old_priority = p->get_priority();
1345         p->set_priority( 0 );
1346 #else
1347         cyg_uitron_dis_dsp_old_priority = 1;
1348 #endif
1349     }
1350     Cyg_Interrupt::disable_interrupts();
1351     Cyg_Scheduler::unlock();
1352     return E_OK;
1353 }
1354
1355 CYG_UIT_FUNC_INLINE
1356 ER
1357 unl_cpu ( void )
1358 {
1359     CYG_UITRON_CHECK_TASK_CONTEXT();
1360     Cyg_Scheduler::lock();
1361     // Enable dispatching (if disabled) and maybe switch threads
1362     if ( 0 != cyg_uitron_dis_dsp_old_priority ) {
1363         // We had prevented preemption by going up to prio 0
1364 #ifdef CYGIMP_THREAD_PRIORITY
1365         Cyg_Thread *p = Cyg_Thread::self();
1366         p->set_priority( cyg_uitron_dis_dsp_old_priority );
1367 #endif
1368         cyg_uitron_dis_dsp_old_priority = 0;
1369     }
1370     Cyg_Interrupt::enable_interrupts();
1371     Cyg_Scheduler::unlock();
1372     CYG_UITRON_CHECK_DISPATCH_ENABLED(); // NB: afterwards!
1373     return E_OK;
1374 }
1375
1376 CYG_UIT_FUNC_INLINE
1377 ER
1378 dis_int ( UINT eintno )
1379 {
1380     CYG_INTERRUPT_STATE old_ints;
1381     
1382 #if 0 < CYGNUM_HAL_ISR_MIN
1383     CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
1384 #endif
1385     CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
1386     HAL_DISABLE_INTERRUPTS(old_ints);
1387     HAL_INTERRUPT_MASK( eintno );
1388     HAL_RESTORE_INTERRUPTS(old_ints);
1389     return E_OK;
1390 }
1391
1392 CYG_UIT_FUNC_INLINE
1393 ER
1394 ena_int ( UINT eintno )
1395 {
1396     CYG_INTERRUPT_STATE old_ints;
1397
1398 #if 0 < CYGNUM_HAL_ISR_MIN
1399     CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MIN <= eintno, E_PAR );
1400 #endif
1401     CYG_UIT_PARAMCHECK( CYGNUM_HAL_ISR_MAX >= eintno, E_PAR );
1402     HAL_DISABLE_INTERRUPTS(old_ints);
1403     HAL_INTERRUPT_UNMASK( eintno );
1404     HAL_RESTORE_INTERRUPTS(old_ints);
1405     return E_OK;
1406 }
1407
1408 #if 0 // NOT SUPPORTED
1409 ER      chg_iXX ( UINT iXXXX );
1410 ER      ref_iXX ( UINT *p_iXXXX );
1411 #endif
1412         
1413 // - Memorypool Management Functions
1414 #ifdef CYGPKG_UITRON_MEMPOOLVAR
1415 #if 0 < CYG_UITRON_NUM( MEMPOOLVAR )
1416
1417 #ifdef CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
1418
1419 CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Variable )
1420
1421 CYG_UIT_FUNC_INLINE
1422 ER
1423 cre_mpl ( ID mplid, T_CMPL *pk_cmpl )
1424 {
1425     ER ret = E_OK;
1426     CYG_UIT_PARAMCHECK_PTR( pk_cmpl );
1427     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLVAR, mplid );
1428     Cyg_Mempool_Variable *p = &(CYG_UITRON_OBJS( MEMPOOLVAR )[ mplid - 1 ]);
1429     Cyg_Mempool_Status stat;
1430
1431     // preserve the original memory area to use
1432     p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
1433
1434     if ( stat.origsize < pk_cmpl->mplsz )
1435         ret = E_NOMEM;
1436     else if ( TA_TFIFO != pk_cmpl->mplatr )
1437         ret = E_RSATR;
1438     else
1439         CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] =
1440             new( p ) Cyg_Mempool_Variable( 
1441                 const_cast<cyg_uint8 *>(stat.origbase), stat.origsize );
1442     Cyg_Scheduler::unlock();
1443     return ret;
1444 }
1445
1446 CYG_UIT_FUNC_INLINE
1447 ER
1448 del_mpl ( ID mplid )
1449 {
1450     Cyg_Mempool_Variable *p;
1451     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1452     Cyg_Scheduler::lock();
1453     // deal with the race condition here
1454     if ( p != CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] ) {
1455         Cyg_Scheduler::unlock();
1456         return E_NOEXS;
1457     }
1458     CYG_UITRON_PTRS( MEMPOOLVAR )[ mplid - 1 ] = NULL;
1459     p->~Cyg_Mempool_Variable();
1460     Cyg_Scheduler::unlock();
1461     return E_OK;
1462 }
1463 #endif // CYGPKG_UITRON_MEMPOOLVAR_CREATE_DELETE
1464
1465 CYG_UIT_FUNC_INLINE
1466 ER
1467 get_blk ( VP *p_blk, ID mplid, INT blksz )
1468 {
1469     Cyg_Mempool_Variable *p;
1470     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1471     CYG_UIT_PARAMCHECK_PTR( p_blk );
1472     CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
1473     CYG_UITRON_CHECK_DISPATCH_ENABLED();
1474     VP result = (VP)p->alloc(blksz);
1475     if ( ! result )
1476         CYG_UITRON_FAIL_RETURN();
1477     *p_blk = result;
1478     return E_OK;
1479 }
1480
1481
1482 CYG_UIT_FUNC_INLINE
1483 ER
1484 pget_blk ( VP *p_blk, ID mplid, INT blksz )
1485 {
1486     Cyg_Mempool_Variable *p;
1487     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1488     CYG_UIT_PARAMCHECK_PTR( p_blk );
1489     CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
1490     VP result = (VP)p->try_alloc(blksz);
1491     if ( ! result )
1492         return E_TMOUT;
1493     *p_blk = result;
1494     return E_OK;
1495 }
1496
1497 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1498 CYG_UIT_FUNC_INLINE
1499 ER
1500 tget_blk ( VP *p_blk, ID mplid, INT blksz, TMO tmout )
1501 {
1502     Cyg_Mempool_Variable *p;
1503     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1504     CYG_UIT_PARAMCHECK_PTR( p_blk );
1505     CYG_UIT_PARAMCHECK( blksz > 0, E_PAR );
1506     CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
1507     // do this now for the case when no sleeping actually occurs
1508     Cyg_Thread *self = Cyg_Thread::self();
1509     self->set_wake_reason( Cyg_Thread::TIMEOUT );
1510     VP result;
1511     if ( TMO_FEVR == tmout )
1512         result = p->alloc(blksz);
1513     else if ( TMO_POL == tmout )
1514         result = p->try_alloc(blksz);
1515     else
1516         result = p->alloc( blksz,
1517             Cyg_Clock::real_time_clock->current_value() +
1518             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
1519     if ( ! result )
1520         CYG_UITRON_FAIL_RETURN_SELF( self );
1521     *p_blk = result;
1522     return E_OK;
1523 }
1524 #endif // CYGFUN_KERNEL_THREADS_TIMER
1525
1526 CYG_UIT_FUNC_INLINE
1527 ER
1528 rel_blk ( ID mplid, VP blk )
1529 {
1530     Cyg_Mempool_Variable *p;
1531     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1532     CYG_UIT_PARAMCHECK_PTR( blk );
1533     cyg_bool result = p->free( (cyg_uint8 *)blk );
1534     if ( ! result )
1535         return E_PAR;
1536     return E_OK;
1537 }
1538
1539 CYG_UIT_FUNC_INLINE
1540 ER
1541 ref_mpl ( T_RMPL *pk_rmpl, ID mplid )
1542 {
1543     Cyg_Mempool_Variable *p;
1544     Cyg_Mempool_Status stat;
1545     CYG_UITRON_CHECK_AND_GETP_MEMPOOLVAR( mplid, p );
1546     CYG_UIT_PARAMCHECK_PTR( pk_rmpl );
1547     p->get_status( CYG_MEMPOOL_STAT_WAITING|
1548                    CYG_MEMPOOL_STAT_TOTALFREE|
1549                    CYG_MEMPOOL_STAT_MAXFREE, stat );
1550
1551     pk_rmpl->exinf = NADR;
1552     pk_rmpl->wtsk = stat.waiting;
1553     pk_rmpl->frsz = stat.totalfree;
1554     pk_rmpl->maxsz = stat.maxfree;
1555
1556     return E_OK;
1557 }
1558
1559 #endif // 0 < CYG_UITRON_NUM( MEMPOOLVAR )
1560 #endif // CYGPKG_UITRON_MEMPOOLVAR
1561
1562 #ifdef CYGPKG_UITRON_MEMPOOLFIXED
1563 #if 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
1564
1565 #ifdef CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
1566
1567 CYG_UITRON_NEWFUNCTION( Cyg_Mempool_Fixed )
1568
1569 CYG_UIT_FUNC_INLINE
1570 ER
1571 cre_mpf ( ID mpfid, T_CMPF *pk_cmpf )
1572 {
1573     ER ret = E_OK;
1574     CYG_UIT_PARAMCHECK_PTR( pk_cmpf );
1575     CYG_UITRON_CHECK_NO_OBJ_LOCK_SCHED( MEMPOOLFIXED, mpfid );
1576     Cyg_Mempool_Fixed *p = &(CYG_UITRON_OBJS( MEMPOOLFIXED )[ mpfid - 1 ]);
1577     Cyg_Mempool_Status stat;
1578
1579     // preserve the original memory area to use
1580     p->get_status( CYG_MEMPOOL_STAT_ORIGBASE|CYG_MEMPOOL_STAT_ORIGSIZE, stat );
1581
1582     if ( stat.origsize < (pk_cmpf->blfsz * (pk_cmpf->mpfcnt + 1)) )
1583         ret = E_NOMEM;
1584     else if ( TA_TFIFO != pk_cmpf->mpfatr )
1585         ret = E_RSATR;
1586     else
1587         CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] =
1588             new( p )
1589             Cyg_Mempool_Fixed( const_cast<cyg_uint8 *>(stat.origbase),
1590                                stat.origsize, (CYG_ADDRWORD)pk_cmpf->blfsz );
1591     Cyg_Scheduler::unlock();
1592     return ret;
1593 }
1594
1595 CYG_UIT_FUNC_INLINE
1596 ER
1597 del_mpf ( ID mpfid )
1598 {
1599     Cyg_Mempool_Fixed *p;
1600     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1601     Cyg_Scheduler::lock();
1602     // deal with the race condition here
1603     if ( p != CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] ) {
1604         Cyg_Scheduler::unlock();
1605         return E_NOEXS;
1606     }
1607     CYG_UITRON_PTRS( MEMPOOLFIXED )[ mpfid - 1 ] = NULL;
1608     p->~Cyg_Mempool_Fixed();
1609     Cyg_Scheduler::unlock();
1610     return E_OK;
1611 }
1612 #endif // CYGPKG_UITRON_MEMPOOLFIXED_CREATE_DELETE
1613
1614 CYG_UIT_FUNC_INLINE
1615 ER
1616 get_blf ( VP *p_blf, ID mpfid )
1617 {
1618     Cyg_Mempool_Fixed *p;
1619     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1620     CYG_UIT_PARAMCHECK_PTR( p_blf );
1621     CYG_UITRON_CHECK_DISPATCH_ENABLED();
1622     VP result = (VP)p->alloc();
1623     if ( ! result )
1624         CYG_UITRON_FAIL_RETURN();
1625     *p_blf = result;
1626     return E_OK;
1627 }
1628
1629 CYG_UIT_FUNC_INLINE
1630 ER
1631 pget_blf ( VP *p_blf, ID mpfid )
1632 {
1633     Cyg_Mempool_Fixed *p;
1634     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1635     CYG_UIT_PARAMCHECK_PTR( p_blf );
1636     VP result = (VP)p->try_alloc();
1637     if ( ! result )
1638         return E_TMOUT;
1639     *p_blf = result;
1640     return E_OK;
1641 }
1642
1643 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1644 CYG_UIT_FUNC_INLINE
1645 ER
1646 tget_blf ( VP *p_blf, ID mpfid, TMO tmout )
1647 {
1648     Cyg_Mempool_Fixed *p;
1649     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1650     CYG_UIT_PARAMCHECK_PTR( p_blf );
1651     CYG_UITRON_CHECK_DISPATCH_ENABLED_TMO( tmout );
1652     // do this now for the case when no sleeping actually occurs
1653     Cyg_Thread *self = Cyg_Thread::self();
1654     self->set_wake_reason( Cyg_Thread::TIMEOUT );
1655     VP result;
1656     if ( TMO_FEVR == tmout )
1657         result = p->alloc();
1658     else if ( TMO_POL == tmout )
1659         result = p->try_alloc();
1660     else
1661         result = p->alloc(
1662             Cyg_Clock::real_time_clock->current_value() +
1663             (cyg_tick_count)CYG_UITRON_TIME_UIT_TO_SYS32( tmout ) );
1664     if ( ! result )
1665         CYG_UITRON_FAIL_RETURN_SELF( self );
1666     *p_blf = result;
1667     return E_OK;
1668 }
1669 #endif // CYGFUN_KERNEL_THREADS_TIMER
1670
1671 CYG_UIT_FUNC_INLINE
1672 ER
1673 rel_blf ( ID mpfid, VP blf )
1674 {
1675     Cyg_Mempool_Fixed *p;
1676     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1677     CYG_UIT_PARAMCHECK_PTR( blf );
1678     cyg_bool result = p->free( (cyg_uint8 *)blf );
1679     if ( ! result )
1680         return E_PAR;
1681     return E_OK;
1682 }
1683
1684 CYG_UIT_FUNC_INLINE
1685 ER
1686 ref_mpf ( T_RMPF *pk_rmpf, ID mpfid )
1687 {
1688     Cyg_Mempool_Fixed *p;
1689     Cyg_Mempool_Status stat;
1690     CYG_UITRON_CHECK_AND_GETP_MEMPOOLFIXED( mpfid, p );
1691     CYG_UIT_PARAMCHECK_PTR( pk_rmpf );
1692
1693     p->get_status( CYG_MEMPOOL_STAT_WAITING|
1694                    CYG_MEMPOOL_STAT_TOTALFREE|
1695                    CYG_MEMPOOL_STAT_TOTALALLOCATED|
1696                    CYG_MEMPOOL_STAT_BLOCKSIZE, stat );
1697
1698     pk_rmpf->exinf = NADR;
1699     pk_rmpf->wtsk = stat.waiting;
1700
1701     pk_rmpf->frbcnt = stat.totalfree / stat.blocksize;
1702     // these two are "implementation dependent" ie. eCos only
1703     pk_rmpf->numbcnt = stat.totalallocated / stat.blocksize;
1704     pk_rmpf->bsize = stat.blocksize;
1705
1706     return E_OK;
1707 }
1708         
1709 #endif // 0 < CYG_UITRON_NUM( MEMPOOLFIXED )
1710 #endif // CYGPKG_UITRON_MEMPOOLFIXED
1711
1712 // - Time Management Functions
1713         
1714 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
1715 CYG_UIT_FUNC_INLINE
1716 ER
1717 set_tim ( SYSTIME *pk_tim )
1718 {
1719     CYG_UIT_PARAMCHECK_PTR( pk_tim );
1720     Cyg_Clock::real_time_clock->set_value(
1721         CYG_UITRON_TIME_UIT_TO_SYS64( *pk_tim ) );
1722     return E_OK;
1723 }
1724
1725 CYG_UIT_FUNC_INLINE
1726 ER
1727 get_tim ( SYSTIME *pk_tim )
1728 {
1729     CYG_UIT_PARAMCHECK_PTR( pk_tim );
1730     *pk_tim = CYG_UITRON_TIME_SYS_TO_UIT64(
1731         Cyg_Clock::real_time_clock->current_value() );
1732     return E_OK;
1733 }
1734 #endif // CYGVAR_KERNEL_COUNTERS_CLOCK
1735
1736
1737 #ifdef CYGFUN_KERNEL_THREADS_TIMER
1738 CYG_UIT_FUNC_INLINE
1739 ER
1740 dly_tsk ( DLYTIME dlytim )
1741 {
1742     CYG_UIT_PARAMCHECK( 0 <= dlytim, E_PAR );
1743     CYG_UITRON_CHECK_DISPATCH_ENABLED();
1744     if ( 0 >= dlytim )
1745         return E_OK;
1746     Cyg_Thread *self = Cyg_Thread::self();
1747     CYG_UITRON_CHECK_TASK_CONTEXT_SELF( self );
1748     self->delay( CYG_UITRON_TIME_UIT_TO_SYS64( dlytim ) );
1749     if ( Cyg_Thread::DONE != self->get_wake_reason() )
1750         CYG_UITRON_FAIL_RETURN_SELF( self );
1751     return E_OK;
1752 }
1753 #endif // CYGFUN_KERNEL_THREADS_TIMER
1754
1755 #ifdef CYGVAR_KERNEL_COUNTERS_CLOCK
1756 #ifdef CYGPKG_UITRON_CYCLICS
1757 #if 0 < CYG_UITRON_NUM( CYCLICS )
1758 CYG_UIT_FUNC_INLINE
1759 ER
1760 def_cyc ( HNO cycno, T_DCYC *pk_dcyc )
1761 {
1762     // pk_dcyc->cycatr is ignored
1763     // The only relevant attribute is TA_HLNG/TA_ASM.
1764     // This can be ignored as assembler routines are defined to be
1765     // more conservative with registers than the procedure call standard.
1766     cyg_tick_count t;
1767     Cyg_Timer *p;
1768     CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
1769 #ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
1770     CYG_UIT_PARAMCHECK( NULL != pk_dcyc, E_PAR );
1771 #endif
1772     if( NADR == pk_dcyc ) {
1773         p->~Cyg_Timer();
1774         return E_OK;
1775     }
1776     CYG_UIT_PARAMCHECK( 0 == (pk_dcyc->cycact & ~TCY_ON), E_PAR );
1777     CYG_UIT_PARAMCHECK( 0 < pk_dcyc->cyctim, E_PAR );
1778     t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dcyc->cyctim );
1779     p->initialize(
1780         Cyg_Clock::real_time_clock,
1781         (cyg_alarm_fn *)pk_dcyc->cychdr,
1782         (CYG_ADDRWORD)pk_dcyc->exinf,
1783         Cyg_Clock::real_time_clock->current_value() + t,
1784         t,
1785         pk_dcyc->cycact);
1786     return E_OK;
1787 }
1788
1789 CYG_UIT_FUNC_INLINE
1790 ER
1791 act_cyc ( HNO cycno, UINT cycact )
1792 {
1793     Cyg_Timer *p;
1794     CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
1795     CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
1796     CYG_UIT_PARAMCHECK( 0 == (cycact & ~(TCY_ON | TCY_INI)), E_PAR );
1797     p->activate(cycact);
1798     return E_OK;
1799 }
1800
1801
1802 CYG_UIT_FUNC_INLINE
1803 ER
1804 ref_cyc ( T_RCYC *pk_rcyc, HNO cycno )
1805 {
1806     Cyg_Timer *p;
1807     cyg_tick_count t;
1808     CYG_UITRON_CHECK_AND_GETHDLR( CYCLICS, cycno, p );
1809     CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
1810     CYG_UIT_PARAMCHECK_PTR( pk_rcyc );
1811
1812     pk_rcyc->exinf = (VP)p->get_data();
1813     Cyg_Scheduler::lock();
1814     t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
1815     Cyg_Scheduler::unlock();
1816     pk_rcyc->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
1817     pk_rcyc->cycact = (UINT)p->is_enabled();
1818     return E_OK;
1819 }
1820 #endif // 0 < CYG_UITRON_NUM( CYCLICS )
1821 #endif // CYGPKG_UITRON_CYCLICS
1822
1823 #ifdef CYGPKG_UITRON_ALARMS
1824 #if 0 < CYG_UITRON_NUM( ALARMS )
1825 CYG_UIT_FUNC_INLINE
1826 ER
1827 def_alm ( HNO almno, T_DALM *pk_dalm )
1828 {
1829     Cyg_Timer *p;
1830     cyg_tick_count t, now;
1831     CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
1832 #ifndef CYGSEM_UITRON_PARAMS_NULL_IS_GOOD_PTR
1833     CYG_UIT_PARAMCHECK( NULL != pk_dalm, E_PAR );
1834 #endif
1835     if( NADR == pk_dalm ) {
1836         p->~Cyg_Timer();
1837         return E_OK;
1838     }
1839
1840     CYG_UIT_PARAMCHECK( 0 == (pk_dalm->tmmode & ~TTM_REL), E_PAR );
1841     CYG_UIT_PARAMCHECK( 0 < pk_dalm->almtim, E_PAR );
1842
1843     // make the time arithmetic safe without locking
1844     now = Cyg_Clock::real_time_clock->current_value();
1845     t = CYG_UITRON_TIME_UIT_TO_SYS64( pk_dalm->almtim );
1846     if( TTM_REL & pk_dalm->tmmode )
1847         t += now;
1848
1849     CYG_UIT_PARAMCHECK( now < t, E_PAR );
1850
1851     p->initialize(Cyg_Clock::real_time_clock,
1852                   (cyg_alarm_fn *)pk_dalm->almhdr,
1853                   (CYG_ADDRWORD)pk_dalm->exinf,
1854                   t, 0, Cyg_Timer::ENABLE);
1855
1856     return E_OK;
1857 }
1858
1859 CYG_UIT_FUNC_INLINE
1860 ER
1861 ref_alm ( T_RALM *pk_ralm, HNO almno )
1862 {
1863     Cyg_Timer *p;
1864     cyg_tick_count t;
1865
1866     CYG_UITRON_CHECK_AND_GETHDLR( ALARMS, almno, p );
1867     CYG_UIT_PARAMCHECK_PTR( pk_ralm );
1868     CYG_UIT_PARAMCHECK( p->is_initialized(), E_NOEXS);
1869
1870     Cyg_Scheduler::lock();
1871     t = p->get_trigger() - Cyg_Clock::real_time_clock->current_value();
1872     Cyg_Scheduler::unlock();
1873     pk_ralm->exinf  = (VP)p->get_data();
1874     pk_ralm->lfttim = CYG_UITRON_TIME_SYS_TO_UIT64( t );
1875     return E_OK;
1876 }
1877 #endif // 0 < CYG_UITRON_NUM( ALARMS )
1878 #endif // CYGPKG_UITRON_ALARMS
1879
1880 #endif // CYGVAR_KERNEL_COUNTERS_CLOCK
1881         
1882 // - System Management Functions
1883         
1884 CYG_UIT_FUNC_INLINE
1885 ER
1886 get_ver ( T_VER *pk_ver )
1887 {
1888     CYG_UIT_PARAMCHECK_PTR( pk_ver );
1889
1890     pk_ver->maker       = CYGNUM_UITRON_VER_MAKER;
1891     pk_ver->id          = CYGNUM_UITRON_VER_ID;
1892     pk_ver->spver       = CYGNUM_UITRON_VER_SPVER;
1893     pk_ver->prver       = CYGNUM_UITRON_VER_PRVER;
1894     pk_ver->prno[0]     = CYGNUM_UITRON_VER_PRNO_0;
1895     pk_ver->prno[1]     = CYGNUM_UITRON_VER_PRNO_1;
1896     pk_ver->prno[2]     = CYGNUM_UITRON_VER_PRNO_2;
1897     pk_ver->prno[3]     = CYGNUM_UITRON_VER_PRNO_3;
1898     pk_ver->cpu         = CYGNUM_UITRON_VER_CPU;
1899     pk_ver->var         = CYGNUM_UITRON_VER_VAR;
1900    
1901     return E_OK;
1902 }
1903
1904 CYG_UIT_FUNC_INLINE
1905 ER
1906 ref_sys ( T_RSYS *pk_rsys )
1907 {
1908     CYG_UIT_PARAMCHECK_PTR( pk_rsys );
1909     if ( ! Cyg_Interrupt::interrupts_enabled() )
1910         // CPU is locked
1911         pk_rsys->sysstat = TSS_LOC;
1912     else
1913         pk_rsys->sysstat =
1914             (0 == cyg_uitron_dis_dsp_old_priority) ? TSS_TSK : TSS_DDSP;
1915     return E_OK;
1916 }
1917
1918 CYG_UIT_FUNC_INLINE
1919 ER
1920 ref_cfg ( T_RCFG *pk_rcfg )
1921 {
1922     CYG_UIT_PARAMCHECK_PTR( pk_rcfg );
1923     // no details here yet
1924     return E_OK;
1925 }
1926
1927 #if 0 // NOT SUPPORTED
1928 ER      def_svc ( FN s_fncd, T_DSVC *pk_dsvc );
1929 ER      def_exc ( UINT exckind, T_DEXC *pk_dexc );
1930 #endif
1931         
1932 // - Network Support Functions
1933         
1934 #if 0 // NOT SUPPORTED
1935 ER      nrea_dat ( INT *p_reasz, VP dstadr, NODE srcnode, VP srcadr,
1936                INT datsz );
1937 ER      nwri_dat ( INT *p_wrisz, NODE dstnode, VP dstadr, VP srcadr,
1938                INT datsz );
1939 ER      nget_nod ( NODE *p_node );
1940 ER      nget_ver ( T_VER *pk_ver, NODE node );
1941 #endif
1942
1943 // ========================================================================
1944
1945 #endif // CYGPKG_UITRON
1946
1947 #endif // CYGPRI_UITRON_FUNCS_HERE_AND_NOW
1948
1949 #endif // CYGONCE_COMPAT_UITRON_UIT_FUNC_INL
1950 //EOF uit_func.inl