Annotation of pgp/src/memmgr.c, revision 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.