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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [kernel/] [current/] [tests/] [philo.cxx] - Blame information for rev 838

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

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//        philo.cxx
4
//
5
//        A test of the dining philosophers problem
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
//==========================================================================
40
//#####DESCRIPTIONBEGIN####
41
//
42
// Author(s):     dsm
43
// Contributors:    dsm
44
// Date:          1998-02-24
45
// Description:   A test of the dining philosophers problem
46
//####DESCRIPTIONEND####
47
// 
48
 
49
#include <cyg/kernel/kernel.hxx>
50
 
51
#include <cyg/hal/hal_io.h>
52
 
53
// -------------------------------------------------------------------------
54
// Data for the philosophers problem
55
 
56
#define PHILOSOPHERS    15              // number of philosophers
57
#define STACKSIZE       (2*1024)        // size of thread stack
58
 
59
#define NTHREADS PHILOSOPHERS
60
#include "testaux.hxx"
61
 
62
// array of chopsticks
63
Cyg_Binary_Semaphore chopstick[PHILOSOPHERS];
64
 
65
 
66
//cyg_thread_entry Philosopher;
67
 
68
// -------------------------------------------------------------------------
69
// State recording and display
70
 
71
static char pstate[PHILOSOPHERS+1];     // state vector showing what each
72
                                        // philosopher is doing
73
 
74
Cyg_Mutex state_mutex;
75
 
76
#ifdef CYG_HAL_MN10300_MN103002
77
static cyg_count8 eaters = 0;
78
#endif
79
 
80
void change_state(int id, char newstate)
81
{
82
    CYG_INSTRUMENT_USER( 1, 0, 0);
83
    state_mutex.lock();
84
    CYG_INSTRUMENT_USER( 2, 0, 0);
85
 
86
#ifdef CYG_HAL_MN10300_MN103002
87
    if( pstate[id] == 'E' ) eaters--;
88
    if( newstate == 'E' ) eaters++;
89
//    led(eaters);
90
#endif
91
 
92
    pstate[id] = newstate;
93
 
94
    diag_write_string(pstate);
95
#if 0
96
    diag_write_char(' ');
97
    diag_write_dec(Cyg_Scheduler::get_thread_switches());
98
#endif    
99
    diag_write_char('\n');
100
 
101
    CYG_INSTRUMENT_USER( 3, 0, 0);
102
    state_mutex.unlock();
103
    CYG_INSTRUMENT_USER( 4, 0, 0);
104
 
105
}
106
 
107
char get_state( int id)
108
{
109
    state_mutex.lock();
110
 
111
    char s = pstate[id];
112
 
113
    state_mutex.unlock();
114
 
115
    return s;
116
}
117
 
118
// -------------------------------------------------------------------------
119
// Thread to behave like a philosopher
120
 
121
void Philosopher( CYG_ADDRESS id )
122
{
123
    Cyg_Thread *self = Cyg_Thread::self();
124
    Cyg_Binary_Semaphore *first_stick = &chopstick[id];
125
    Cyg_Binary_Semaphore *second_stick = &chopstick[(id+1)%PHILOSOPHERS];
126
#ifdef CYGPKG_INFRA_DEBUG
127
    int left_philo = ((id==0)?PHILOSOPHERS:id)-1;
128
    int right_philo = (id==PHILOSOPHERS-1)?0:(id+1);
129
#endif
130
 
131
    CYG_ASSERT( id >= 0 && id < PHILOSOPHERS, "Bad id");
132
 
133
    // Deadlock avoidance. The easiest way to make the philosophers
134
    // behave is to make each pick up the lowest numbered stick
135
    // first. This is how it works out anyway for all the philosophers
136
    // except the last, who must have his sticks swapped.
137
 
138
    if( id == PHILOSOPHERS-1 )
139
    {
140
        Cyg_Binary_Semaphore *t = first_stick;
141
        first_stick = second_stick;
142
        second_stick = t;
143
    }
144
 
145
    // The following variable is shared by all philosophers.
146
    // It is incremented unprotected, but this does not matter
147
    // since it is only present to introduce a little variability
148
    // into the think and eat times.
149
 
150
    static int cycle = 0;
151
 
152
    for(;;)
153
    {
154
        // Think for a bit
155
 
156
        self->delay((id+cycle++)%12);    // Cogito ergo sum...
157
 
158
        // I am now hungry, try to get the chopsticks
159
 
160
        change_state(id,'H');
161
 
162
        // Get the first stick
163
    CYG_INSTRUMENT_USER( 5, 0, 0);
164
        first_stick->wait();
165
    CYG_INSTRUMENT_USER( 6, 0, 0);
166
 
167
        // Get the second stick
168
    CYG_INSTRUMENT_USER( 7, 0, 0);
169
        second_stick->wait();
170
    CYG_INSTRUMENT_USER( 8, 0, 0);
171
 
172
        // Got them, now eat
173
 
174
        change_state(id,'E');
175
 
176
        // Check that the world is as I think it is...
177
        CYG_ASSERT( !first_stick->posted(), "Not got first stick");
178
        CYG_ASSERT( !second_stick->posted(), "Not got second stick");
179
        CYG_ASSERT( get_state(left_philo) != 'E', "Left neighbour also eating!!");
180
        CYG_ASSERT( get_state(right_philo) != 'E', "Right neighbour also eating!!");
181
 
182
        self->delay((id+cycle++)%6);    // munch munch
183
 
184
        // Finished eating, put down sticks.
185
 
186
        change_state(id,'T');
187
 
188
    CYG_INSTRUMENT_USER( 9, 0, 0);
189
        first_stick->post();
190
    CYG_INSTRUMENT_USER( 10, 0, 0);
191
        second_stick->post();
192
    CYG_INSTRUMENT_USER( 11, 0, 0);
193
 
194
//    Cyg_Scheduler::lock();
195
//    Cyg_Scheduler::unlock();
196
    CYG_INSTRUMENT_USER( 12, 0, 0);
197
 
198
    }
199
}
200
 
201
// -------------------------------------------------------------------------
202
 
203
externC void
204
cyg_start( void )
205
{
206
#ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG
207
    cyg_hal_invoke_constructors();
208
#endif
209
    diag_init();
210
 
211
    diag_write_string("Philosophers\n");
212
    diag_write_string("Started\n");
213
 
214
    // Zero last element in state so it acts like
215
    // a string.
216
    pstate[PHILOSOPHERS] = 0;
217
 
218
#if 1
219
    for( int i = 0; i < PHILOSOPHERS; i++ )
220
    {
221
        change_state(i,'T');            // starting state
222
 
223
        // Start the philosopher
224
        Cyg_Thread *t = new_thread( Philosopher, i );
225
 
226
        // resume it
227
        t->resume();
228
 
229
        // and make the matching chopstick present
230
        chopstick[i].post();
231
    }
232
#endif
233
 
234
    // Get the world going
235
    Cyg_Scheduler::scheduler.start();
236
 
237
}
238
 
239
// -------------------------------------------------------------------------
240
// EOF philo.cxx

powered by: WebSVN 2.1.0

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