diff options
| author | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
|---|---|---|
| committer | Florian Fischer <florian.fl.fischer@fau.de> | 2019-08-24 17:57:51 +0200 |
| commit | 77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507 (patch) | |
| tree | 93d4e30a207265af03394d347bfff76ba677f3ce /src/benchmarks/cfrac/pops.c | |
| parent | 971adefadb94e8780b1a73f08ed11d76c2ead8a2 (diff) | |
| download | allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.tar.gz allocbench-77ac9ce0a5c55d4f79f8fb8f7daa59ddb53cb507.zip | |
add cfrac benchmark
Diffstat (limited to 'src/benchmarks/cfrac/pops.c')
| -rw-r--r-- | src/benchmarks/cfrac/pops.c | 339 |
1 files changed, 339 insertions, 0 deletions
diff --git a/src/benchmarks/cfrac/pops.c b/src/benchmarks/cfrac/pops.c new file mode 100644 index 0000000..7154dd7 --- /dev/null +++ b/src/benchmarks/cfrac/pops.c @@ -0,0 +1,339 @@ +#ifdef DEBUGOPS +#include <stdio.h> +#endif +/* + * High Precision Math Library + * + * Written by Dave Barrett 2/23/83 + * Translated from modcal to pascal 4/30/84 + * Mod portability fixed; removed floor function 5/14/84 + * Fixed numerous bugs and improved robustness 5/21/84 + * Translated to C 6/14/84 + * Changed precision to be determined at run-time 5/19/85 + * Added dynamic allocation 7/21/85 + * Combined unsigned math and integer math 8/01/85 + * Fixed Bug in pcmp 7/20/87 + * Fixed handling of dynamic storage (refcount added) 7/20/87 + * Final debugging of current version 8/22/87 + * Fixed many bugs in various routines, wrote atop 2/07/89 + * Tuned for speed, fixed overflow problems 3/01/89 + * Removed refcounts, more tuning, removed pcreate 3/16/89 + * Added cmp macros, change name of pzero, added pshift 4/29/89 + * Repaired operation order bugs in pdiv, calc.c 5/15/91 + * Added pdiv macro, split out pcmp, pabs, much cleanup 5/21/91 + * + * warning! The mod operation with negative arguments not portable. + * I have therefore avoided it completely with much pain. + * + * The following identities have proven useful: + * + * given: a % b = a - floor(a/b) * b + * then : -a % -b = -(a % b) + * -a % b = -( a % -b) = b - a % b (a % b != 0) + * a % -b = -(-a % b) = a % b - b (a % b != 0) + * + * given: a % b = a - a / b * b + * then : -a % -b = -a % b = -(a % b) + * a % -b = a % b + * + * Also, be very careful of computations in the inner loops. Much + * work has been done to make sure the compiler does not re-arrange + * expressions to cause an overflow. The compiler may still be doing + * unnecessary type conversions. + * + * NOTES: + * + * The ptoa routine creates storage which is likely to be forgotton. + * + * A function returning a result must use the result. If it doesn't + * the storage is never freed. For example: itop(2); by itself + * You must make sure to pdestroy the result. + * + * An error (out of storage) fails to deallocate u and v. + * + * psub, pcmp, pdiv, and pmul all assume normalized arguments. + * + * This file contains the storage management-specific code: + * palloc, pfree, pset -- together these account for 45% of execution time + */ +#include <string.h> +#include "pdefs.h" /* private include file */ +#include "precision.h" /* public include file for forward refs */ + +cacheType pcache[CACHESIZE]; +static char ident[] = + " @(#) libprecision.a version 2.00 3-May-91 by Dave Barrett\n"; + +/* + * normalize (used by div and sub) + * remove all leading zero's + * force positive sign if result is zero + */ +void pnorm(u) + register precision u; +{ + register digitPtr uPtr; + + uPtr = u->value + u->size; + do { + if (*--uPtr != 0) break; + } while (uPtr > u->value); + + if (uPtr == u->value && *uPtr == 0) u->sign = false; + + u->size = (uPtr - u->value) + 1; /* normalize */ +} + +/* + * Create a number with the given size (private) (very heavily used) + */ +precision palloc(size) + register posit size; +{ + register precision w; + register cacheType *kludge = pcache + size; /* for shitty compilers */ + +#if !(defined(NOMEMOPT) || defined(BWGC)) + if (size < CACHESIZE && (w = kludge->next) != pUndef) { + kludge->next = ((cacheType *) w)->next; + --kludge->count; + } else { +#endif + w = (precision) allocate(PrecisionSize + sizeof(digit) * size); + if (w == pUndef) { + w = errorp(PNOMEM, "palloc", "out of memory"); + return w; + } +#if !(defined(NOMEMOPT) || defined(BWGC)) + } +#endif +#ifndef BWGC + w->refcount = 1; +#endif + w->size = w->alloc = size; +#ifdef DEBUGOPS + printf("alloc %.8x\n", w); + fflush(stdout); +#endif + return w; +} + +/* + * (Very heavily used: Called conditionally pdestroy) + * (should be void, but some compilers can't handle it with the macro) + */ +int pfree(u) + register precision u; +{ + register posit size; + register cacheType *kludge; /* for shitty compilers */ + +#ifdef DEBUGOPS + printf("free %.8x\n", u); + fflush(stdout); +#endif + + size = u->alloc; + + kludge = pcache + size; +#if !(defined(NOMEMOPT) || defined(BWGC)) + if (size < CACHESIZE && kludge->count < CACHELIMIT) { + ((cacheType *) u)->next = kludge->next; + kludge->next = u; + kludge->count++; + } else { +#endif + deallocate(u); +#if !(defined(NOMEMOPT) || defined(BWGC)) + } +#endif + return 0; +} + +/* + * User inteface: + * + * Rules: + * a precision must be initialized to pUndef or to result of pnew. + * a precision pointer must point to a precision or be pNull + * pUndef may not be passed as an rvalue into a function + * pNull may not be passed as an lvalue into a function + * + * presult and pdestroy are the only functions which may be passed pUndef + */ + +/* + * assignment with verification (slower, but helpful for bug detect) + * It would be nice if this routine could detect pointers to incorrect + * or non-living areas of memory. + * + * We can't check for undefined rvalue because we want to allow functions + * to return pUndef, and then let the application check for it after assigning + * it to a variable. + * + * usage: pset(&i, j); + */ +precision psetv(up, v) + register precision *up, v; +{ + register precision u; + +#ifdef DEBUGOPS + printf("psetv %.8x %.8x ", up, v); +#endif +#ifdef DEBUGOPS +#ifndef BWGC + printf("->%u", v->refcount); +#endif +#endif + if (up == pNull) { + errorp(PDOMAIN, "pset", "lvalue is pNull"); + } + u = *up; +#ifdef DEBUGOPS + printf(" %.8x", u); +#endif + *up = v; + if (v != pUndef) { +#ifndef BWGC + v->refcount++; +#endif + } + if (u != pUndef) { + if (u->sign & ~1) { /* a minimal check */ + errorp(PDOMAIN, "pset", "invalid precision"); + } +#ifndef BWGC + if (--(u->refcount) == 0) { +#ifdef DEBUGOPS + printf("->%u", u->refcount); +#endif + pfree(u); + } +#endif + } +#ifdef DEBUGOPS + putchar('\n'); + fflush(stdout); +#endif + return v; +} + +precision pparmv(u) + register precision u; +{ +#ifdef DEBUGOPS + printf("pparm %.8x\n", u); + fflush(stdout); +#endif + if (u == pUndef) { + errorp(PDOMAIN, "pparm", "undefined function argument"); + } + if (u->sign & ~1) { /* a minimal check */ + errorp(PDOMAIN, "pparm", "invalid precision"); + } +#ifndef BWGC + u->refcount++; +#endif + return u; +} + +/* + * Function version of unsafe pparmq macro + */ +precision pparmf(u) + register precision u; +{ +#ifndef BWGC + if (u != pUndef) { + u->refcount++; + } +#endif + return u; +} + +/* + * Function version of pdestroy macro + */ +void pdestroyf(u) + register precision u; +{ +#ifndef BWGC + if (u != pUndef && --u->refcount == 0) { + pfree(u); + } +#endif +} + +#ifndef __GNUC__ /* inline in header file */ +/* + * We cannot allow this to be a macro because of the probability that it's + * argument will be a function (e.g. utop(2)) + */ +precision pnew(u) + register precision u; +{ +#ifndef BWGC + u->refcount++; +#endif + return u; +} + +/* + * Cannot be a macro because of function argument possibility + */ +precision presult(u) + register precision u; +{ +#ifndef BWGC + if (u != pUndef) { + --(u->refcount); + } +#endif + return u; +} + +/* + * Quick but dangerous assignment + * + * Assumes: target not pNull and source not pUndef + */ +precision psetq(up, v) + register precision *up, v; +{ + register precision u = *up; /* up may NOT be pNULL! */ + + *up = v; /* up may be &v, OK */ +#ifndef BWGC + if (v != pUndef) { /* to allow: x=func(); if (x==pUndef) ... */ + v->refcount++; + } + if (u != pUndef && --(u->refcount) == 0) { + pfree(u); + } +#endif + return v; +} +#endif + +#if 0 /* original assignment code */ +precision pset(up, v) + register precision *up, v; +{ + register precision u; + +#ifndef BWGC + if (v != pUndef) v->refcount++; +#endif + if (up == pNull) { /* useful voiding parameters (pdiv) */ + pdestroy(v); + return pUndef; + } + u = *up; + if (u != pUndef) { /* useful to force initial creation */ + pdestroy(u); + } + *up = v; /* notice that v may be pUndef which is OK! */ + return v; /* no presult! This is a variable */ +} +#endif |
