Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 233289 Details for
Bug 276137
=dev-libs/pcl-1.10 bump request
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Test case application for version 1.10 verifying library operation
hilo.c (text/plain), 8.39 KB, created by
Guenther Brunthaler
on 2010-05-28 15:10:47 UTC
(
hide
)
Description:
Test case application for version 1.10 verifying library operation
Filename:
MIME Type:
Creator:
Guenther Brunthaler
Created:
2010-05-28 15:10:47 UTC
Size:
8.39 KB
patch
obsolete
>/* > Test program for Portable Coroutine Library. > > Written in 2009 by Guenther Brunthaler. >*/ > > >#include <stdio.h> >#include <stdlib.h> >#include <math.h> > >/* Get it: wget http://xmailserver.org/pcl-1.6.tar.gz */ >#include <pcl.h> > > >#ifdef GNUC > #define NORETURN __attribute__((noreturn)) >#else > #define NORETURN >#endif > > >/* Type of the coroutine main function expected by co_create(). */ >typedef void (*CO_FUNC_T)(void *); > >/* Parameter passing structure for random-generator coroutine. */ >union prng_arguments { > /* Initialize the pseudo random number generator. */ > union { > struct { > double seed; /* For seeding the generator. */ > } in; > } initialize; > /* For requesting the next random number to be generated. */ > union { > struct { > int min; /* Smallest allowed value for random number. */ > int max; /* Largest allowed value for random number. */ > } in; > struct { > int rnd; /* The generated pseudo random number. */ > } out; > } generate; >}; > >/* Constants used by guesser/solver coroutines. */ >enum {TOO_SMALL, JUST_RIGHT, TOO_LARGE}; > >/* Parameter passing structure for quiz master coroutine. */ >union quizmaster_arguments { > /* Initialization phase. */ > union { > struct { > coroutine_t prng; /* Random number generator coroutine. */ > union prng_arguments *prng_arguments; > coroutine_t candidate; /* Quiz candidate coroutine. */ > union candidate_arguments *candidate_arguments; > } in; > } initialize; > union { > struct { > /* The guess from the candidate. */ > int guess; > } in; > } probe; >}; > >/* Parameter passing structure for quiz candidate coroutine. */ >union candidate_arguments { > /* Initialization phase. */ > union { > struct { > int smallest; /* Lower bound for number to be guessed. */ > int largest; /* Upper bound for number to be guessed. */ > } in; > } initialize; > union { > struct { > int guess; /* Our guess. */ > } out; > struct { > /* What the quiz master tells us. */ > int test_result; > } in; > } evaluate; >}; > > >/* > Stores seed value when called first. > > From then on, yields one pseudo random number per activation. >*/ >static void prng_coroutine(union prng_arguments *xch) { > double const multiplier= 997; > double const displacement= atan2(0, -1); /* Pi! */ > double seed; > seed= xch->initialize.in.seed; > co_resume(); /* Resume caller. */ > for (;;) { > int min, max; > /* Generate next normalized pseudo random number. */ > seed= seed * multiplier + displacement; > seed-= floor(seed); > /* Emit next random number scaled to the desired value range. */ > min= xch->generate.in.min; max= xch->generate.in.max; > xch->generate.out.rnd= min + (int)(seed * (max - min + 1)); > co_resume(); /* Yield result to caller. */ > } >} > > >/* Use a candidate coroutine to solve a quiz generated here. */ >static void quizmaster_coroutine(union quizmaster_arguments *xch) { > int const lower= 1; > int const upper= 1000; > coroutine_t prng= xch->initialize.in.prng; > union prng_arguments *pa= xch->initialize.in.prng_arguments; > coroutine_t candidate= xch->initialize.in.candidate; > union candidate_arguments *ca= xch->initialize.in.candidate_arguments; > int secret; > /* Run an infinite number of games. */ > /* (We want to avoid leaving the coroutine as this would destroy it.) */ > for (;;) { > /* Generate the random number to be guessed. */ > pa->generate.in.min= lower; > pa->generate.in.max= upper; > co_call(prng); > secret= pa->generate.out.rnd; > (void)printf( > "A: Try to guess a number in the range from %d to %d!\n" > , lower, upper > ); > { > /* Tell the candidate the numeric range of the secret number. */ > ca->initialize.in.smallest= lower; > ca->initialize.in.largest= upper; /* Processed on first invocation. */ > /* Iterate until the candidate finds the solution. */ > for (;;) { > /* Request next guess. (Also initialize if first invocation.) */ > co_call(candidate); > if (ca->evaluate.out.guess == secret) { > (void)printf( > "A: Congratulations - %d is the secret number!\n", secret > ); > ca->evaluate.in.test_result= JUST_RIGHT; > co_call(candidate); > break; /* Coroutine will finish execution. */ > } else if (ca->evaluate.out.guess < secret) { > (void)printf("A: %d is too small!\n", ca->evaluate.out.guess); > ca->evaluate.in.test_result= TOO_SMALL; > } else { > (void)printf("A: %d is too large!\n", ca->evaluate.out.guess); > ca->evaluate.in.test_result= TOO_LARGE; > } > } > } > /* Give our primary caller a chance to terminate the series of games. */ > co_resume(); > } >} > > >static void NORETURN die(char const *message) { > (void)fputs("An error has occurred: ", stderr); > (void)fputs(message, stderr); > (void)fputc('\n', stderr); > exit(EXIT_FAILURE); >} > > >/* Let a quizmaster coroutine assess our guesses. */ >static void candidate_coroutine(union candidate_arguments *xch) { > /* Play an infinite number of games. */ > /* (We want to avoid leaving the coroutine as this would destroy it.) */ > for (;;) { > int lower= xch->initialize.in.smallest; > int upper= xch->initialize.in.largest; > int try= 1; > (void)printf( > "Q: OK, so it's a number from %d to %d - let's see!\n" > , lower, upper > ); > for (;;) { > int guess= (lower + upper) / 2; > (void)printf("Q: My guess # %d: What about %d?\n", try, guess); > xch->evaluate.out.guess= guess; > co_resume(); /* Evaluate our query. */ > switch (xch->evaluate.in.test_result) { > case TOO_SMALL: lower= guess + 1; break; > case TOO_LARGE: upper= guess - 1; break; > case JUST_RIGHT: goto won; > default: die("Unrecognized assessment!"); > } > ++try; > } > won: > (void)printf("Q: I knew I would finally guess it!\n"); > co_resume(); /* Give our caller a chance to terminate. */ > } >} > > >/* Mostly a co_create() wrapper with included error checking. */ >static coroutine_t safe_co_create(CO_FUNC_T func, void *data, int stacksize) { > coroutine_t *co; > if (!(co= co_create(func, data, 0, stacksize))) { > die("Could not allocate coroutine resources!"); > } > return co; >} > > >/* Bundled resources for playing a series of games. */ >struct game_arguments { > coroutine_t pco; > union prng_arguments pa; > coroutine_t qco; > union quizmaster_arguments qa; > coroutine_t cco; > union candidate_arguments ca; >}; > > >static void play_game(struct game_arguments *ga) { > /* Set up arguments for quizmaster. */ > ga->qa.initialize.in.prng= ga->pco; > ga->qa.initialize.in.prng_arguments= &ga->pa; > ga->qa.initialize.in.candidate= ga->cco; > ga->qa.initialize.in.candidate_arguments= &ga->ca; > /* > I admit there is no actual reason why quizmaster is a coroutine as it > has only a single exit point. > > However, this is a coroutine test applcation - so let's test! > */ > co_call(ga->qco); /* Run quizmaster coroutine. */ >} > > >int main(int argc, char **argv) { > int const stksz= 0x2000; /* The stack size we use for coroutines. */ > struct game_arguments ga; > int g, num_games; > if ( > argc < 2 || argc > 3 > || sscanf(argv[1], "%lf", &ga.pa.initialize.in.seed) != 1 > || ga.pa.initialize.in.seed <= 0 > || argc < 3 > ? (num_games= 1, 0) > : sscanf(argv[2], "%d", &num_games) != 1 > ) { > printf("Usage: %s <seed> [ <number_of_games> ]\n", argv[0]); > return EXIT_FAILURE; > } > /* Create coroutines. */ > ga.pco= safe_co_create((CO_FUNC_T)prng_coroutine, &ga.pa, stksz); > ga.qco= safe_co_create((CO_FUNC_T)quizmaster_coroutine, &ga.qa, stksz); > ga.cco= safe_co_create((CO_FUNC_T)candidate_coroutine, &ga.ca, stksz); > /* Initialize random number generator. */ > co_call(ga.pco); /* Coroutine initializes itself using the seed value. */ > /* Run the requested number of games. */ > for (g= 1; g <= num_games; ++g) { > if (g > 1) (void)putchar('\n'); > (void)printf("Playing game %d.\n", g); > play_game(&ga); /* Play a single game. */ > } > /* Abort and destroy all coroutines. */ > co_delete(ga.cco); > co_delete(ga.qco); > co_delete(ga.pco); > return EXIT_SUCCESS; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 276137
:
196301
|
196329
|
196330
|
233285
| 233289