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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
#ifndef CYGONCE_KERNEL_THREAD_HXX
2
#define CYGONCE_KERNEL_THREAD_HXX
3
 
4
//==========================================================================
5
//
6
//      thread.hxx
7
//
8
//      Thread class declarations
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 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 Thread class interfaces
49
// Description: The classes defined here collectively implement the
50
//              internal API used to create, configure and manage threads.
51
// Usage:       #include 
52
//
53
//####DESCRIPTIONEND####
54
//
55
//==========================================================================
56
 
57
#include 
58
#include          // assertion macros
59
#include 
60
#include 
61
#include 
62
 
63
#include 
64
 
65
// -------------------------------------------------------------------------
66
// Miscellaneous types
67
 
68
typedef void cyg_thread_entry(CYG_ADDRWORD data);// Thread entry point function
69
 
70
// -------------------------------------------------------------------------
71
// Hardware thread interface.
72
// The implementation of this class is provided by the HAL.
73
 
74
class Cyg_HardwareThread
75
{
76
    friend class Cyg_Scheduler;
77
 
78
protected:
79
 
80
    CYG_ADDRESS         stack_base;     // pointer to base of stack area
81
 
82
    cyg_uint32          stack_size;     // size of stack area in bytes
83
 
84
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
85
    CYG_ADDRESS         stack_limit;    // movable stack limit
86
#endif
87
 
88
    CYG_ADDRESS         stack_ptr;      // pointer to saved state on stack
89
 
90
    cyg_thread_entry    *entry_point;   // main entry point (code pointer!)
91
 
92
    CYG_ADDRWORD        entry_data;     // entry point argument
93
 
94
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
95
 
96
    HAL_SavedRegisters  *saved_context; // If non-zero, this points at a more
97
                                        // interesting context than stack_ptr.
98
#endif
99
 
100
    Cyg_HardwareThread(
101
        cyg_thread_entry        *entry_point,   // entry point function
102
        CYG_ADDRWORD            entry_data,     // entry data
103
        cyg_ucount32            stack_size = 0, // stack size, 0 = use default
104
        CYG_ADDRESS             stack_base = 0  // stack base, NULL = allocate
105
    );
106
 
107
    // Thread entry point. This is where all threads begin execution.
108
    // This routine does a little housekeeping and then call the main
109
    // entry_point specified above.
110
    static void thread_entry(Cyg_Thread *thread);
111
 
112
    // Initialize the context of the thread to start execution at thread_entry
113
    void    init_context( Cyg_Thread *thread );
114
 
115
    // Save current thread's context and load that of the given next thread.
116
    void    switch_context(Cyg_HardwareThread *next);
117
 
118
    // attach a stack to this thread
119
    void    attach_stack(CYG_ADDRESS stack, cyg_uint32 stack_size);
120
 
121
    // detach the stack from this thread
122
    CYG_ADDRESS detach_stack();
123
 
124
    // Adjust the thread's saved state to call the exception
125
    // handler when next executed.
126
    void    prepare_exception (
127
        cyg_exception_handler   *exception_handler,
128
        CYG_ADDRWORD            exception_data,
129
        cyg_code                exception_number,
130
        CYG_ADDRWORD            exception_info
131
        );
132
 
133
public:
134
 
135
    CYGDBG_DEFINE_CHECK_THIS
136
 
137
    // Get and set entry_data.
138
 
139
    void set_entry_data( CYG_ADDRWORD data );
140
 
141
    CYG_ADDRWORD get_entry_data();
142
 
143
#ifdef CYGDBG_KERNEL_DEBUG_GDB_THREAD_SUPPORT
144
    // Return the current saved state for this thread.
145
    HAL_SavedRegisters *get_saved_context();
146
 
147
    // Set the saved context pointer.
148
    void set_saved_context(HAL_SavedRegisters *ctx);
149
#endif
150
 
151
    // get the size/base of this thread's stack
152
    CYG_ADDRESS get_stack_base();
153
 
154
    cyg_uint32 get_stack_size();
155
 
156
#ifdef CYGFUN_KERNEL_THREADS_STACK_LIMIT
157
    // Allocate some memory at the lower end of the stack
158
    // by moving the stack limit pointer.
159
 
160
    void *increment_stack_limit( cyg_ucount32 size);
161
 
162
    CYG_ADDRESS get_stack_limit();
163
#endif
164
 
165
#ifdef CYGFUN_KERNEL_THREADS_STACK_CHECKING
166
 
167
    inline void check_stack(void);
168
 
169
#endif
170
#ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
171
 
172
    inline cyg_uint32 measure_stack_usage(void);
173
 
174
#endif
175
};
176
 
