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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [compat/] [uitron/] [v2_0/] [include/] [uit_func.inl] - Blame information for rev 773

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
#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  // uITRON setup CYGNUM_UITRON_SEMAS
60
 
61
// kernel facilities only needed here
62
#include 
63
#include 
64
 
65
// and the implementations of other kernel facilities
66
#include 
67
#include 
68
#include 
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(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(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

powered by: WebSVN 2.1.0

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