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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [include/] [thread.inl] - Blame information for rev 851

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

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_KERNEL_THREAD_INL
2
#define CYGONCE_KERNEL_THREAD_INL
3
 
4
//==========================================================================
5
//
6
//      thread.inl
7
//
8
//      Thread class inlines
9
//
10
//==========================================================================
11
// ####ECOSGPLCOPYRIGHTBEGIN####
12
// -------------------------------------------
13
// This file is part of eCos, the Embedded Configurable Operating System.
14
// Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2008 Free Software Foundation, Inc.
15
//
16
// eCos is free software; you can redistribute it and/or modify it under
17
// the terms of the GNU General Public License as published by the Free
18
// Software Foundation; either version 2 or (at your option) any later
19
// version.
20
//
21
// eCos is distributed in the hope that it will be useful, but WITHOUT
22
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
24
// for more details.
25
//
26
// You should have received a copy of the GNU General Public License
27
// along with eCos; if not, write to the Free Software Foundation, Inc.,
28
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
29
//
30
// As a special exception, if other files instantiate templates or use
31
// macros or inline functions from this file, or you compile this file
32
// and link it with other works to produce a work based on this file,
33
// this file does not by itself cause the resulting work to be covered by
34
// the GNU General Public License. However the source code for this file
35
// must still be made available in accordance with section (3) of the GNU
36
// General Public License v2.
37
//
38
// This exception does not invalidate any other reasons why a work based
39
// on this file might be covered by the GNU General Public License.
40
// -------------------------------------------
41
// ####ECOSGPLCOPYRIGHTEND####
42
//==========================================================================
43
//#####DESCRIPTIONBEGIN####
44
//
45
// Author(s):   nickg
46
// Contributors:        nickg
47
// Date:        1997-09-09
48
// Purpose:     Define inlines for thread classes
49
// Description: Inline implementations of various member functions defined
50
//              in various Thread classes.
51
// Usage:
52
//              #include 
53
//              ...
54
//              #include 
55
//              ...
56
 
57
//
58
//####DESCRIPTIONEND####
59
//
60
//==========================================================================
61
 
62
#include 
63
#include 
64
 
65
#include 
66
#include 
67
 
68
#ifndef CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE
69
#define CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE (0)
70
#endif
71
 
72
//==========================================================================
73
// Inlines for Cyg_HardwareThread
74
 
75
// -------------------------------------------------------------------------
76
// get the size/base of this thread's stack
77
 
78
inline CYG_ADDRESS
79
Cyg_HardwareThread::get_stack_base()
80
{
81
    return stack_base - CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
82
}
83
 
84
inline cyg_uint32
85
Cyg_HardwareThread::get_stack_size()
86
{
87
    return stack_size + 2 * CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
88
}
89
 
