|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.