Annotation of pgp/src/memmgr.c, revision 1.1.1.1

1.1       root        1: /***
                      2:        Begin memory management routines:  pcreat2, gblock, and rblock. 
                      3:        Assumes fixed sized blocks.  This approach produces no memory
                      4:        fragmentation, and requires no garbage collection.  This feature
                      5:        is important in a real-time environment.
                      6: 
                      7:        (c) 1988 Philip Zimmermann
                      8:        Boulder Software Engineering
                      9:        3021 Eleventh Street
                     10:        Boulder, CO 80304
                     11:        (303) 444-4541
                     12: 
                     13:        31 July 88
                     14:        Revised 15 Dec 90
                     15: ***/
                     16: 
                     17: /* #define _NOPRINTF   /* define if no printf available */
                     18: #ifndef _NOPRINTF
                     19: #include <stdio.h>     /* for printf(), puts() */
                     20: #endif
                     21: /* Define whether malloc is available.  Some embedded systems lack it. */
                     22: /* #define _NOMALLOC */ /* define if no malloc is available. */
                     23: #ifndef _NOMALLOC      /* malloc library routine available */
                     24: #include <stdlib.h>    /* ANSI C library - for malloc() and free() */
                     25: /* #include <alloc.h> */       /* Borland Turbo C has malloc in <alloc.h> */
                     26: #endif /* malloc available */
                     27: 
                     28: #include "memmgr.h"    /* memory manager headers */
                     29: 
                     30: #define putstr(s) puts(s) /* put string */
                     31: 
                     32: /*     gblock and rblock contain critical sections of code that should not
                     33:        be interrupted by any other process that might use the same data
                     34:        structure.  We protect this critical code by disabling interrupts.
                     35:        The primitives for this are begin_critical_section() and 
                     36:        end_critical_section().  These are necessarily machine-dependent 
                     37:        primitives, and are only needed in multitasking or interrupt-
                     38:        driven realtime environments.  For non-realtime environments, 
                     39:        stubs are provided here for these primitives.
                     40: */
                     41: #define begin_critical_section()       /* null stub */
                     42: #define end_critical_section() /* null stub */
                     43: 
                     44: /* This typedef for a memory partition is unused, but is here for clarity */
                     45: typedef struct /* memory manager partition structure */
                     46: {      ptr head;       /* ptr to head of free list */
                     47:        p_range psize;  /* partition size, as measured in bytes */
                     48:        byte body;      /* body of memory partition starts here */
                     49: } partition;
                     50: 
                     51: 
                     52: /*
                     53: **     partsize - returns size of partition in bytes
                     54: **     Used to declare storage for a memory partition array of bytes.
                     55: **     Computed from the block size, the number of blocks,
                     56: **     plus partheadsize.
                     57: **
                     58: **     partheadsize is a #define in the header file "memmgr.h"
                     59: **     partsize() is a #define in the header file "memmgr.h"
                     60: */
                     61: 
                     62: 
                     63: /*
                     64: **     pcreate - initialize memory manager partition
                     65: **     Similar to pcreat2, but with slightly different arguments.
                     66: **
                     67: **     pcreate() is a #define in the header file "memmgr.h"
                     68: */
                     69: 
                     70: 
                     71: /*
                     72: **     pcreat2 - initialize memory manager partition
                     73: **
                     74: **     Create a linked list of fixed-sized free memory blocks.
                     75: **     Note that the link field of each block has meaning only when the
                     76: **     block is in the list of deallocated blocks.
                     77: **     If invoked in a real-time environment, we assume this entire 
                     78: **     routine is executed without interruption.
                     79: */
                     80: void pcreat2(ptr part, word16 bsize, word16 nblocks)
                     81: /*     part is pointer to memory partition, better if aligned 
                     82:        to ptr boundary.
                     83:        bsize is block size, must be ptr aligned.
                     84:        nblocks is number of blocks.
                     85: */
                     86: {      ptr link;               /* scratch pointer */
                     87:        p_range * psize;        /* pointer to partition size */
                     88:        psize = (p_range *) (part + sizeof(ptr));
                     89:        *psize = partsize(bsize,nblocks);
                     90:        link = part + partheadsize; /* address of 1st block */
                     91:        *(ptr *) part = link;   /* point head at 1st block */
                     92: 
                     93:        while (nblocks--)
                     94:        {       part = link;            /* skip to next block */
                     95:                /* compute addr of next block */
                     96:                link += bsize;          /* compute addr of next block */
                     97:                *(ptr *) part = link;   /* create link to it */
                     98:        }
                     99:        *(ptr *) part = nil;    /* last link in chain is nil */
                    100: }      /* pcreat2 */
                    101: 
                    102: #ifndef _NOMALLOC      /* malloc library routine available */
                    103: /*
                    104: **     partalloc - allocate and initialize memory manager partition
                    105: **     Returns a ptr to the initialized partition, or NULL if there's no room.
                    106: **     Can be called instead of pcreat2, if the storage needs allocating.
                    107: **     If invoked in a real-time environment, we assume this entire 
                    108: **     routine is executed without interruption.
                    109: */
                    110: ptr partalloc(word16 bsize, word16 nblocks)
                    111: /*     bsize is block size.
                    112:        nblocks is number of blocks.
                    113: */
                    114: {      ptr *part;
                    115:        /* allign block size to ptr boundary */
                    116:        bsize = alignptr(bsize);
                    117:        /* allocate memory partition... */
                    118:        part = (ptr *) malloc(partsize(bsize,nblocks));
                    119:        if (part != NULL)       /* if memory is not exhausted... */
                    120:                pcreat2((ptr) part,bsize,nblocks);
                    121:        return ((ptr) part);
                    122: } /* partalloc */
                    123: #endif /* ifndef _NOMALLOC */
                    124: 
                    125: /*
                    126: **     gblock - get memory block from partition
                    127: **
                    128: **     Delink a block from the head of the linked list of free blocks.
                    129: */
                    130: ptr gblock(register ptr part)
                    131: /*     part is pointer to memory partition. */
                    132: {      register ptr link;      /* scratch pointer */
                    133:        begin_critical_section();       /* prevent interruption */
                    134:        link = *(ptr *) part;   /* get head of free list */
                    135:        if (link != nil)        /* list exhausted if head is nil */
                    136:                *(ptr *) part = *(ptr *) link; /* update head */
                    137: #ifdef DEBUG
                    138:        else    putstr("\nGblock warning: memory partion exhausted!\07\n");
                    139: #endif /* DEBUG */
                    140:        end_critical_section();
                    141:        return (link);          /* return address of memory block or nil */
                    142:        /* Note that this allocated block's link field is now trashable. */
                    143: }      /* gblock */
                    144: 
                    145: 
                    146: /*
                    147: **     rblock - release memory block to partition
                    148: **
                    149: **     Insert a block at the head of the linked list of free blocks.
                    150: */
                    151: ptr rblock(register ptr part, register ptr addr)
                    152: /*     part is pointer to memory partition.
                    153:        addr is pointer to block--must belong to partition.
                    154: */
                    155: {      register ptr link;      /* scratch pointer */
                    156: #ifdef DEBUG
                    157:        {       p_range * psize;        /* pointer to partition size */
                    158:                psize = (p_range *) (part + sizeof(ptr));
                    159:                if ( ( addr > (part + *psize) )
                    160:                  || ( addr < (part + partheadsize) ) )
                    161:                {       if (addr==nil)  /* special case diagnostic */
                    162:                                putstr("\nRblock warning: nil memory block pointer\07\n");
                    163:                        else
                    164:                                putstr("\nRblock error: memory block not in partition!\07\n");
                    165:                        return (addr);  /* return ptr unmodified */
                    166:                }
                    167:        }
                    168: #endif /* DEBUG */
                    169:        begin_critical_section();       /* prevent interruption */
                    170:        link = *(ptr *) part;   /* save old head of free list */
                    171:        *(ptr *) addr = link;   /* point released block at old head */
                    172:        *(ptr *) part = addr;   /* point head at released block */
                    173:        end_critical_section();
                    174:        return (nil);           /* normal return--nil ptr */
                    175: }      /* rblock */
                    176: 
                    177: 
                    178: #ifndef _NOPRINTF      /* printf available */
                    179: /*
                    180: **     dumpfree - dump a partition's free block list in hex.
                    181: **     If invoked in a real-time environment, we assume this entire 
                    182: **     routine is executed without interruption.
                    183: */
                    184: void dumpfree(ptr part)
                    185: /*     part is pointer to memory partition. */
                    186: {      byte i;
                    187:        p_range * psize;        /* pointer to partition size */
                    188:        psize = (p_range *) (part + sizeof(ptr));
                    189:        i = 0;
                    190:        printf("\nMemory partition at %04X, size=%04X ",part,*psize);
                    191:        while ((*(ptr *)part)!=nil)             /* go until we hit a nil ptr */
                    192:        {       if ((i-- & 7)==0) putchar('\n');
                    193:                printf("%04X ",*(ptr *)part);   /* print a pointer */
                    194:                part = *(ptr *)part;            /* follow chain */
                    195:        }
                    196:        putstr("nil\n");
                    197: } /* dumpfree */
                    198: #endif /* ifndef _NOPRINTF */
                    199: 
                    200: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.