90
// -------------------------------------------------------------------------
91
// Check the stack bounds of this thread:
92
#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
93
inline void Cyg_HardwareThread::check_stack(void)
94
{
95
    cyg_uint32 sig = (cyg_uint32)this;
96
    cyg_uint32 *base = (cyg_uint32 *)get_stack_base();
97
    cyg_uint32 *top =  (cyg_uint32 *)(stack_base + stack_size);
98
    cyg_ucount32 i;
99
 
100
    CYG_INSTRUMENT_THREAD(CHECK_STACK, base, top );
101
 
102
    CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base not word aligned" );
103
    CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top not word aligned" );
104
 
105
    CYG_ASSERT( (cyg_uint32)stack_ptr > (cyg_uint32)stack_base,
106
                "Stack_ptr below base" );
107
    CYG_ASSERT( (cyg_uint32)stack_ptr <= ((cyg_uint32)stack_base + stack_size),
108
                "Stack_ptr above top" );
109
 
110
    for ( i = 0;
111
          i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
112
          i++ ) {
113
        if ((sig ^ (i * 0x01010101)) != base[i]) {
114
            const char *reason = "Stack base corrupt";
115
            diag_printf("%s - i: %d\n", reason, i);
116
            diag_dump_buf(base, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
117
            CYG_FAIL(reason);
118
        }
119
        if ((sig ^ (i * 0x10101010)) != top[i]) {
120
            const char *reason = "Stack top corrupt";
121
            diag_printf("%s - i: %d\n", reason, i);
122
            diag_dump_buf(top, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
123
            CYG_FAIL(reason);
124
        }
125
    }
126
 
127
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
128
    // we won't have added check data above the stack limit if it hasn't
129
    // been incremented
130
    if (stack_limit != stack_base) {
131
        CYG_ADDRESS limit = stack_limit;
132
        // the limit will be off by the check data size, so lets correct it
133
        limit -= CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE;
134
 
135
        // determine base of check data by rounding up to nearest word aligned
136
        // address if not already aligned
137
        cyg_uint32 *p = (cyg_uint32 *)((limit + 3) & ~3);
138
        // i.e. + sizeof(cyg_uint32)-1) & ~(sizeof(cyg_uint32)-1);
139
 
140
        for ( i = 0;
141
              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
142
              i++ ) {
143
            if ((sig ^ (i * 0x01010101)) != p[i]) {
144
                const char *reason = "Gap between stack limit and base corrupt";
145
                diag_printf("%s - i: %d\n", reason, i);
146
                diag_dump_buf(p, CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
147
                CYG_FAIL(reason);
148
            }
149
        }
150
    }
151
#endif
152
}
153
#endif
154
 
155
// -------------------------------------------------------------------------
156
// Measure the stack usage of the thread
157
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
158
inline cyg_uint32 Cyg_HardwareThread::measure_stack_usage(void)
159
{
160
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
161
    CYG_WORD *base = (CYG_WORD *)stack_limit;
162
    cyg_uint32 size = (stack_size - (stack_limit-stack_base))/sizeof(CYG_WORD);
163
#else
164
    CYG_WORD *base = (CYG_WORD *)stack_base;
165
    cyg_uint32 size = stack_size/sizeof(CYG_WORD);
166
#endif
167
    cyg_ucount32 i;
168
 
169
    // Work up the stack comparing with the preset value
170
    // We assume the stack grows downwards, hmm...
171
    for (i=0; i
172
        if (base[i] != 0xDEADBEEF)
173
          break;
174
    }
175
    return (size - i)*sizeof(CYG_WORD);
176
}
177
#endif
178
 
179
// -------------------------------------------------------------------------
180
// Attach a stack to this thread. If there is a HAL defined macro to
181
// do this, then we use that, otherwise assume a falling stack.
182
inline void Cyg_HardwareThread::attach_stack(CYG_ADDRESS s_base, cyg_uint32 s_size)
183
{
184
#ifdef CYGNUM_HAL_STACK_SIZE_MINIMUM
185
    CYG_ASSERT( s_size >= CYGNUM_HAL_STACK_SIZE_MINIMUM,
186
                "Stack size too small");
187
#endif
188
 
189
#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
190
    {
191
        cyg_uint32 sig = (cyg_uint32)this;
192
        cyg_uint32 *base = (cyg_uint32 *)s_base;
193
        cyg_uint32 *top =  (cyg_uint32 *)(s_base + s_size -
194
            CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE);
195
 
196
        unsigned int i;
197
 
198
        CYG_INSTRUMENT_THREAD(ATTACH_STACK, base, top );
199
 
200
        CYG_ASSERT( NULL != base, "stack base non-NULL" );
201
        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)base), "stack base alignment" );
202
        CYG_ASSERT( 0 == ((sizeof(CYG_WORD)-1) & (cyg_uint32)top),  "stack  top alignment" );
203
 
204
        for ( i = 0;
205
              i < CYGNUM_KERNEL_THREADS_STACK_CHECK_DATA_SIZE/sizeof(cyg_uint32);
206
              i++ ) {
207
            base[i] = (sig ^ (i * 0x01010101));
208
             top[i] = (sig ^ (i * 0x10101010));
209
        }
210
        // This check for overlap of the two signature areas also detects
211
        // wrap round zero of the size in the unsigned subtraction below.
212
        CYG_ASSERT( &base[i] < &top[0], "Stack is so small size wrapped" );
213
        // Use this 'i' expression to round correctly to whole words.
214
        s_base += i * sizeof(cyg_uint32);
215
        s_size -= i * sizeof(cyg_uint32) * 2;
216
        // This is a complete guess, the 256; the point is to assert early that
217
        // this might go badly wrong.  It would not detect wrap of unsigned size.
218
        CYG_ASSERT( s_size >= 256,
219
                    "Stack size too small after allocating checking buffer");
220
    }
221
#endif
222
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
223
    {
224
        CYG_WORD *base = (CYG_WORD *)s_base;
225
        cyg_uint32 size = s_size/sizeof(CYG_WORD);
226
        cyg_ucount32 i;
227
 
228
        // initialize all of stack with known value - don't choose 0
229
        // could do with pseudo value as above, but this way, checking
230
        // is faster
231
        for (i=0; i
232
                base[i] = 0xDEADBEEF;
233
        }
234
        // Don't bother about the case when the stack isn't a multiple of
235
        // CYG_WORD in size. Since it's at the top of the stack, it will
236
        // almost certainly be overwritten the instant the thread starts
237
        // anyway.
238
    }
239
#endif
240
    stack_base = s_base;
241
    stack_size = s_size;
242
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
243
    stack_limit = s_base;
244
#endif
245
 
246
#ifdef HAL_THREAD_ATTACH_STACK
247
 
248
    HAL_THREAD_ATTACH_STACK(stack_ptr, stack_base, stack_size);
249
 
250
#else
251
 
252
    stack_ptr = stack_base + stack_size;
253
 
254
#endif
255
 
256
#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
257
    check_stack();
258
#endif
259
}
260
 
