1: /* $Header: vsalloc.c,v 10.3 86/02/01 15:47:58 tony Rel $ */
   2: /* vsalloc.c	routines to allocate and free vs framebuffer memory
   3:  *
   4:  *	VSMemInit	Initializes the free list
   5:  *	VSAlloc		Allocates a chunk of memory
   6:  *	VSFree		Frees a chunk of memory
   7:  *
   8:  *	The method used is a variant on the method described in Knuth
   9:  * volume 1, page 441.  The modification is that since we can't directly
  10:  * modify the memory in the vs, we maintain an ordered linked list of
  11:  * extents with either free chain pointers or addresses of blocks
  12:  *
  13:  */
  14: 
  15: /****************************************************************************
  16:  *									    *
  17:  *  Copyright (c) 1983, 1984 by						    *
  18:  *  DIGITAL EQUIPMENT CORPORATION, Maynard, Massachusetts.		    *
  19:  *  All rights reserved.						    *
  20:  * 									    *
  21:  *  This software is furnished on an as-is basis and may be used and copied *
  22:  *  only with inclusion of the above copyright notice. This software or any *
  23:  *  other copies thereof may be provided or otherwise made available to     *
  24:  *  others only for non-commercial purposes.  No title to or ownership of   *
  25:  *  the software is hereby transferred.					    *
  26:  * 									    *
  27:  *  The information in this software is  subject to change without notice   *
  28:  *  and  should  not  be  construed as  a commitment by DIGITAL EQUIPMENT   *
  29:  *  CORPORATION.							    *
  30:  * 									    *
  31:  *  DIGITAL assumes no responsibility for the use  or  reliability of its   *
  32:  *  software on equipment which is not supplied by DIGITAL.		    *
  33:  * 									    *
  34:  *									    *
  35:  ****************************************************************************/
  36: 
  37: #include "vs100.h"
  38: #include <errno.h>
  39: 
  40: extern int errno;
  41: 
  42: char *Xalloc();
  43: 
  44: #define slopsize 10 /* Amount we're willing to overallocate */
  45: 
  46: static VSArea listhead;
  47: 
  48: /* Initialize the memory structures.  Called by DownLoad, usually */
  49: 
  50: int VSMemInit()
  51: {
  52:     MemArea freefb, freepg;
  53:     register VSArea *fb, *buf, *pg;
  54:     VSArea *AllocVSArea();
  55: 
  56:     if (ReportStatus ((int *) NULL, (short *) NULL, (short *) NULL,
  57:               (BitMap *) NULL, &freefb, &freepg, (MemArea *) NULL,
  58:               0) == -1) return (-1);
  59: 
  60:     if ((fb = AllocVSArea()) == NULL) return (-1);
  61:     if ((buf = AllocVSArea()) == NULL) return (-1);
  62:     if ((pg = AllocVSArea()) == NULL) return (-1);
  63: 
  64:     /* Make the list of memory areas */
  65: 
  66:     listhead.next = buf->prev = fb;
  67:     fb->next = pg->prev = buf;
  68:     buf->next = listhead.prev = pg;
  69:     pg->next = fb->prev = &listhead;
  70: 
  71:     /* Now set up the free list */
  72: 
  73:     listhead.vsFree.next = pg->vsFree.prev = fb;
  74:     fb->vsFree.next = listhead.vsFree.prev = pg;
  75:     pg->vsFree.next = fb->vsFree.prev = &listhead;
  76: 
  77:     /* Set up the sizes and addresses */
  78: 
  79:     listhead.vsPtr = NULL;
  80:     listhead.vsFreeFlag = VS_INUSE;
  81:     listhead.vsSize = 0;
  82: 
  83:     fb->vsPtr = *(caddr_t *) freefb.m_base;
  84:     fb->vsFreeFlag = VS_FREE;
  85:     fb->vsSize = *(long *) freefb.m_size;
  86: 
  87:     /* There's at least one version of the software that returns
  88: 	   bogus information there, so... (ug) */
  89: 
  90:     if (fb->vsPtr == (caddr_t) 0x12ee00) {
  91:         fb->vsPtr = (caddr_t) 0x117700;
  92:         fb->vsSize = 35072;
  93:     }
  94: 
  95:     /* Hack to deal with the crummy framebuffer bug:  can't use
  96: 	   first 8 bytes */
  97: 
  98:     if (fb->vsPtr == (caddr_t) 0x117700) {
  99:         fb->vsPtr += 8;
 100:         fb->vsSize -= 8;
 101:     }
 102: 
 103:     buf->vsPtr = 0;
 104:     buf->vsFreeFlag = VS_INUSE;
 105:     buf->vsSize = 0;
 106: 
 107:     pg->vsPtr = *(caddr_t *) freepg.m_base;
 108:     pg->vsFreeFlag = VS_FREE;
 109:     pg->vsSize = *(long *) freepg.m_size;
 110: 
 111:     return (0);
 112: }
 113: 
 114: /* Allocate size bytes of specified type (bitmap, halftone, or font) */
 115: 
 116: VSArea *VSAlloc (size, type)
 117:     int size, type;
 118: {
 119:     register VSArea *f = listhead.vsFree.next, *new;
 120: 
 121:     /* Make sure size is a multiple of 2 */
 122: 
 123:     if (size & 0x1) size++;
 124: 
 125:     while (f != &listhead && f->vsSize < size) f = f->vsFree.next;
 126: 
 127:     if (f == &listhead) {
 128:         DeallocateSpace();
 129:         errno = ENOMEM;
 130:         return (NULL);  /* No space */
 131:     }
 132: 
 133:     if (f->vsSize <= size + slopsize) { /* Don't split block */
 134:         f->vsFree.next->vsFree.prev = f->vsFree.prev;
 135:         f->vsFree.prev->vsFree.next = f->vsFree.next;
 136:         f->vsFreeFlag = VS_INUSE;
 137:         f->vsType = type;
 138:         return (f);
 139: 
 140:     } else {    /* Split into two smaller blocks */
 141:         if ((new = AllocVSArea()) == NULL) return (NULL);
 142:         new->prev = f->prev;
 143:         new->next = f;
 144:         f->prev->next = new;
 145:         f->prev = new;
 146:         new->vsSize = size;
 147:         f->vsSize -= size;
 148:         new->vsPtr = f->vsPtr;
 149:         f->vsPtr += size;
 150: 
 151:         new->vsFreeFlag = VS_INUSE;
 152:         new->vsType = type;
 153: 
 154:         return (new);
 155:     }
 156: }
 157: 
 158: /* Free the allocated storage */
 159: 
 160: int VSFree (block)
 161:     register VSArea *block;
 162: {
 163:     register VSArea *temp;
 164: 
 165:     if (block->prev->vsFreeFlag == VS_FREE) { /* Coalesce areas */
 166:         temp = block;
 167:         block = block->prev;
 168:         block->vsSize += temp->vsSize;
 169:         block->next = temp->next;
 170:         temp->next->prev = block;
 171:         FreeVSArea (temp);
 172:         block->vsFree.next->vsFree.prev = block->vsFree.prev;
 173:         block->vsFree.prev->vsFree.next = block->vsFree.next;
 174:     }
 175: 
 176:     if (block->next->vsFreeFlag == VS_FREE) { /* ditto */
 177:         temp = block;
 178:         block = block->next;
 179:         block->vsPtr = temp->vsPtr;
 180:         block->vsSize += temp->vsSize;
 181:         block->prev = temp->prev;
 182:         temp->prev->next = block;
 183:         FreeVSArea (temp);
 184:         block->vsFree.next->vsFree.prev = block->vsFree.prev;
 185:         block->vsFree.prev->vsFree.next = block->vsFree.next;
 186:     }
 187: 
 188:     /* Link the block into the free list */
 189: 
 190:     block->vsFreeFlag = VS_FREE;
 191:     block->vsFree.next = listhead.vsFree.next;
 192:     block->vsFree.prev = &listhead;
 193:     listhead.vsFree.next->vsFree.prev = block;
 194:     listhead.vsFree.next = block;
 195: }
 196: 
 197: /* Boring routines to manage the allocation of the memory area descriptors
 198:  * on the Vax.
 199:  */
 200: 
 201: static VSArea *freeVSAreaHead = NULL;
 202: #define alloc_at_once 10
 203: 
 204: VSArea *AllocVSArea()
 205: {
 206:     register VSArea *block;
 207:     register int i;
 208: 
 209:     if ((block = freeVSAreaHead) == NULL) {
 210:         block = (VSArea *) Xalloc (alloc_at_once * sizeof (VSArea));
 211:         freeVSAreaHead = block;
 212:         i = alloc_at_once;
 213:         while (--i)
 214:         block = block->next = block + 1;
 215:         block->next = NULL;
 216:         block = freeVSAreaHead;
 217:     }
 218:     freeVSAreaHead = block->next;
 219: 
 220:     return (block);
 221: }
 222: 
 223: FreeVSArea(block)
 224:     VSArea *block;
 225: {
 226:     block->next = freeVSAreaHead;
 227:     freeVSAreaHead = block;
 228: }

Defined functions

AllocVSArea defined in line 204; used 5 times
FreeVSArea defined in line 223; used 2 times
VSAlloc defined in line 116; used 6 times
VSFree defined in line 160; used 2 times
VSMemInit defined in line 50; used 1 times

Defined variables

freeVSAreaHead defined in line 201; used 6 times
listhead defined in line 46; used 16 times

Defined macros

alloc_at_once defined in line 202; used 2 times
slopsize defined in line 44; used 1 times
Last modified: 1986-02-01
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1156
Valid CSS Valid XHTML 1.0 Strict