summaryrefslogtreecommitdiff
path: root/410user/libmalloc/memlib.c
blob: 8332559668474ab94db3b7063bba389667b3960e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
/* This should look a lot like 15-213 support code.
 * Guess what...
 */

/* memlib.c - functions for modeling the memory system */
/* $begin memlib */

#include <stddef.h>
#include <stdio.h>
#include <syscall.h>

/* #define PAGE_SIZE       0x00001000 */
/* #define PAGE_ALIGN_MASK 0xFFFFF000 */
#define PAGE_ALIGN_MASK ((unsigned int) ~((unsigned int) (PAGE_SIZE-1)))

#ifndef NULL
#define NULL 0
#endif

/* private global variables */
static char *mem_max_addr;   /* max virtual address for the heap */
static char *mem_brkp; /* Simulated brk pointer */
static char *mem_alloctop; /* Maximum allocated address */

extern void *_end; /* The end of the ELF binary address space */

/* 
 * mem_init - initializes the memory system model
 */
void mem_init(int max_heap_addr)
{
  /* The max address for the heap. */
  mem_max_addr = (char*)max_heap_addr;
  mem_brkp = (char*)&_end + PAGE_SIZE;
  mem_brkp = (char*)((int)mem_brkp & PAGE_ALIGN_MASK);
  while (new_pages(mem_brkp, PAGE_SIZE))
    mem_brkp += PAGE_SIZE;
  mem_alloctop = mem_brkp + PAGE_SIZE;
}

/* 
 * mem_sbrk - simply uses the the sbrk function. Extends the heap 
 *    by incr bytes and returns the start address of the new area. In
 *    this model, the heap cannot be shrunk.
 */
void *mem_sbrk(int incr) 
{
    char *old_brk = mem_brkp;

    /* Error check the request. */
    if ( (incr < 0) || ((old_brk + incr) > mem_max_addr)) {
      return (void *)NULL;
    }

    if (old_brk + incr > mem_alloctop) {
      int allocincr = old_brk + incr - mem_alloctop;
      allocincr += PAGE_SIZE - 1;
      allocincr &= PAGE_ALIGN_MASK;

      /* Issue a SBRK for more memory. */
      if (new_pages((void*)mem_alloctop, allocincr)) {
	return (void *)NULL;
      }

      mem_alloctop += allocincr;
    }

    mem_brkp += incr;

    return (void *)old_brk;
}
/* $end memlib */