177
// -------------------------------------------------------------------------
178
// Per-thread timer support class.
179
// This is only included when required.
180
 
181
#ifdef CYGFUN_KERNEL_THREADS_TIMER
182
 
183
class Cyg_ThreadTimer
184
    : public Cyg_Alarm
185
{
186
    friend class Cyg_Thread;
187
 
188
    // Pointer to current thread
189
    Cyg_Thread          *thread;
190
 
191
    // Constructor
192
    Cyg_ThreadTimer(
193
        Cyg_Thread      *thread
194
        );
195
 
196
    // Alarm function
197
    static void alarm( Cyg_Alarm *alarm, CYG_ADDRWORD data);
198
 
199
    CYGDBG_DEFINE_CHECK_THIS
200
 
201
};
202
 
203
#endif
204
 
205
// -------------------------------------------------------------------------
206
// Main Thread class.
207
// This provides the public API for controlling threads.
208
 
209
class Cyg_Thread
210
    : public Cyg_HardwareThread,       // provides hardware abstractions
211
      public Cyg_SchedThread           // provides scheduling abstractions
212
{
213
    friend class Cyg_Scheduler;
214
    friend void deliver_exception( CYG_WORD code, CYG_ADDRWORD data );
215
 
216
    // The following definitions are used by all variants of the
217
    // basic thread object.
218
 
219
public:
220
    enum {                       // Thread state values
221
 
222
        RUNNING    = 0,          // Thread is runnable or running
223
        SLEEPING   = 1,          // Thread is waiting for something to happen
224
        COUNTSLEEP = 2,          // Sleep in counted manner
225
        SUSPENDED  = 4,          // Suspend count is non-zero
226
        CREATING   = 8,          // Thread is being created
227
        EXITED     = 16,         // Thread has exited
228
 
229
        // This is the set of bits that must be cleared by a generic
230
        // wake() or release().
231
        SLEEPSET   = (SLEEPING | COUNTSLEEP)
232
    };
233
 
234
private:
235
    // Current thread state, a logical OR of the above values.
236
    // Only if this word is zero can the thread execute.
237
    cyg_uint32                  state;
238
 
239
    // Suspension counter, if > 0, the thread is suspended
240
    cyg_ucount32                suspend_count;
241
 
242
    // Wakeup counter, if > 0, sleep will not sleep, just decrement
243
    cyg_ucount32                wakeup_count;
244
 
245
    // A word of data used in syncronization object to communicate
246
    // information between sleepers and wakers.
247
    CYG_ADDRWORD                wait_info;
248
 
249
    // Unique thread id assigned on creation
250
    cyg_uint16                  unique_id;
251
 
252
#ifdef CYGPKG_KERNEL_EXCEPTIONS
253
 
254
    // If exceptions are supported, define an exception control
255
    // object that will be used to manage and deliver them. If
256
    // exceptions are global there is a single static instance
257
    // of this object, if they are per-thread then there is one
258
    // for each thread.
259
private:
260
 
261
#ifdef CYGSEM_KERNEL_EXCEPTIONS_GLOBAL
262
    static
263
#endif
264
    Cyg_Exception_Control       exception_control;
265
 
266
public:
267
 
268
    static void register_exception(
269
        cyg_code                exception_number,       // exception number
270
        cyg_exception_handler   handler,                // handler function
271
        CYG_ADDRWORD            data,                   // data argument
272
        cyg_exception_handler   **old_handler,          // handler function
273
        CYG_ADDRWORD            *old_data               // data argument
274
        );
275
 
276
    static void deregister_exception(
277
        cyg_code                exception_number        // exception number
278
        );
279
 
280
    void deliver_exception(
281
        cyg_code            exception_number,       // exception being raised
282
        CYG_ADDRWORD        exception_info          // exception specific info
283
        );
284
 
285
#endif
286
 
287
 
288
public:
289
 
290
    CYGDBG_DEFINE_CHECK_THIS
291
 
292
    // Constructor, Initialize the thread structure. The thread is
293
    // created in suspended state, and needs to be resumed to execute.
294
    // It is also started at some (configurable) default priority, which
295
    // may need to be changed before calling resume.
296
 
297
    Cyg_Thread (
298
        cyg_thread_entry        *entry,         // entry point function
299
        CYG_ADDRWORD            entry_data,     // entry data
300
        cyg_ucount32            stack_size = 0, // stack size, 0 = use default
301
        CYG_ADDRESS             stack_base = 0  // stack base, NULL = allocate
302
        );
303
 
304
    Cyg_Thread (
305
        CYG_ADDRWORD            sched_info,     // Scheduling parameter(s)
306
        cyg_thread_entry        *entry,         // entry point function
307
        CYG_ADDRWORD            entry_data,     // entry data
308
        char                    *name,          // thread name
309
        CYG_ADDRESS             stack_base = 0, // stack base, NULL = allocate
310
        cyg_ucount32            stack_size = 0  // stack size, 0 = use default
311
        );
312
 
313
    // Re-initialize the thread back to it's initial state.
314
    void reinitialize();
315
 
316
    ~Cyg_Thread();
317
 
318
    // The following are invoked implicitly on the current thread,
319
    // hence they are static member functions.
320
 
321
    static void         sleep();        // Put thread to sleep
322
 
323
    static void         counted_sleep();// Decrement counter or put
324
                                        // thread to sleep
325
#ifdef CYGFUN_KERNEL_THREADS_TIMER
326
    static void         counted_sleep( cyg_tick_count delay );
327
                                        // ...for delay ticks
328
#endif
329
 
330
    static void         exit();         // Terminate thread
331
 
332
    static void         yield();        // Yield CPU to another thread
333
 
334
    static void         rotate_queue( cyg_priority pri );
335
                                        // Rotate that run queue
336
 
337
    void                to_queue_head( void );
338
                                        // Move to the head of its queue
339
                                        // (not necessarily a scheduler q)
340
 
341
    static Cyg_Thread   *self();        // Return current thread
342
 
343
 
344
    // The following are called on threads other than the current one.
345
 
346
    void                wake();         // Wake this thread from sleep.
347
 
348
    void                counted_wake(); // Increment counter or wake thread
349
    cyg_uint32          cancel_counted_wake();
350
                                        // Cancel counted wakeups for this
351
                                        // thread and return how many were
352
                                        // pending
353
 
354
    void                suspend();      // Suspend this thread: increment counter and
355
                                        // deschedule.
356
 
357
    void                resume();       // Resume this thread: decrement counter and
358
                                        // reschedule if counter is zero.
359
 
360
    void                release();      // Release thread from sleep with BREAK
361
                                        // wake_reason.
362
 
363
    void                kill();         // Kill this thread
364
 
365
    void                force_resume(); // Resume this thread: set counter to zero.
366
 
367
    cyg_uint32          get_state();    // Return current thread state.
368
 
369
 
370
    // Accessor functions to set and get wait_info.
371
 
372
    void                set_wait_info(CYG_ADDRWORD data);
373
 
374
    CYG_ADDRWORD        get_wait_info();
375
 
376
    // This part of the API is used if we have a clock and want
377
    // per-thread timers for doing delays and timeouts.
378
 
379
    // delay the given number of ticks
380
    void delay( cyg_tick_count delay );
381
 
382
 
383
    enum cyg_reason                     // sleep/wakeup reason codes
384
    {
385
        NONE,                           // No recorded reason
386
        WAIT,                           // Wait with no timeout
387
        DELAY,                          // Simple time delay
388
        TIMEOUT,                        // Wait with timeout/timeout expired
389
        BREAK,                          // forced break out of sleep
390
        DESTRUCT,                       // wait object destroyed[note]
391
        EXIT,                           // forced termination
392
        DONE                            // Wait/delay complete
393
    };
394
    // [note] NOT the thread, some object it was waiting on.
395
    //        Thread destruction would first involve EXITing it.
396
 
397
private:
398
 
399
#ifdef CYGFUN_KERNEL_THREADS_TIMER
400
    Cyg_ThreadTimer     timer;          // per-thread timer
401
#endif
402
 
403
    cyg_reason          sleep_reason;   // reason for sleeping
404
 
405
    cyg_reason          wake_reason;    // reason for waking
406
 
407
#ifdef CYGIMP_THREAD_PRIORITY
408
 
409
public:
410
 
411
    // If the scheduler implements priorities, provide
412
    // functions to set and get it.
413
 
414
    void set_priority( cyg_priority pri );
415
 
416
    cyg_priority get_priority();
417
 
418
    // This returns the current dispatching priority of the
419
    // thread. This may differ from the result of get_priority()
420
    // in the presence of priority inheritance or certain
421
    // scheduling algorithms.
422
    cyg_priority get_current_priority();
423
 
424
#endif
425
 
426
#ifdef CYGVAR_KERNEL_THREADS_DATA
427
 
428
private:
429
    // Array of single word entries for each index.
430
    CYG_ADDRWORD        thread_data[CYGNUM_KERNEL_THREADS_DATA_MAX];
431
 
432
    // Map of free thread_data indexes. Each bit represents an index
433
    // and is 1 if that index is free, and 0 if it is in use.
434
    static cyg_ucount32        thread_data_map;
435
 
436
public:
437
 
438
    typedef cyg_count32 cyg_data_index;
439
 
440
    static CYG_ADDRWORD get_data( cyg_data_index index );
441
 
442
    static CYG_ADDRWORD *get_data_ptr( cyg_data_index index );
443
 
444
    void                set_data( cyg_data_index index, CYG_ADDRWORD data );
445
 
446
    // returns -1 if no more indexes available
447
    static cyg_data_index new_data_index();
448
 
449
    static void         free_data_index( cyg_data_index index );
450
 
451
#endif
452
 
453
#ifdef CYGPKG_KERNEL_THREADS_DESTRUCTORS
454
 
455
    // thread destructors, called on thread exit.
456
private:
457
    typedef void (*destructor_fn)(CYG_ADDRWORD);
458
    struct Cyg_Destructor_Entry {
459
        destructor_fn fn;
460
        CYG_ADDRWORD data;
461
    };
462
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
463
    static
464
#endif
465
    Cyg_Destructor_Entry destructors[ CYGNUM_KERNEL_THREADS_DESTRUCTORS ];
466
public:
467
 
468
    // Add and remove destructors. Returns true on success, false on failure.
469
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
470
    static
471
#endif
472
    cyg_bool     add_destructor( destructor_fn fn, CYG_ADDRWORD data );
473
#ifndef CYGSEM_KERNEL_THREADS_DESTRUCTORS_PER_THREAD
474
    static
475
#endif
476
    cyg_bool     rem_destructor( destructor_fn fn, CYG_ADDRWORD data );
477
#endif
478
 
479
#ifdef CYGVAR_KERNEL_THREADS_NAME
480
 
481
private:
482
    // An optional thread name string, for humans to read
483
    char                        *name;
484
 
485
public:
486
    // function to get the name string
487
    char                        *get_name();
488
 
489
#endif
490
 
491
 
492
#ifdef CYGVAR_KERNEL_THREADS_LIST
493
 
494
        // Housekeeping list that tracks all threads
495
private:
496
    Cyg_Thread                  *list_next;
497
    static Cyg_Thread           *thread_list;
498
 
499
    void                        add_to_list(      void );
500
    void                        remove_from_list( void );
501
public:
502
 
503
    static Cyg_Thread           *get_list_head();
504
 
505
    Cyg_Thread                  *get_list_next();
506
 
507
#endif
508
 
509
public:
510
 
511
    // Set sleep reason to reason and wake reason to NONE
512
    static void set_sleep_reason( cyg_reason reason = WAIT);
513
 
514
    cyg_reason get_sleep_reason();
515
 
516
    // Set the wakeup reason to the given value
517
    void set_wake_reason( cyg_reason reason = DONE);
518
 
519
    // Get current wake reason
520
    cyg_reason get_wake_reason();
521
 
522
    static void set_timer(              // Set timeout and sleep reason
523
        cyg_tick_count  trigger,        // Absolute wakeup time
524
        cyg_reason      sleep_reason    // reason for sleeping
525
        );
526
 
527
    static void clear_timer();          // disable thread timer
528
 
529
    // Get a 16 bit unique id for this thread. This is
530
    // used in tracing and instrumentation to identify the
531
    // current thread.
532
 
533
    cyg_uint16 get_unique_id();
534
 
535
};
536
 
