diff options
-rw-r--r-- | doc/SystemTap_Tapset_Reference/tapsets.tmpl | 7 | ||||
-rw-r--r-- | runtime/arith.c | 24 | ||||
-rw-r--r-- | tapset/random.stp | 14 | ||||
-rw-r--r-- | testsuite/systemtap.base/rand.exp | 3 | ||||
-rw-r--r-- | testsuite/systemtap.base/rand.stp | 19 |
5 files changed, 59 insertions, 8 deletions
diff --git a/doc/SystemTap_Tapset_Reference/tapsets.tmpl b/doc/SystemTap_Tapset_Reference/tapsets.tmpl index fcfb1e85..99f72727 100644 --- a/doc/SystemTap_Tapset_Reference/tapsets.tmpl +++ b/doc/SystemTap_Tapset_Reference/tapsets.tmpl @@ -214,4 +214,11 @@ </para> !Itapset/logging.stp </chapter> + <chapter id="random.stp"> + <title>Random functions Tapset</title> + <para> + These functions deal with random number generation. + </para> +!Itapset/random.stp + </chapter> </book> diff --git a/runtime/arith.c b/runtime/arith.c index d1d0da29..4c818a76 100644 --- a/runtime/arith.c +++ b/runtime/arith.c @@ -84,26 +84,34 @@ static int64_t _stp_mod64 (const char **error, int64_t x, int64_t y) } -#ifndef _STP_TEST_ -/** Return a random integer between -n and n. +/** Return a random integer between 0 and n - 1. * @param n how far from zero to go. Make it positive but less than a million or so. */ -static int _stp_random_pm (int n) +static unsigned long _stp_random_u (unsigned long n) { static unsigned long seed; static int initialized_p = 0; - + if (unlikely (! initialized_p)) { seed = (unsigned long) jiffies; initialized_p = 1; } - + /* from glibc rand man page */ seed = seed * 1103515245 + 12345; - - return (seed % (2*n+1)-n); + + return (n == 0 ? 0 : seed % n); } -#endif /* _STP_TEST_ */ + + +/** Return a random integer between -n and n. + * @param n how far from zero to go. Make it positive but less than a million or so. + */ +static int _stp_random_pm (unsigned n) +{ + return -(int)n + (int)_stp_random_u (2*n + 1); +} + #if defined (__i386__) || defined (__arm__) diff --git a/tapset/random.stp b/tapset/random.stp new file mode 100644 index 00000000..9b2fdc70 --- /dev/null +++ b/tapset/random.stp @@ -0,0 +1,14 @@ +/** + * sfunction randint - Return a random number between [0,n) + * @n: Number past upper limit of range, not larger than 2**20. + */ +function randint:long(n:long) +%{ /* unprivileged */ +#define RANDMAX (1024*1024) + if (THIS->n > RANDMAX) + CONTEXT->last_error = "range too wide"; + else { + THIS->__retvalue = (uint64_t) _stp_random_u((unsigned long) THIS->n); + } +#undef RANDMAX +%} diff --git a/testsuite/systemtap.base/rand.exp b/testsuite/systemtap.base/rand.exp new file mode 100644 index 00000000..9b372e18 --- /dev/null +++ b/testsuite/systemtap.base/rand.exp @@ -0,0 +1,3 @@ +set test "rand" +set ::result_string {PASS} +stap_run2 $srcdir/$subdir/$test.stp diff --git a/testsuite/systemtap.base/rand.stp b/testsuite/systemtap.base/rand.stp new file mode 100644 index 00000000..d584e5f7 --- /dev/null +++ b/testsuite/systemtap.base/rand.stp @@ -0,0 +1,19 @@ +function checkStatus(status:long){ + if (status == 1){ + printf("%s\n","FAIL") + }else{ + printf("%s\n","PASS") + } +} + +probe begin +{ + status = 0 + for (i=1; i <= 100; i++){ + if (randint(i) < 0 || randint(i) > i) { + status = 1 + } + } + checkStatus(status) + exit() +} |