Newer
Older
Import / applications / MakePDF / Tests / exip-0.5.4 / build / gcc / contiki / d_mem.c
/*
 * "Copyright (c) 2008, 2009 The Regents of the University  of California.
 * All rights reserved."
 *
 * Permission to use, copy, modify, and distribute this software and its
 * documentation for any purpose, without fee, and without written agreement is
 * hereby granted, provided that the above copyright notice, the following
 * two paragraphs and the author appear in all copies of this software.
 *
 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
 * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF
 * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS."
 *
 */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "d_mem.h"

uint8_t heap[D_MEM_HEAP_SIZE];

uint16_t memUsage = 0;

void d_malloc_init() {
  bndrt_t *b = (bndrt_t *)heap;
  *b = D_MEM_HEAP_SIZE  & D_MEM_LEN;
}

uint16_t getMemUsage()
{
	uint16_t tmpUsg = memUsage;
	memUsage = 0;
	return tmpUsg;
}

void* d_malloc(uint16_t sz) {
  bndrt_t* cur = (bndrt_t*) heap;
  sz += sizeof(bndrt_t) * 2;
  sz += (sz % D_MEM_ALIGN);

  while (((*cur & D_MEM_LEN) < sz || (*cur & D_MEM_INUSE) != 0)
         && (uint8_t *)cur - heap < D_MEM_HEAP_SIZE) {
    cur = (bndrt_t *)(((uint8_t *)cur) + ((*cur) & D_MEM_LEN));
  }

  if ((uint8_t *)cur < heap + D_MEM_HEAP_SIZE) {
	  bndrt_t oldsize = *cur & D_MEM_LEN;
    bndrt_t *next;
    sz -= sizeof(bndrt_t);
    next = ((bndrt_t *)(((uint8_t *)cur) + sz));

    *cur = (sz & D_MEM_LEN) | D_MEM_INUSE;
    *next = (oldsize - sz) & D_MEM_LEN;

    if(memUsage < D_MEM_HEAP_SIZE - d_malloc_freespace())
    {
    	memUsage = D_MEM_HEAP_SIZE - d_malloc_freespace();
    }
    return cur + 1;
  } else return NULL;
}

void d_free(void *ptr) {
  bndrt_t *prev = NULL, *cur, *next = NULL;
  cur = (bndrt_t *)heap;

  while (cur + 1 != ptr && (uint8_t *)cur - heap < D_MEM_HEAP_SIZE) {
    prev = cur;
    cur = (bndrt_t *)(((uint8_t *)cur) + ((*cur) & D_MEM_LEN));
  }
  if (cur + 1 == ptr) {
    next = (bndrt_t *)((*cur & D_MEM_LEN) + ((uint8_t *)cur));

    *cur &= ~D_MEM_INUSE;
    if ((((uint8_t *)next) - heap) < D_MEM_HEAP_SIZE &&
        (*next & D_MEM_INUSE) == 0) {
      *cur = (*cur & D_MEM_LEN) + (*next & D_MEM_LEN);
    }
    if (prev != NULL && (*prev & D_MEM_INUSE) == 0) {
      *prev = (*prev & D_MEM_LEN) + (*cur & D_MEM_LEN);
    }
  }
}

uint16_t d_malloc_freespace() {
  uint16_t ret = 0;
  bndrt_t *cur = (bndrt_t *)heap;

  while ((uint8_t *)cur - heap < D_MEM_HEAP_SIZE) {
    if ((*cur & D_MEM_INUSE) == 0)
      ret += *cur & D_MEM_LEN;
    cur = (bndrt_t *)(((uint8_t *)cur) + ((*cur) & D_MEM_LEN));
  }
  return ret;
}

void* d_realloc(void *ptr, uint16_t size)
{
	void* p_ptr = d_malloc(size);
	if(p_ptr == NULL)
		return NULL;

	memcpy(p_ptr, ptr, size);

	d_free(ptr);
	return p_ptr;
}