]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/lib/font/Type1/t1malloc.c
Removed Xserver/ directory, it does nothing useful ATM.
[rdpsrv] / Xserver / lib / font / Type1 / t1malloc.c
diff --git a/Xserver/lib/font/Type1/t1malloc.c b/Xserver/lib/font/Type1/t1malloc.c
deleted file mode 100644 (file)
index be93bda..0000000
+++ /dev/null
@@ -1,729 +0,0 @@
-/* $XConsortium: t1malloc.c,v 1.5 93/09/10 10:48:21 rws Exp $ */
-/* Copyright International Business Machines, Corp. 1991
- * All Rights Reserved
- * Copyright Lexmark International, Inc. 1991
- * All Rights Reserved
- *
- * License to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation, and that the name of IBM or Lexmark not be
- * used in advertising or publicity pertaining to distribution of the
- * software without specific, written prior permission.
- *
- * IBM AND LEXMARK PROVIDE THIS SOFTWARE "AS IS", WITHOUT ANY WARRANTIES OF
- * ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO ANY
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE,
- * AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  THE ENTIRE RISK AS TO THE
- * QUALITY AND PERFORMANCE OF THE SOFTWARE, INCLUDING ANY DUTY TO SUPPORT
- * OR MAINTAIN, BELONGS TO THE LICENSEE.  SHOULD ANY PORTION OF THE
- * SOFTWARE PROVE DEFECTIVE, THE LICENSEE (NOT IBM OR LEXMARK) ASSUMES THE
- * ENTIRE COST OF ALL SERVICING, REPAIR AND CORRECTION.  IN NO EVENT SHALL
- * IBM OR LEXMARK BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
- * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
- * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
- * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- * THIS SOFTWARE.
- */
- /* MALLOC   CWEB         V0004 LOTS                                 */
-/*
-:h1.MALLOC - Fast Memory Allocation
-This module is meant to provide portable C-style memory allocation
-routines (malloc/free).
-&author. Jeffrey B. Lotspiech (lotspiech@almaden.ibm.com)
-*/
-
-#include "objects.h"   /* get #define for abort() */
-
-static combine();
-static freeuncombinable();
-static unhook();
-static dumpchain();
-/*
-:h3.Define NULL
-In the beginning, C compilers made no assumptions about NULL.  It was
-even theoretically possible that NULL would not be 0.  ANSI has tied
-this down a bit.  The following definition seems to be the most
-popular (in terms of reducing compiler complaints), however, if your
-compiler is unhappy about it, you can redefine it on the command line:
-*/
-#ifndef   NULL
-#define   NULL   0
-#endif
-/*
-Of course, NULL is important because xiMalloc() is defined to return
-NULL when out of memory.
-:h2.Data Structures Used to Manage Free Memory
-:h3.The "freeblock" Structure
-The list of available memory blocks is a doubly-linked list.  Each
-block begins with the following structure:
-*/
-struct freeblock {
-        long size;                      /* number of 'longs' in block,
-                                           including this header */
-        struct freeblock *fore;        /* forward in doubly-linked list */
-        struct freeblock *back;        /* backward in doubly-linked list */
-} ;
-/*
-In addition, each free block has a TRAILER that is simply the 'size'
-repeated.  Thus 'size' is found at the beginning of the block and at the
-end of the block (size-1 longs away).  'size' includes both the header
-and the trailer.
-When a block is allocated, its 'size' is turned negative (both at the
-beginning and at the end).  Thus, checking whether two blocks may be
-combined is very simple.  We merely examine both neighboring blocks'
-size to see if they are positive (and hence available for combination).
-The memory address returned to the user is therefore one "long" below the
-size, and one extra "long" is added to the end of the block (beyond what
-the user requested) to store the trailing size.
-:h3."firstfree" and "lastfree", the Anchors to the Free List
-"firstfree" points to the first available free block; "lastfree" points
-to the end of the chain of available blocks.  These are linked together
-by initialization code; see :hdref refid=addmem..
-*/
-static struct freeblock firstfree = { 0L, NULL, NULL };
-static struct freeblock lastfree = { 0L, NULL, NULL };
-/*
-:h3."firstcombined" and "uncombined", Keeping Track of Uncombined Blocks
-This module is designed to make the combining of adjacent free memory
-blocks be very fast.  Nonetheless, combining blocks is naturally the
-most expensive part of any memory system.  In an X system,
-it is worthwhile to defer the combination for a while, because
-frequently we will end up asking for a block of exactly the same
-size that we recently returned and we can save ourselves some work.
-"MAXUNCOMBINED" is the maximum number of uncombined blocks that we will
-allow at any time:
-*/
-#define   MAXUNCOMBINED  3
-/*
-"firstcombined" is a pointer into the free list.  The uncombined blocks
-are always at the front of the list.  "firstcombined" points to the
-first block that has been combined.
-*/
-static struct freeblock *firstcombined = &lastfree;
-static short uncombined = 0; /* current number of uncombined blocks          */
-/*
-Uncombined blocks have a negative 'size'; in this they are like
-allocated blocks.
-We store a distinctive hex pattern in 'size' when we combine a block
-to help us debug:
-*/
-#define   COMBINED   0xBADBAD
-/*
-:h3.DEBUGWORDS - Extra Memory Saved With Each Block for Debug
-We add 'DEBUGWORDS' words to each allocated block to put interesting
-debug information:
-*/
-#ifndef   DEBUGWORDS
-#define   DEBUGWORDS   0
-#endif
-/*
-:h3.MINEXCESS - Amount of "Excess" We Would be Willing to Ignore
-When we search the free list to find memory for a user request, we
-frequently find an area that is bigger than what the user has asked for.
-Normally we put the remaining words (the excess) back on the free list.
-However, if the area is just slightly bigger than what the user needs,
-it is counter-productive to do this, as the small amount recovered tends
-to hurt by increasing memory fragmentation rather than help by providing
-more available memory.  "MINEXCESS" is the number of words that must be
-recovered before we would bother to put the excess back on the free
-list.  If there is not enough excess, we just give the user more than he
-asked for.
-*/
-#define   MINEXCESS      (7 + DEBUGWORDS)
-/*
-:h3.Some Flags for Debug
-*/
-long AvailableWords = 0;     /* number of words available in memory          */
-char mallocdebug = 0;        /* a flag that enables some chatty printf's     */
-/*
-:h3.whocalledme() - Debug for Memory Leaks
-This routine is 68000-specific; it copies the value of the application's
-curOper variable (which is often a pointer to a character string), and
-the first part of the stack at the time malloc was called into the
-DEBUGWORDS area reserved with each block.
-We use it to see who is malloc-ing memory without free-ing it.
-*/
-#if DEBUGWORDS
-static whocalledme(addr, stack)
-       long *addr;           /* address of memory block                      */
-       long *stack;          /* address of malloc's parameter on stack       */
-{
-       register long size;   /* size of memory block                         */
-       register int i;       /* loop index                                   */
-       extern char *curOper; /* ptr to last operator (kept by appl.) */
-       stack--;
-       size = - *addr;
-       addr += size - 1 - DEBUGWORDS;
-       *addr++ = (long) curOper;
-       for (i=0; i < DEBUGWORDS-1; i++)
-               *addr++ = *stack++;
-}
-#else
-#define whocalledme(addr, stack)
-#endif
-/*
-:h2.xiFree() - User-Callable "Return Memory" Routine
-The actual beginning of the block is one 'long' before the address we
-gave to the user.  The block begins and ends with '-size' in words.
-*/
-void xiFree(addr)
-        register long *addr;           /* user's memory to be returned   */
-{
-        register long size;            /* amount of memory in this block */
-        register struct freeblock *p;  /* identical to 'addr'            */
-        if (addr == NULL) {  /* common "mistake", so allow it (CHT) */
-            printf("\nxiFree(NULL)?\n");
-            return;
-        }
-        size = *--addr;
-/*
-Make sure this address looks OK; 'size' must be less than zero (meaning
-the block is allocated) and should be repeated at the end of the block.
-*/
-        if (size >= 0)
-                abort("free: bad size");
-        if (addr[-1 - size] != size)
-                abort("free: mismatched size");
-/*
-Now make this a 'freeblock' structure and tack it on the FRONT of the
-free list (where uncombined blocks go):
-*/
-        AvailableWords -= size;  /* actually INCREASES AvailableWords */
-        p = (struct freeblock *) addr;
-        p->back = &firstfree;
-        (p->fore = firstfree.fore)->back = p;
-        firstfree.fore = p;
-/*
-If we have too many uncombined blocks, call combine() to combine one.
-*/
-        if (++uncombined > MAXUNCOMBINED) {
-                combine();
-                if (mallocdebug) {
-                        printf("xiFree(%08x) with combine, ", addr);
-                        dumpchain();
-                }
-        }
-        else {
-                if (mallocdebug) {
-                        printf("xiFree(%08x), ", addr);
-                        dumpchain();
-                }
-        }
-        return;
-}
-/*
-:h3.combine() - Subroutine of xiFree() to Combine Blocks
-This routine tries to combine the block just before 'firstcombined'.
-In any event, that block will be moved to the end of the list (after
-'firstcombined').
-*/
-static combine()
-{
-        register struct freeblock *p;   /* block we will try to combine */
-        register long *addr;            /* identical to 'p' for 'long' access */
-        register long size;             /* size of this block  */
-        register long size2;            /* size of potential combinee */
-        p = firstcombined->back;
-        if (p == &firstfree)
-               abort("why are we combining?");
-        addr = (long *) p;
-        size = - p->size;
-        if (--uncombined < 0)
-                abort("too many combine()s");
-        if (addr[-1] < 0 && addr[size] < 0) {
-/*
-We special case the situation where no combining can be done.  Then, we
-just mark the chain "combined" (i.e., positive size), move the
-'firstcombined' pointer back in the chain, and return.
-*/
-                addr[0] = addr[size - 1] = size;
-                firstcombined = (struct freeblock *) addr;
-                return;
-        }
-/*
-Otherwise, we unhook this pointer from the chain:
-*/
-        unhook(p);
-/*
-First we attempt to combine this with the block immediately above:
-*/
-        size2 = addr[-1];
-        if (size2 > 0) {     /* i.e., block above is free */
-                *addr = COMBINED;  /* might help debug */
-                addr -= size2;
-                if (addr[0] != size2)
-                        abort("bad block above");
-                unhook(addr);
-                size += size2;
-        }
-/*
-At this point 'addr' and 'size' may be the original block, or it may be
-the newly combined block.  Now we attempt to combine it with the block
-below:
-*/
-        p = (struct freeblock *) (addr + size);
-        size2 = p->size;
-        if (size2 > 0) {     /* i.e., block below is free                    */
-                p->size = COMBINED;
-                if (size2 != ((long *) p)[size2 - 1])
-                        abort("bad block below");
-                unhook(p);
-                size += size2;
-        }
-/*
-Finally we take the newly combined block and put it on the end of the
-chain by calling the "freeuncombinable" subroutine:
-*/
-        freeuncombinable(addr, size);
-}
-/*
-:h3.freeuncombinable() - Free a Block That Need Not be Combined
-This block is "uncombinable" either because we have already combined
-it with its eligible neighbors, or perhaps because we know it has
-no neighbors.
-*/
-static freeuncombinable(addr, size)
-        register long *addr;  /* address of the block to be freed            */
-        register long size;   /* size of block in words                      */
-{
-        register struct freeblock *p;  /* a convenient synonym for 'addr'    */
-/*
-Mark block allocated and combined by setting its 'size' positive:
-*/
-        addr[size - 1] = addr[0] = size;
-/*
-Now tack the block on the end of the doubly-linked free list:
-*/
-        p = (struct freeblock *) addr;
-        p->fore = &lastfree;
-        (p->back = lastfree.back)->fore = p;
-        lastfree.back = p;
-/*
-If we have previously had no combined blocks, we must update
-'firstcombined' to point to this block:
-*/
-        if (firstcombined->fore == NULL)
-                firstcombined = p;
-}
-/*
-:h3.unhook() - Unhook a Block from the Doubly-linked List
-The only tricky thing here is to make sure that 'firstcombined' is
-updated if this block happened to be the old 'firstcombined'.  (We
-would never be unhooking 'firstfree' or 'lastfree', so we do not
-have to worry about the end cases.)
-*/
-static unhook(p)
-        register struct freeblock *p;  /* block to unhook                    */
-{
-        p->back->fore = p->fore;
-        p->fore->back = p->back;
-        if (firstcombined == p)
-                firstcombined = p->fore;
-}
-/*
-:h2.xiMalloc() - Main User Entry Point for Getting Memory
-We have two slightly different versions of xiMalloc().  In the case
-where we have TYPE1IMAGER and a font cache, we are prepared, when nominally
-out of memory, to loop calling TYPE1IMAGER's GimeSpace() to release font
-cache.
-*/
-/* The following code put in by MDC on 11/10/90 */
-#ifdef TYPE1IMAGER
-static char *malloc_local();
-char *xiMalloc(size)
-        register unsigned size;
-{
-  char *memaddr;
-  while ( (memaddr = malloc_local(size)) == NULL ) {
-    /* Ask TYPE1IMAGER to give us some of its cache back */
-    if ( I_GimeSpace() == 0 ) break; /* We are really, really, out of memory */
-  }
-  return(memaddr);
-}
-#endif
-/*
-Now begins the real workhorse xiMalloc() (called 'malloc_local' if
-we are taking advantage of TYPE1IMAGER).  Its argument is an unsigned;
-at least that lets users with 16-bit integers get a 64K chunk of
-memory, and it is also compatible with the definition of a "size_t"
-in most systems.
-*/
-#ifdef TYPE1IMAGER
-static char *malloc_local(Size)
-#else
-char *xiMalloc(Size)
-#endif
-        unsigned Size;       /* number of bytes the user requested           */
-{
-        register long size = (long)Size;  /* a working register for size     */
-        register struct freeblock *p;  /* tentative block to be returned     */
-        register long excess; /* words in excess of user request             */
-        register long *area; /* a convenient synonym for 'p'                 */
-/*
-First, we increase 'size' to allow for the two size fields we will
-save with the block, plus any information for debug purposes.
-Then we ensure that the block will be large enough to hold our
-'freeblock' information.  Finally we convert it to be in words
-(longs), not bytes, increased to span an integral number of double
-words, so that all memory blocks dispensed with be properly aligned.
-*/
-        size += 2*sizeof(long) + DEBUGWORDS*sizeof(long);
-        if (size < sizeof(struct freeblock) + sizeof(long))
-               size = sizeof(struct freeblock) + sizeof(long);
-        size = ((unsigned) (size + sizeof(double) - 1) / sizeof(double)) * (sizeof(double)/sizeof(long));
-/*
-For speed, we will try first to give the user back a very recently
-returned block--one that is on the front of the chain before
-'firstcombined'.  These blocks still have negative sizes, and need
-only to be "unhook"ed:
-*/
-        size = -size;
-        for (p=firstfree.fore; p != firstcombined; p=p->fore) {
-                if (p->size == size) {
-                        unhook(p);
-                        uncombined--;
-                        if (mallocdebug) {
-                               printf("fast xiMalloc(%d) = %08x, ", size, p);
-                               dumpchain();
-                        }
-                        AvailableWords += size;  /* decreases AvailableWords */
-                        whocalledme(p, &Size);
-                        return((char *)&p->fore);
-                }
-        }
-/*
-Well, if we get here, there are no uncombined blocks matching the user's
-request.  So, we search the rest of the chain for a block that is big
-enough.  ('size' becomes positive again):
-*/
-        size = -size;
-        for (;; p = p->fore) {
-/*
-If we hit the end of the chain (p->size == 0), we are probably out of
-memory.  However, we should first try to combine any memory that has
-not yet been combined before we give that pessimistic answer.  If
-we succeed in combining, we can call ourselves recursively to try to
-allocate the requested amount:
-*/
-               if (p->size == 0) {
-                       if (uncombined <= 0)
-                              return(NULL);
-                       while (firstfree.fore != firstcombined)
-                              combine();
-                       return(xiMalloc(sizeof(long) * (size - 2 - DEBUGWORDS)));
-               }
-/*
-Otherwise, we keep searching until we find a big enough block:
-*/
-               if (p->size >= size)
-                       break;
-        }
-/*
-At this point, 'p' contains a block at least as big as what the user
-requested, so we take it off the free chain.  If it is excessively big,
-we return the excess to the free chain:
-*/
-        unhook(p);
-        excess = p->size - size;
-        area = (long *) p;
-        if (excess > MINEXCESS)
-                freeuncombinable(area + size, excess);
-        else
-                size = p->size;
-        AvailableWords -= size;
-/*
-Mark first and last word of block with the negative of the size, to
-flag that this block is allocated:
-*/
-        area[size - 1] = area[0] = - size;
-        if (mallocdebug) {
-                printf("slow xiMalloc(%d) @ %08x, ", size, area);
-                dumpchain();
-        }
-        whocalledme(area, &Size);
-/*
-The address we return to the user is one 'long' BELOW the address of
-the block.  This protects our 'size' field, so we can tell the size
-of the block when he returns it to us with xiFree().  Also, he better not
-touch the 'size' field at the end of the block either.  (That would be
-nasty of him, as he would be touching memory outside of the bytes he
-requested).
-*/
-        return((char *) (area + 1));
-}
-/*
-:h2 id=addmem.addmemory() - Initialize Free Memory
-This routine should be called at initialization to initialize the
-free chain.  There is no standard way to do this in C.
-We want the memory dispensed by malloc to be aligned on a double word
-boundary (because some machines either require alignment, or are
-more efficient if accesses are aligned).  Since the total size of
-any block created by malloc is an integral number of double words,
-all we have to do to ensure alignment is to adjust each large block
-added to the free chain to start on an odd long-word boundary.
-(Malloc's size field will occupy the odd long and the user's memory
-will then begin on an even boundary.)  Since we fill in additional
-size fields at the beginning and end of each of the large freeblocks,
-we need only adjust the address passed to addmemory to a double word
-boundary.
-*/
-#define   MAXAREAS   10      /* there can be this many calls to addmemory()  */
-static long *freearea[MAXAREAS] = { NULL };  /* so we can report later       */
-void addmemory(addr, size)
-        register long *addr; /* beginning of free area                       */
-        register long size;  /* number of bytes of free area                 */
-{
-        register int i;      /* loop index variable                          */
-        register long *aaddr;  /* aligned beginning of free area             */
-#if DEBUGWORDS
-        printf("malloc has DEBUGWORDS=%d\n", DEBUGWORDS);
-#endif
-/*
-First link together firstfree and lastfree if necessary:
-*/
-        if (firstfree.fore == NULL) {
-                firstfree.fore = &lastfree;
-                lastfree.back = &firstfree;
-        }
-/*
-We'll record where the area was that was given to us for later reports:
-*/
-        for (i=0; i < MAXAREAS; i++)
-                if (freearea[i] == NULL) break;
-        if (i >= MAXAREAS)
-                abort("too many addmemory()s");
-        aaddr = (long *) ( ((long) addr + sizeof(double) - 1) & - (long)sizeof(double) );
-        size -= (char *) aaddr - (char *) addr;
-        freearea[i] = aaddr;
-/*
-Convert 'size' to number of longs, and store '-size' guards at the
-beginning and end of this area so we will not accidentally recombine the
-first or last block:
-*/
-        size /= sizeof(long);
-        AvailableWords += size - 2;
-        aaddr[size - 1] = aaddr[0] = -size;
-/*
-Finally, call 'freeuncombinable' to put the remaining memory on the
-free list:
-*/
-        freeuncombinable(aaddr + 1, size - 2);
-}
-/*
-:h3.delmemory() - Delete Memory Pool
-*/
-void delmemory()
-{
-       register int i;
-       AvailableWords = 0;
-       firstfree.fore = &lastfree;
-       lastfree.back  = &firstfree;
-       firstcombined  = &lastfree;
-       uncombined     = 0;
-       for (i=0; i<MAXAREAS; i++)
-               freearea[i] = NULL;
-}
-/*
-:h2.Debug Routines
-:h3.dumpchain() - Print the Chain of Free Blocks
-*/
-static dumpchain()
-{
-        register struct freeblock *p;  /* current free block                 */
-        register long size;  /* size of block                                */
-        register struct freeblock *back;  /* block before 'p'                */
-        register int i;      /* temp variable for counting                   */
-        printf("DUMPING FAST FREE LIST:\n");
-        back = &firstfree;
-        for (p = firstfree.fore, i=uncombined; p != firstcombined;
-                                 p = p->fore) {
-                if (--i < 0)
-                        abort("too many uncombined areas");
-                size = p->size;
-                printf(". . . area @ %08x, size = %ld\n", p, -size);
-                if (size >= 0 || size != ((int *) p)[-1 - size])
-                        abort("dumpchain: bad size");
-                if (p->back != back)
-                        abort("dumpchain: bad back");
-                back = p;
-        }
-        printf("DUMPING COMBINED FREE LIST:\n");
-        for (; p != &lastfree; p = p->fore)  {
-                size = p->size;
-                printf(". . . area @ %08x, size = %d\n", p, size);
-                if (size <= 0 || size != ((int *) p)[size - 1])
-                        abort("dumpchain: bad size");
-                if (p->back != back)
-                        abort("dumpchain: bad back");
-                back = p;
-        }
-        if (back != lastfree.back)
-                abort("dumpchain: bad lastfree");
-}
-/*
-:h3.reportarea() - Display a Contiguous Set of Memory Blocks
-*/
-static reportarea(area)
-       register long *area;   /* start of blocks (from addmemory)            */
-{
-       register long size;    /* size of current block                       */
-       register long wholesize;  /* size of original area                    */
-       register struct freeblock *p;  /* pointer to block                    */
-       if (area == NULL)
-               return;
-       wholesize = - *area++;
-       wholesize -= 2;
-       while (wholesize > 0) {
-               size = *area;
-               if (size < 0) {
-                       register int i,j;
-                       size = -size;
-                       printf("Allocated %5d bytes at %08x, first words=%08x %08x\n",
-                               size * sizeof(long), area + 1, area[1], area[2]);
-#if DEBUGWORDS
-                       printf("  ...Last operator: %s\n",
-                               (char *)area[size-DEBUGWORDS-1]);
-#endif
-                       for (i = size - DEBUGWORDS; i < size - 2; i += 8) {
-                               printf("  ...");
-                               for (j=0; j<8; j++)
-                                       printf(" %08x", area[i+j]);
-                               printf("\n");
-                       }
-               }
-               else {
-                       printf("Free %d bytes at %x\n", size * sizeof(long),
-                               area);
-                       if (size == 0)
-                               abort("zero sized memory block");
-                       for (p = firstfree.fore; p != NULL; p = p->fore)
-                               if ((long *) p == area) break;
-                       if ((long *) p != area)
-                               abort("not found on forward chain");
-                       for (p = lastfree.back; p != NULL; p = p->back)
-                               if ((long *) p == area) break;
-                       if ((long *) p != area)
-                               abort("not found on backward chain");
-               }
-               if (area[0] != area[size - 1])
-                       abort("unmatched check sizes");
-               area += size;
-               wholesize -= size;
-       }
-}
-/*
-:h3.MemReport() - Display All of Memory
-*/
-MemReport()
-{
-       register int i;
-       dumpchain();
-       for (i=0; i<MAXAREAS; i++)
-               reportarea(freearea[i]);
-}
-/*
-:h3.MemBytesAvail - Display Number of Bytes Now Available
-*/
-MemBytesAvail()
-{
-       printf("There are now %d bytes available\n", AvailableWords *
-                                                    sizeof(long) );
-}