261
// -------------------------------------------------------------------------
262
 
263
inline Cyg_HardwareThread::Cyg_HardwareThread(
264
    cyg_thread_entry        *e_point,   // entry point function
265
    CYG_ADDRWORD            e_data,     // entry data
266
    cyg_ucount32            s_size,     // stack size, 0 = use default
267
    CYG_ADDRESS             s_base      // stack base, NULL = allocate
268
)
269
{
270
    entry_point = e_point;
271
    entry_data  = e_data;
272
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
273
    saved_context = 0;
274
#endif
275
 
276
    attach_stack( s_base, s_size );
277
};
278
 
279
// -------------------------------------------------------------------------
280
 
281
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
282
 
283
// Return the current saved state for this thread.
284
inline HAL_SavedRegisters *Cyg_HardwareThread::get_saved_context()
285
{
286
    HAL_SavedRegisters *regs;
287
    if( saved_context != 0 ) regs = saved_context;
288
    else HAL_THREAD_GET_SAVED_REGISTERS( stack_ptr, regs );
289
    return regs;
290
}
291
 
292
inline void Cyg_HardwareThread::set_saved_context(HAL_SavedRegisters *ctx)
293
{
294
    saved_context = ctx;
295
}
296
 
297
#endif
298
 
299
// -------------------------------------------------------------------------
300
// (declare this inline before its first use)
301
 
302
inline cyg_uint16 Cyg_Thread::get_unique_id()
303
{
304
    return unique_id;
305
}
306
 
307
// -------------------------------------------------------------------------
308
// Initialize the context of this thread.
309
 
