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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [compat/] [uitron/] [current/] [include/] [uit_func.inl] - Blame information for rev 786

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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