Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / gcc / testsuite / go.test / test / bench / chameneosredux.c
blobed78c31d7ba09a80430eed112021c81cb6d57548
1 /*
2 Redistribution and use in source and binary forms, with or without
3 modification, are permitted provided that the following conditions are met:
5 * Redistributions of source code must retain the above copyright
6 notice, this list of conditions and the following disclaimer.
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.
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.
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.
30 /* The Computer Language Benchmarks Game
31 http://shootout.alioth.debian.org/
33 contributed by Michael Barker
34 based on a Java contribution by Luzius Meisser
36 convert to C by dualamd
39 #include <stdlib.h>
40 #include <stdio.h>
41 #include <pthread.h>
44 enum Colour
46 blue = 0,
47 red = 1,
48 yellow = 2,
49 Invalid = 3
52 const char* ColourName[] = {"blue", "red", "yellow"};
53 const int STACK_SIZE = 32*1024;
55 typedef unsigned int BOOL;
56 const BOOL TRUE = 1;
57 const BOOL FALSE = 0;
59 int CreatureID = 0;
62 enum Colour doCompliment(enum Colour c1, enum Colour c2)
64 switch (c1)
66 case blue:
67 switch (c2)
69 case blue:
70 return blue;
71 case red:
72 return yellow;
73 case yellow:
74 return red;
75 default:
76 goto errlb;
78 case red:
79 switch (c2)
81 case blue:
82 return yellow;
83 case red:
84 return red;
85 case yellow:
86 return blue;
87 default:
88 goto errlb;
90 case yellow:
91 switch (c2)
93 case blue:
94 return red;
95 case red:
96 return blue;
97 case yellow:
98 return yellow;
99 default:
100 goto errlb;
102 default:
103 break;
106 errlb:
107 printf("Invalid colour\n");
108 exit( 1 );
111 /* convert integer to number string: 1234 -> "one two three four" */
112 char* formatNumber(int n, char* outbuf)
114 int ochar = 0, ichar = 0;
115 int i;
116 char tmp[64];
118 const char* NUMBERS[] =
120 "zero", "one", "two", "three", "four", "five",
121 "six", "seven", "eight", "nine"
124 ichar = sprintf(tmp, "%d", n);
126 for (i = 0; i < ichar; i++)
127 ochar += sprintf( outbuf + ochar, " %s", NUMBERS[ tmp[i] - '0' ] );
129 return outbuf;
133 struct MeetingPlace
135 pthread_mutex_t mutex;
136 int meetingsLeft;
137 struct Creature* firstCreature;
140 struct Creature
142 pthread_t ht;
143 pthread_attr_t stack_att;
145 struct MeetingPlace* place;
146 int count;
147 int sameCount;
149 enum Colour colour;
150 int id;
152 BOOL two_met;
153 BOOL sameid;
157 void MeetingPlace_Init(struct MeetingPlace* m, int meetings )
159 pthread_mutex_init( &m->mutex, 0 );
160 m->meetingsLeft = meetings;
161 m->firstCreature = 0;
165 BOOL Meet( struct Creature* cr)
167 BOOL retval = TRUE;
169 struct MeetingPlace* mp = cr->place;
170 pthread_mutex_lock( &(mp->mutex) );
172 if ( mp->meetingsLeft > 0 )
174 if ( mp->firstCreature == 0 )
176 cr->two_met = FALSE;
177 mp->firstCreature = cr;
179 else
181 struct Creature* first;
182 enum Colour newColour;
184 first = mp->firstCreature;
185 newColour = doCompliment( cr->colour, first->colour );
187 cr->sameid = cr->id == first->id;
188 cr->colour = newColour;
189 cr->two_met = TRUE;
191 first->sameid = cr->sameid;
192 first->colour = newColour;
193 first->two_met = TRUE;
195 mp->firstCreature = 0;
196 mp->meetingsLeft--;
199 else
200 retval = FALSE;
202 pthread_mutex_unlock( &(mp->mutex) );
203 return retval;
207 void* CreatureThreadRun(void* param)
209 struct Creature* cr = (struct Creature*)param;
211 while (TRUE)
213 if ( Meet(cr) )
215 while (cr->two_met == FALSE)
216 sched_yield();
218 if (cr->sameid)
219 cr->sameCount++;
220 cr->count++;
222 else
223 break;
226 return 0;
229 void Creature_Init( struct Creature *cr, struct MeetingPlace* place, enum Colour colour )
231 cr->place = place;
232 cr->count = cr->sameCount = 0;
234 cr->id = ++CreatureID;
235 cr->colour = colour;
236 cr->two_met = FALSE;
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) );
243 /* format meeting times of each creature to string */
244 char* Creature_getResult(struct Creature* cr, char* str)
246 char numstr[256];
247 formatNumber(cr->sameCount, numstr);
249 sprintf( str, "%u%s", cr->count, numstr );
250 return str;
254 void runGame( int n_meeting, int ncolor, const enum Colour* colours )
256 int i;
257 int total = 0;
258 char str[256];
260 struct MeetingPlace place;
261 struct Creature *creatures = (struct Creature*) calloc( ncolor, sizeof(struct Creature) );
263 MeetingPlace_Init( &place, n_meeting );
265 /* print initial color of each creature */
266 for (i = 0; i < ncolor; i++)
268 printf( "%s ", ColourName[ colours[i] ] );
269 Creature_Init( &(creatures[i]), &place, colours[i] );
271 printf("\n");
273 /* wait for them to meet */
274 for (i = 0; i < ncolor; i++)
275 pthread_join( creatures[i].ht, 0 );
277 /* print meeting times of each creature */
278 for (i = 0; i < ncolor; i++)
280 printf( "%s\n", Creature_getResult(&(creatures[i]), str) );
281 total += creatures[i].count;
284 /* print total meeting times, should equal n_meeting */
285 printf( "%s\n\n", formatNumber(total, str) );
287 /* cleaup & quit */
288 pthread_mutex_destroy( &place.mutex );
289 free( creatures );
293 void printColours( enum Colour c1, enum Colour c2 )
295 printf( "%s + %s -> %s\n",
296 ColourName[c1],
297 ColourName[c2],
298 ColourName[doCompliment(c1, c2)] );
301 void printColoursTable(void)
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);
314 int main(int argc, char** argv)
316 int n = (argc == 2) ? atoi(argv[1]) : 600;
318 printColoursTable();
319 printf("\n");
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 };
326 runGame( n, sizeof(r1) / sizeof(r1[0]), r1 );
327 runGame( n, sizeof(r2) / sizeof(r2[0]), r2 );
329 return 0;