310
inline void Cyg_HardwareThread::init_context(Cyg_Thread *thread)
311
{
312
#ifdef CYGPKG_INFRA_DEBUG
313
    cyg_uint32 threadid = thread->get_unique_id()*0x01010000;
314
#else
315
    cyg_uint32 threadid = 0x11110000;
316
#endif
317
    HAL_THREAD_INIT_CONTEXT( stack_ptr, thread, thread_entry, threadid );
318
}
319
 
320
 
321
 
322
// -------------------------------------------------------------------------
323
// Save current thread's context and load that of the given next thread.
324
// This function is only really here for completeness, the
325
// kernel generally calls the HAL macros directly.
326
 
327
inline void Cyg_HardwareThread::switch_context(Cyg_HardwareThread *next)
328
{
329
    HAL_THREAD_SWITCH_CONTEXT( &stack_ptr, &next->stack_ptr );
330
}
331
 
332
// -------------------------------------------------------------------------
333
// Get and set entry_data.
334
 
335
inline void Cyg_HardwareThread::set_entry_data( CYG_ADDRWORD data )
336
{
337
    entry_data = data;
338
}
339
 
340
inline CYG_ADDRWORD Cyg_HardwareThread::get_entry_data()
341
{
342
    return entry_data;
343
}
344
 
345
// -------------------------------------------------------------------------
346
// Allocate some memory at the lower end of the stack
347
// by moving the stack limit pointer.
348
 
349
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
350
 
351
#ifndef CYGFUN_KERNEL_THREADS_STACK_CHECKING
352
// if stack checking, implementation is in thread.cxx
353
inline void *Cyg_HardwareThread::increment_stack_limit( cyg_ucount32 size )
354
{
355
    void *ret = (void *)stack_limit;
356
    stack_limit += size;
357
    return ret;
358
}
359
#endif
360
 
361
inline CYG_ADDRESS
362
Cyg_HardwareThread::get_stack_limit()
363
{
364
    return stack_limit;
365
}
366
 
367
#endif
368
 
369
//==========================================================================
370
// Inlines for Cyg_Thread class
371
 
372
inline Cyg_Thread *Cyg_Thread::self()
373
{
374
    return Cyg_Scheduler::get_current_thread();
375
}
376
 
377
// -------------------------------------------------------------------------
378
 
379
inline void Cyg_Thread::yield()
380
{
381
    self()->Cyg_SchedThread::yield();
382
}
383
 
384
// -------------------------------------------------------------------------
385
 
386
inline void
387
Cyg_Thread::rotate_queue( cyg_priority pri )
388
{
389
    self()->Cyg_SchedThread::rotate_queue( pri );
390
}
391
 
392
// -------------------------------------------------------------------------
393
 
394
inline void
395
Cyg_Thread::to_queue_head( void )
396
{
397
    this->Cyg_SchedThread::to_queue_head();
398
}
399
 
400
// -------------------------------------------------------------------------
401
 
402
#ifdef CYGIMP_THREAD_PRIORITY
403
 
404
inline cyg_priority Cyg_Thread::get_priority()
405
{
406
#ifdef CYGSEM_KERNEL_SYNCH_MUTEX_PRIORITY_INVERSION_PROTOCOL_SIMPLE
407
 
408
    // If we have an inherited priority, return our original
409
    // priority rather than the current one.
410
 
411
    if( priority_inherited ) return original_priority;
412
 
413
#endif
414
 
415
    return priority;
416
}
417
 
418
// Return the actual dispatching priority of the thread
419
// regardless of inheritance or scheduling concerns.
420
inline cyg_priority Cyg_Thread::get_current_priority()
421
{
422
    return priority;
423
}
424
 
425
#endif
426
 
427
// -------------------------------------------------------------------------
428
 
429
inline void Cyg_Thread::set_sleep_reason( cyg_reason reason)
430
{
431
    self()->sleep_reason = reason;
432
    self()->wake_reason = NONE;
433
}
434
 
435
// -------------------------------------------------------------------------
436
 
437
inline Cyg_Thread::cyg_reason Cyg_Thread::get_sleep_reason()
438
{
439
    return sleep_reason;
440
}
441
 
