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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [bench/] [shootout/] [chameneosredux.c] - Blame information for rev 700

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 700 jeremybenn
/*
2
Redistribution and use in source and binary forms, with or without
3
modification, are permitted provided that the following conditions are met:
4
 
5
    * Redistributions of source code must retain the above copyright
6
    notice, this list of conditions and the following disclaimer.
7
 
8
    * Redistributions in binary form must reproduce the above copyright
9
    notice, this list of conditions and the following disclaimer in the
10
    documentation and/or other materials provided with the distribution.
11
 
12
    * Neither the name of "The Computer Language Benchmarks Game" nor the
13
    name of "The Computer Language Shootout Benchmarks" nor the names of
14
    its contributors may be used to endorse or promote products derived
15
    from this software without specific prior written permission.
16
 
17
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
POSSIBILITY OF SUCH DAMAGE.
28
*/
29
 
30
/* The Computer Language Benchmarks Game
31
   http://shootout.alioth.debian.org/
32
 
33
   contributed by Michael Barker
34
   based on a Java contribution by Luzius Meisser
35
 
36
   convert to C by dualamd
37
*/
38
 
39
#include <stdlib.h>
40
#include <stdio.h>
41
#include <pthread.h>
42
 
43
 
44
enum Colour
45
{
46
   blue      = 0,
47
   red      = 1,
48
   yellow   = 2,
49
   Invalid   = 3
50
};
51
 
52
const char* ColourName[] = {"blue", "red", "yellow"};
53
const int STACK_SIZE   = 32*1024;
54
 
55
typedef unsigned int BOOL;
56
const BOOL TRUE = 1;
57
const BOOL FALSE = 0;
58
 
59
int CreatureID = 0;
60
 
61
 
62
enum Colour doCompliment(enum Colour c1, enum Colour c2)
63
{
64
   switch (c1)
65
   {
66
   case blue:
67
      switch (c2)
68
      {
69
      case blue:
70
         return blue;
71
      case red:
72
         return yellow;
73
      case yellow:
74
         return red;
75
      default:
76
         goto errlb;
77
      }
78
   case red:
79
      switch (c2)
80
      {
81
      case blue:
82
         return yellow;
83
      case red:
84
         return red;
85
      case yellow:
86
         return blue;
87
      default:
88
         goto errlb;
89
      }
90
   case yellow:
91
      switch (c2)
92
      {
93
      case blue:
94
         return red;
95
      case red:
96
         return blue;
97
      case yellow:
98
         return yellow;
99
      default:
100
         goto errlb;
101
      }
102
   default:
103
      break;
104
   }
105
 
106
errlb:
107
   printf("Invalid colour\n");
108
   exit( 1 );
109
}
110
 
111
/* convert integer to number string: 1234 -> "one two three four" */
112
char* formatNumber(int n, char* outbuf)
113
{
114
   int ochar = 0, ichar = 0;
115
   int i;
116
   char tmp[64];
117
 
118
   const char* NUMBERS[] =
119
   {
120
      "zero", "one", "two", "three", "four", "five",
121
      "six", "seven", "eight", "nine"
122
   };
123
 
124
   ichar = sprintf(tmp, "%d", n);
125
 
126
   for (i = 0; i < ichar; i++)
127
      ochar += sprintf( outbuf + ochar, " %s", NUMBERS[ tmp[i] - '0' ] );
128
 
129
   return outbuf;
130
}
131
 
132
 
133
struct MeetingPlace
134
{
135
   pthread_mutex_t   mutex;
136
   int             meetingsLeft;
137
   struct Creature*   firstCreature;
138
};
139
 
140
struct Creature
141
{
142
   pthread_t         ht;
143
   pthread_attr_t      stack_att;
144
 
145
   struct MeetingPlace* place;
146
   int         count;
147
   int         sameCount;
148
 
149
   enum Colour   colour;
150
   int          id;
151
 
152
   BOOL      two_met;
153
   BOOL      sameid;
154
};
155
 
156
 
157
void MeetingPlace_Init(struct MeetingPlace* m, int meetings )
158
{
159
   pthread_mutex_init( &m->mutex, 0 );
160
   m->meetingsLeft = meetings;
161
   m->firstCreature = 0;
162
}
163
 
164
 
