🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.sys.amiga.tech
Article #3203

Re: Manx-C and realloc()

#3203
From: Frank J. Edwards
Date: Sat, 07 Apr 1990 14:28
186 lines
4758 bytes
>I am using Manx 3.6a, and had the need for realloc() the other
>day.  Unfortunately the linker couldn't find it, and neither could I!
>
>I am using 16 bit ints.  realloc() doesn't seem to be in c.lib, or
>heapmem.o.  I seem to recall that this has been discussed several times
>before in this group, but I don't remember the answer.
>
>Sorry for the duplication, but where is realloc()???
>
>Nick
>ng@maxwell.physics.purdue.edu

The realloc() routine is in heapmem.o in your Library directory.  There
are multiple versions, i.e. ".o32", ".ol32", etc, for each of the memory
models.

However, there's a bug in the 16-bit int version.  Use the one included
here instead.  This came from the Manx BBS, so it shouldn't be a problem
to post it here.  You will need to compile it once for each memory model
that you intend to use.

Good Luck!!!

----- cut here ----- cut here ----- cut here ----- cut here -----
/* Copyright (C) 1987 by Manx Software Systems, Inc. */

unsigned long _Heapsize = 40 * 1024L;

typedef long size_t;
#define bump(p,i) ((l_t *)((char *)(p)+(i)))
#define ptrdiff(p1,p2) (unsigned long)((char *)(p1)-(char *)(p2))

typedef struct list {
	struct list *next;
} l_t;

static l_t first, *current;
static l_t *endmarker = &first, *restart = &first;
static size_t keep;

#define INUSE	1
#define inuse(p) (*(size_t *)(p)&INUSE)
#define markblk(p) (*(size_t *)(p) |= INUSE)
#define unmark(p) (*(size_t *)(p) &= ~INUSE)
#define chain(p)	((l_t *)(*(size_t *)(p) & ~INUSE))

#define BLOCK	(512*sizeof(l_t))	/* # of bytes to ask sbrk for */

char *realloc(area, size)
register char *area; unsigned size;
{
	register char *cp, *end;
	size_t osize;
	char *malloc();

	end = (char *)chain((l_t *)area-1);
	if ((osize = ptrdiff(end, area)) > size) {
		osize = size;
		end = (char *)bump(area, osize);
	}
	free(area);
	if ((cp = malloc(size)) != 0 && cp != area) {
		movmem(area, cp, (int) osize);
		/*               ^^^^^  THE BUG!  This was missing! */
		if ((char *)current >= area && (char *)current < end)
			*(size_t *)bump(cp, ptrdiff(current,area)) = keep;
	}
	return cp;
}

char *lmalloc(size)
unsigned long size;
{
	register l_t *ptr, *temp, *lastfree;
	register size_t len;
	int times;
	char *sbrk();

	size = ((size+sizeof(l_t)*2-1)/sizeof(l_t))*sizeof(l_t);
	if (current == 0) {
		first.next = &first;
		markblk(&first);
		current = &first;
	}
	for (times = 0, lastfree = ptr = current ; ; ptr = chain(ptr)) {
		if (ptr == endmarker) {
			if (++times > 1) {
				len = BLOCK;
				if ((temp = (l_t *)sbrk((int)len)) == (l_t *)-1)
					return 0;
				if (temp != bump(ptr,sizeof(l_t))) {
					/* non-contiguous allocation */
					ptr->next = temp;
					markblk(ptr);
					len -= sizeof(l_t);
					ptr = temp;
				}
				temp = bump(ptr, len);
				ptr->next = temp;
				temp->next = &first;	/* new end marker */
				markblk(temp);
				endmarker = temp;
				if (chain(lastfree) == ptr)
					ptr = lastfree;
			}
		}
		if (inuse(ptr))
			continue;
		lastfree = ptr;
		while (!inuse(temp = chain(ptr)))
			ptr->next = temp->next;
		len = ptrdiff(temp,ptr);
		if (len >= size) {
			if (len > size) {
				ptr->next = bump(ptr, size);
				keep = *(size_t *)ptr->next;
				ptr->next->next = temp;
			}
			current = ptr->next;
			markblk(ptr);
			return (char *)(ptr+1);
		}
	}
}

char *malloc(size)
unsigned size;
{
	return(lmalloc((unsigned long)size));
}

free(p)
char *p;
{
	register l_t *ptr;

	ptr = (l_t *)p - 1;
	if (!inuse(ptr))
		return -1;
	unmark(ptr);
	current = ptr;
	return 0;
}

#include	<exec/types.h>
#include	<exec/memory.h>

char *AllocMem();

static char *data;
static size_t amt;

static cleanup()
{
	FreeMem(data, amt);
	data = 0;
}

char *sbrk(size)
unsigned size;
{
	register char *cp;
	static char *ptr;
	extern int (*_cln)();

	if (size&1)
		size++;
	if (data == 0) {
		_cln = cleanup;
		amt = _Heapsize;
		while ((data = AllocMem(amt, 0L)) == 0)
			amt -= 1024;
		ptr = data;
	}
	if (ptr+size >= data+amt)
		return(-1);
	cp = ptr;
	ptr += size;
	return(cp);
}
----- cut here ----- cut here ----- cut here ----- cut here -----
-----
Frank J. Edwards		ComputerKnowledge Corp
2677 Arjay Court		12740 Hillcrest, Suite 212
Palm Harbor, FL  34684-4505	Dallas, TX  75230
Phone:  (813) 786-3675		(214) 385-9700 / (800) 227-9700
Technical Details
Message-ID: <90.04.08.10.58.59.535@ckctpa.UUCP>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!pdn!palan!ckctpa

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!pdn!palan!ckctpa
From: crash@ckctpa.UUCP (Frank J. Edwards)
Newsgroups: comp.sys.amiga.tech
Subject: Re: Manx-C and realloc()
Message-ID: <90.04.08.10.58.59.535@ckctpa.UUCP>
Date: 7 Apr 90 14:28:59 GMT
Organization: Nah, impossible!
Lines: 186