442
// -------------------------------------------------------------------------
443
 
444
inline void Cyg_Thread::set_wake_reason( cyg_reason reason )
445
{
446
    sleep_reason = NONE;
447
    wake_reason = reason;
448
}
449
 
450
// -------------------------------------------------------------------------
451
 
452
inline Cyg_Thread::cyg_reason Cyg_Thread::get_wake_reason()
453
{
454
    return wake_reason;
455
}
456
 
457
// -------------------------------------------------------------------------
458
 
459
inline void Cyg_Thread::set_timer(
460
    cyg_tick_count      trigger,
461
    cyg_reason          reason
462
)
463
{
464
#ifdef CYGFUN_KERNEL_THREADS_TIMER
465
    self()->sleep_reason = reason;
466
    self()->wake_reason = NONE;
467
    self()->timer.initialize( trigger);
468
#endif
469
}
470
 
471
// -------------------------------------------------------------------------
472
 
473
inline void Cyg_Thread::clear_timer()
474
{
475
#ifdef CYGFUN_KERNEL_THREADS_TIMER
476
    self()->timer.disable();
477
#endif
478
}
479
 
480
// -------------------------------------------------------------------------
481
 
482
#ifdef CYGVAR_KERNEL_THREADS_DATA
483
 
484
inline CYG_ADDRWORD Cyg_Thread::get_data( Cyg_Thread::cyg_data_index index )
485
{
486
    CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
487
                "Per thread data index out of bounds");
