123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 |
- /*
- * File: - dis.c
- *
- * dispose() built in standard procedure in Pascal (6.6.5.3)
- *
- * Re-implementation of storage allocator for Ack Pascal compiler
- * under Linux, and other UNIX-like systems.
- *
- * Written by Erik Backerud, 2010-10-01
- *
- * Original copyright and author info below:
- */
- /* $Id$ */
- /*
- * (c) copyright 1983 by the Vrije Universiteit, Amsterdam, The Netherlands.
- *
- * This product is part of the Amsterdam Compiler Kit.
- *
- * Permission to use, sell, duplicate or disclose this software must be
- * obtained in writing. Requests for such permissions may be sent to
- *
- * Dr. Andrew S. Tanenbaum
- * Wiskundig Seminarium
- * Vrije Universiteit
- * Postbox 7161
- * 1007 MC Amsterdam
- * The Netherlands
- *
- */
- /* Author: J.W. Stevenson */
- #include <pc_err.h>
- #define assert() /* nothing */
- /*
- * use a singly linked list of free blocks.
- */
- struct adm {
- struct adm *next;
- int size;
- };
- struct adm *freep = 0; /* first element on free list */
- extern void _trp(int);
- /*
- * Dispose
- * Called with two arguments:
- * n the size of the block to be freed, in bytes,
- * pp address of pointer to data.
- */
- void
- _dis(int n, struct adm **pp)
- {
- struct adm *block; /* the block of data being freed (inc. header) */
- struct adm *p, *q;
- if (*pp == 0) {
- _trp(EFREE);
- }
- block = *pp - 1;
- if (freep == 0) {
- freep = block;
- block->next = 0;
- } else {
- q = 0; /* trail one behind */
- for (p = freep; p < block; p = p->next) {
- if (p == 0) { /* We reached the end of the free list. */
- break;
- }
- q = p;
- /* check if block is contained in the free block p */
- if (p+p->size > block) {
- _trp(EFREE);
- }
- }
- if (p == block) { /* this block already freed */
- _trp(EFREE);
- }
- if (q == 0) { /* block is first */
- freep = block;
- block->next = p;
- } else {
- q->next = block;
- }
- block->next = p;
- /* merge with successor on free list? */
- if (block + block->size == p) {
- block->size = block->size + p->size;
- block->next = p->next;
- }
- /* merge with preceding block on free list? */
- if (q != 0 && q+q->size == block) {
- q->size = q->size + block->size;
- q->next = block->next;
- }
- }
- } /* _dis */
|