537
// -------------------------------------------------------------------------
538
// Thread Queue class.
539
// This defines the main API for manipulating queues of threads.
540
 
541
class Cyg_ThreadQueue
542
    : public Cyg_ThreadQueue_Implementation
543
{
544
 
545
public:
546
 
547
    CYGDBG_DEFINE_CHECK_THIS
548
 
549
    // API used by rest of kernel.
550
 
551
                        // Add thread to queue
552
    void                enqueue(Cyg_Thread *thread);
553
 
554
                        // return first thread on queue
555
    Cyg_Thread          *highpri();
556
 
557
                        // remove first thread on queue
558
    Cyg_Thread          *dequeue();
559
 
560
                        // remove specified thread from queue
561
    void                remove(Cyg_Thread *thread);
562
 
563
                        // test if queue is empty
564
    inline cyg_bool     empty();
565
 
566
};
567
 
568
// -------------------------------------------------------------------------
569
// Thread inlines
570
 
571
// Return current thread state.
572
inline cyg_uint32 Cyg_Thread::get_state()
573
{
574
    return state;
575
}
576
 
577
inline void Cyg_Thread::set_wait_info(CYG_ADDRWORD data)
578
{
579
    wait_info = data;
580
}
581
 
582
inline CYG_ADDRWORD Cyg_Thread::get_wait_info()
583
{
584
    return wait_info;
585
}
586
 
587
// -------------------------------------------------------------------------
588
#endif // ifndef CYGONCE_KERNEL_THREAD_HXX
589
// EOF thread.hxx

powered by: WebSVN 2.1.0

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