488
    CYG_ASSERT( (thread_data_map & (1<
489
                "Unallocated index used");
490
 
491
    return self()->thread_data[index];
492
}
493
 
494
inline CYG_ADDRWORD *Cyg_Thread::get_data_ptr( Cyg_Thread::cyg_data_index index )
495
{
496
    CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
497
                "Per thread data index out of bounds");
498
    CYG_ASSERT( (thread_data_map & (1<
499
                "Unallocated index used");
500
 
501
    return &(self()->thread_data[index]);
502
}
503
 
504
inline void Cyg_Thread::set_data( Cyg_Thread::cyg_data_index index,
505
                                  CYG_ADDRWORD data )
506
{
507
    CYG_ASSERT( index < CYGNUM_KERNEL_THREADS_DATA_MAX,
508
                "Per thread data index out of bounds");
509
    CYG_ASSERT( (thread_data_map & (1<
510
                "Unallocated index used");
511
 
512
    thread_data[index] = data;
513
}
514
 
515
#endif
516
 
517
// -------------------------------------------------------------------------
518
 
519
#ifdef CYGVAR_KERNEL_THREADS_NAME
520
 
521
inline char *Cyg_Thread::get_name()
522
{
523
    return name;
524
}
525
 
526
#endif
527
 
528
// -------------------------------------------------------------------------
529
 
530
#ifdef CYGVAR_KERNEL_THREADS_LIST
531
 
532
inline Cyg_Thread *Cyg_Thread::get_list_head()
533
{
534
    return thread_list?thread_list->list_next:0;
535
}
536
 
537
inline Cyg_Thread *Cyg_Thread::get_list_next()
538
{
539
    return (this==thread_list)?0:list_next;
540
}
541
 
542
#endif
543
 
544
 
545
// -------------------------------------------------------------------------
546
 
547
#ifdef CYGPKG_KERNEL_EXCEPTIONS
548
 
549
inline void Cyg_Thread::register_exception(
550
    cyg_code                exception_number,       // exception number
551
    cyg_exception_handler   handler,                // handler function
552
    CYG_ADDRWORD            data,                   // data argument
553
    cyg_exception_handler   **old_handler,          // handler function
554
    CYG_ADDRWORD            *old_data               // data argument
555
    )
556
{
557
    self()->exception_control.register_exception(
558
        exception_number,
559
        handler,
560
        data,
561
        old_handler,
562
        old_data
563
        );
564
}
565
 
566
inline void Cyg_Thread::deregister_exception(
567
    cyg_code                exception_number        // exception number
568
    )
569
{
570
    self()->exception_control.deregister_exception(
571
        exception_number
572
        );
573
}
574
 
575
#endif
576
 
577
//==========================================================================
578
// Inlines for Cyg_ThreadTimer class
579
 
580
// -------------------------------------------------------------------------
581
#if defined(CYGFUN_KERNEL_THREADS_TIMER) && defined(CYGVAR_KERNEL_COUNTERS_CLOCK)
582
 
583
inline Cyg_ThreadTimer::Cyg_ThreadTimer(
584
    Cyg_Thread  *th
585
    )
586
    : Cyg_Alarm(Cyg_Clock::real_time_clock,
587
                &alarm,
588
                CYG_ADDRWORD(this)
589
                )
590
{
591
    thread = th;
592
}
593
 
594
#endif
595
 
596
//==========================================================================
597
// Inlines for Cyg_ThreadQueue class
598
 
599
 
600
inline void Cyg_ThreadQueue::enqueue(Cyg_Thread *thread)
601
{
602
    Cyg_ThreadQueue_Implementation::enqueue(thread);
603
}
604
 
605
// -------------------------------------------------------------------------
606
 
607
inline Cyg_Thread *Cyg_ThreadQueue::highpri()
608
{
609
    return Cyg_ThreadQueue_Implementation::highpri();
610
}
611
 
612
// -------------------------------------------------------------------------
613
 
614
inline Cyg_Thread *Cyg_ThreadQueue::dequeue()
615
{
616
    return Cyg_ThreadQueue_Implementation::dequeue();
617
}
618
 
619
// -------------------------------------------------------------------------
620
 
621
inline void Cyg_ThreadQueue::remove(Cyg_Thread *thread)
622
{
623
    Cyg_ThreadQueue_Implementation::remove(thread);
624
}
625
 
626
// -------------------------------------------------------------------------
627
 
628
inline cyg_bool Cyg_ThreadQueue::empty()
629
{
630
    return Cyg_ThreadQueue_Implementation::empty();
631
}
632
 
633
// -------------------------------------------------------------------------
634
 
635
#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
636
 
637
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
638
# include 
639
#endif
640
 
641
// Add and remove destructors. Returns true on success, false on failure.
642
inline cyg_bool
643
Cyg_Thread::add_destructor( destructor_fn fn, CYG_ADDRWORD data )
644
{
645
    cyg_ucount16 i;
646
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
647
    Cyg_Scheduler::lock();
648
#endif
649
    for (i=0; i
650
        if (NULL == destructors[i].fn) {
651
            destructors[i].data = data;
652
            destructors[i].fn = fn;
653
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
654
            Cyg_Scheduler::unlock();
655
#endif
656
            return true;
657
        }
658
    }
659
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
660
    Cyg_Scheduler::unlock();
661
#endif
662
    return false;
663
}
664
 
665
inline cyg_bool
666
Cyg_Thread::rem_destructor( destructor_fn fn, CYG_ADDRWORD data )
667
{
668
    cyg_ucount16 i;
669
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
670
    Cyg_Scheduler::lock();
671
#endif
672
    for (i=0; i
673
        if (destructors[i].fn == fn && destructors[i].data == data) {
674
            destructors[i].fn = NULL;
675
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
676
            Cyg_Scheduler::unlock();
677
#endif
678
            return true;
679
        }
680
    }
681
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
682
    Cyg_Scheduler::unlock();
683
#endif
684
    return false;
685
}
686
#endif
687
 
688
// -------------------------------------------------------------------------
689
 
690
#endif // ifndef CYGONCE_KERNEL_THREAD_INL
691
// EOF thread.inl

powered by: WebSVN 2.1.0

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