Subversion Repositories Code-Repo

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
141 Kevin 1
/*
2
 * memlib.c - a module that simulates the memory system.  Needed because it 
3
 *            allows us to interleave calls from the student's malloc package 
4
 *            with the system's malloc package in libc.
5
 */
6
#include <stdio.h>
7
#include <stdlib.h>
8
#include <assert.h>
9
#include <unistd.h>
10
#include <sys/mman.h>
11
#include <string.h>
12
#include <errno.h>
13
 
14
#include "memlib.h"
15
#include "config.h"
16
 
17
/* private variables */
18
static char *mem_start_brk;  /* points to first byte of heap */
19
static char *mem_brk;        /* points to last byte of heap */
20
static char *mem_max_addr;   /* largest legal heap address */ 
21
static int use_mmap;         /* Use mmap instead of malloc */
22
static void * mmap_addr = (void *)0x58000000;
23
 
24
/* 
25
 * mem_init - initialize the memory system model
26
 */
27
void mem_init(int _use_mmap)
28
{
29
    use_mmap = _use_mmap;
30
 
31
    /* allocate the storage we will use to model the available VM */
32
    if (use_mmap) {
33
        mem_start_brk = (char *)mmap(mmap_addr, MAX_HEAP, PROT_READ|PROT_WRITE, 
34
                                 MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
35
        if (mem_start_brk == MAP_FAILED) {
36
            perror("mem_init_vm: mmap error:");
37
            exit(1);
38
        }
39
        if (mem_start_brk != mmap_addr) {
40
            perror("mmap");
41
            fprintf(stderr, 
42
                "mem_init_vm: could not obtain memory at address %p\n", 
43
                mmap_addr);
44
            exit(1);
45
        }
46
    } else {
47
        if ((mem_start_brk = (char *)malloc(MAX_HEAP)) == NULL) {
48
            fprintf(stderr, "mem_init_vm: malloc error\n");
49
            exit(1);
50
        }
51
    }
52
 
53
    mem_max_addr = mem_start_brk + MAX_HEAP;  /* max legal heap address */
54
    mem_brk = mem_start_brk;                  /* heap is empty initially */
55
}
56
 
57
/* 
58
 * mem_deinit - free the storage used by the memory system model
59
 */
60
void mem_deinit(void)
61
{
62
    if (use_mmap) {
63
        if (munmap(mem_start_brk, MAX_HEAP))
64
            perror("munmap");
65
    } else {
66
        free(mem_start_brk);
67
    }
68
}
69
 
70
/*
71
 * mem_reset_brk - reset the simulated brk pointer to make an empty heap
72
 */
73
void mem_reset_brk()
74
{
75
    mem_brk = mem_start_brk;
76
}
77
 
78
/* 
79
 * mem_sbrk - simple model of the sbrk function. Extends the heap 
80
 *    by incr bytes and returns the start address of the new area. In
81
 *    this model, the heap cannot be shrunk.
82
 */
83
void *mem_sbrk(int incr) 
84
{
85
    char *old_brk = mem_brk;
86
 
87
    if ( (incr < 0) || ((mem_brk + incr) > mem_max_addr)) {
88
	errno = ENOMEM;
89
	fprintf(stderr, "ERROR: mem_sbrk failed. Ran out of memory...\n");
90
	return NULL;
91
    }
92
    mem_brk += incr;
93
    return (void *)old_brk;
94
}
95
 
96
/*
97
 * mem_heap_lo - return address of the first heap byte
98
 */
99
void *mem_heap_lo()
100
{
101
    return (void *)mem_start_brk;
102
}
103
 
104
/* 
105
 * mem_heap_hi - return address of last heap byte
106
 */
107
void *mem_heap_hi()
108
{
109
    return (void *)(mem_brk - 1);
110
}
111
 
112
/*
113
 * mem_heapsize() - returns the heap size in bytes
114
 */
115
size_t mem_heapsize() 
116
{
117
    return (size_t)(mem_brk - mem_start_brk);
118
}
119
 
120
/*
121
 * mem_pagesize() - returns the page size of the system
122
 */
123
size_t mem_pagesize()
124
{
125
    return (size_t)getpagesize();
126
}