165
BOOL Meet( struct Creature* cr)
166
{
167
   BOOL retval = TRUE;
168
 
169
   struct MeetingPlace* mp = cr->place;
170
   pthread_mutex_lock( &(mp->mutex) );
171
 
172
   if ( mp->meetingsLeft > 0 )
173
   {
174
      if ( mp->firstCreature == 0 )
175
      {
176
         cr->two_met = FALSE;
177
         mp->firstCreature = cr;
178
      }
179
      else
180
      {
181
         struct Creature* first;
182
         enum Colour newColour;
183
 
184
         first = mp->firstCreature;
185
         newColour = doCompliment( cr->colour, first->colour );
186
 
187
         cr->sameid = cr->id == first->id;
188
         cr->colour = newColour;
189
         cr->two_met = TRUE;
190
 
191
         first->sameid = cr->sameid;
192
         first->colour = newColour;
193
         first->two_met = TRUE;
194
 
195
         mp->firstCreature = 0;
196
         mp->meetingsLeft--;
197
      }
198
   }
199
   else
200
      retval = FALSE;
201
 
202
   pthread_mutex_unlock( &(mp->mutex) );
203
   return retval;
204
}
205
 
206
 
207
void* CreatureThreadRun(void* param)
208
{
209
   struct Creature* cr = (struct Creature*)param;
210
 
211
   while (TRUE)
212
   {
213
      if ( Meet(cr) )
214
      {
215
         while (cr->two_met == FALSE)
216
            sched_yield();
217
 
218
         if (cr->sameid)
219
            cr->sameCount++;
220
         cr->count++;
221
      }
222
      else
223
         break;
224
   }
225
 
226
   return 0;
227
}
228
 
229
void Creature_Init( struct Creature *cr, struct MeetingPlace* place, enum Colour colour )
230
{
231
   cr->place = place;
232
   cr->count = cr->sameCount = 0;
233
 
234
   cr->id = ++CreatureID;
235
   cr->colour = colour;
236
   cr->two_met = FALSE;
237
 
238
   pthread_attr_init( &cr->stack_att );
239
   pthread_attr_setstacksize( &cr->stack_att, STACK_SIZE );
240
   pthread_create( &cr->ht, &cr->stack_att, &CreatureThreadRun, (void*)(cr) );
241
}
242
 
243
/* format meeting times of each creature to string */
244
char* Creature_getResult(struct Creature* cr, char* str)
245
{
246
   char numstr[256];
247
   formatNumber(cr->sameCount, numstr);
248
 
249
   sprintf( str, "%u%s", cr->count, numstr );
250
   return str;
251
}
252
 
253
 
254
void runGame( int n_meeting, int ncolor, const enum Colour* colours )
255
{
256
   int i;
257
   int total = 0;
258
   char str[256];
259
 
260
   struct MeetingPlace place;
261
   struct Creature *creatures = (struct Creature*) calloc( ncolor, sizeof(struct Creature) );
262
 
263
   MeetingPlace_Init( &place, n_meeting );
264
 
265
   /* print initial color of each creature */
266
   for (i = 0; i < ncolor; i++)
267
   {
268
      printf( "%s ", ColourName[ colours[i] ] );
269
      Creature_Init( &(creatures[i]), &place, colours[i] );
270
   }
271
   printf("\n");
272
 
273
   /* wait for them to meet */
274
   for (i = 0; i < ncolor; i++)
275
      pthread_join( creatures[i].ht, 0 );
276
 
277
   /* print meeting times of each creature */
278
   for (i = 0; i < ncolor; i++)
279
   {
280
      printf( "%s\n", Creature_getResult(&(creatures[i]), str) );
281
      total += creatures[i].count;
282
   }
283
 
284
   /* print total meeting times, should equal n_meeting */
285
   printf( "%s\n\n", formatNumber(total, str) );
286
 
287
   /* cleaup & quit */
288
   pthread_mutex_destroy( &place.mutex );
289
   free( creatures );
290
}
291
 
292
 
293
void printColours( enum Colour c1, enum Colour c2 )
294
{
295
   printf( "%s + %s -> %s\n",
296
      ColourName[c1],
297
      ColourName[c2],
298
      ColourName[doCompliment(c1, c2)]   );
299
}
300
 
301
void printColoursTable(void)
302
{
303
   printColours(blue, blue);
304
   printColours(blue, red);
305
   printColours(blue, yellow);
306
   printColours(red, blue);
307
   printColours(red, red);
308
   printColours(red, yellow);
309
   printColours(yellow, blue);
310
   printColours(yellow, red);
311
   printColours(yellow, yellow);
312
}
313
 
314
int main(int argc, char** argv)
315
{
316
   int n = (argc == 2) ? atoi(argv[1]) : 600;
317
 
318
   printColoursTable();
319
   printf("\n");
320
 
321
   const enum Colour r1[] = {   blue, red, yellow   };
322
   const enum Colour r2[] = {   blue, red, yellow,
323
               red, yellow, blue,
324
               red, yellow, red, blue   };
325
 
326
   runGame( n, sizeof(r1) / sizeof(r1[0]), r1 );
327
   runGame( n, sizeof(r2) / sizeof(r2[0]), r2 );
328
 
329
   return 0;
330
}

powered by: WebSVN 2.1.0

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