aboutsummaryrefslogblamecommitdiff
path: root/8.8/malloc.c
blob: df91a2d1db371b62389ae1bf4d40a3d7bfba0267 (plain) (tree)





















































































































































                                                                             
#include <unistd.h>
#include <stdio.h>
#include "malloc.h"

#define NALLOC		128
#define MAX_BYTES	(size_t) 8192

typedef long long Align;

typedef union header {
	struct {
		union header *ptr;
		size_t size;
	} s;

	Align x;
} Header;

/* see my_free
 * static size_t maxalloc; */
static Header base;
static Header *freep = NULL;

/* static Header *my_morecore(size_t nunits); */

void *my_calloc(size_t n ,size_t size)
{
	char *p, *temp;
	size_t nb;

	nb = n * size;
	if ((p = temp = my_malloc(nb)) == NULL)
		while (nb-- > 0)
			*temp++ = '\0';

	return p;
}

void *my_malloc(size_t nbytes)
{
	Header *prevp, *p;
	size_t nunits;

	if (nbytes > MAX_BYTES) {
		fprintf(stderr, "alloc:can't allocate more than %lu bytes\n",
		      MAX_BYTES);
		return NULL;
	}

	if ((prevp = freep) == NULL) {
		base.s.ptr = prevp = freep = &base;
		base.s.size = 0;
	}

	nunits = (nbytes + sizeof(Header) - 1) / sizeof(Header) + 1;
	for (p = freep->s.ptr; ; prevp = p, p = p->s.ptr) {
		if (p->s.size >= nunits) {
			if (p->s.size == nunits) {
				prevp->s.ptr = p->s.ptr;
			} else {
				p->s.size -= nunits;
				p += p->s.size;
				p->s.size = nunits;
			}

			freep = prevp;
			return (void *)(p + 1);
		}

		if (p == freep)
			/* if ((p = my_morecore(nunits)) == NULL) \
			* we fully rely on mem from stdlib malloc */
			return NULL;
	}

	return NULL;
}

/* see my_free
 * static Header *my_morecore(size_t nunits)
 *{
 *	Header *p;
 *
 *	if (nunits < NALLOC)
 *		nunits = NALLOC;
 *
 *	if ((p = sbrk(nunits * sizeof(Header))) == (Header *) -1)
 *		return NULL;
 *
 *	p->s.size = nunits;
 *	if ((p->s.size = nunits) > maxalloc)
 *	 	maxalloc = nunits;
 *
 *	my_free (p + 1);
 *	return freep;
 * } */

void my_free(void *ap)
{
	Header *bp, *p;

	bp = (Header *)ap - 1;

	if (freep == NULL) {
		base.s.ptr = freep = &base;
		base.s.size = 0;
	}

	/* we accept random values from bfree 
	 * if (bp->s.size == 0 || bp->s.size > maxalloc) {
	 *	fprintf(stderr, "alloc: can't free %lu units\n", bp->s.size);
	 *	return;
	 * } */

	for (p = freep; !(bp > p && bp < p->s.ptr) ; p = p->s.ptr)
		if (p >= p->s.ptr && (bp > p || bp < p->s.ptr))
			break;

	if (bp + bp->s.size == p->s.ptr) {
		bp->s.size += p->s.ptr->s.size;
		bp->s.ptr = p->s.ptr->s.ptr;
	} else {
		bp->s.ptr = p->s.ptr;
	}

	if (p + p->s.size == bp) {
		p->s.size += bp->s.size;
		p->s.ptr = bp->s.ptr;
	} else {
		p->s.ptr = bp;
	}

	freep = p;
}

size_t bfree(void *ap, size_t n)
{
	Header *p;

	if (n < sizeof(Header) * 2) {
		fprintf(stderr, "bfree: can't free %lu bytes\n", n);
		return 0;
	}

	p = (Header *) ap;
	p->s.size = (n / sizeof(Header));
	my_free(p + 1);

	return p->s.size;
}