1. File Header and Includes
c
복사편집
/*--------------------------------------------------------------------*/
/* heapmgr1.c (from heapmrgbase.c) */
/* Author: Donghwi Kim, KyoungSoo Park, Kim Chanwoo */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "chunk.h"
- Lines 1–4: File name, origin, authors.
- Lines 6–8: Pulls in:
<stdio.h>
for fprintf()
.
<stdlib.h>
for exit()
, size_t
.
<assert.h>
for runtime sanity checks.
- Line 10: Includes our opaque chunk API.
2. Constants & Globals
c
복사편집
#define FALSE 0
#define TRUE 1
enum {
MEMALLOC_MIN = 1024,
};
/* g_free_head: head of the free‑chunk list */
static Chunk_T g_free_head = NULL;
/* g_heap_start, g_heap_end: current heap bounds */
static void *g_heap_start = NULL, *g_heap_end = NULL;
FALSE
/TRUE
: Simple boolean constants.
MEMALLOC_MIN
: Minimum number of units to request from the OS at once (to avoid tiny sbrk calls).
g_free_head
: Points to the first free chunk (a singly‑linked list via chunk_get_next_free_chunk
).
g_heap_start
/g_heap_end
: Track the start and end of the heap region as returned by sbrk(0)
.
3. Debug: check_heap_validity
c
복사편집
#ifndef NDEBUG
static int check_heap_validity(void) {
Chunk_T w;
if (g_heap_start == NULL) {
fprintf(stderr, "Uninitialized heap start\\n");
return FALSE;
}
if (g_heap_end == NULL) {
fprintf(stderr, "Uninitialized heap end\\n");
return FALSE;
}
if (g_heap_start == g_heap_end) {
if (g_free_head == NULL) return TRUE;
fprintf(stderr, "Inconsistent empty heap\\n");
return FALSE;
}
/* Walk every chunk in memory, ensure it's valid */
for (w = (Chunk_T)g_heap_start; w && w < (Chunk_T)g_heap_end;
w = chunk_get_next_adjacent(w, g_heap_start, g_heap_end)) {
if (!chunk_is_valid(w, g_heap_start, g_heap_end))
return FALSE;
}
/* Walk free‑list, ensure chunks are flagged free, valid, and coalesced */
for (w = g_free_head; w; w = chunk_get_next_free_chunk(w)) {
if (chunk_get_status(w) != CHUNK_FREE) {
fprintf(stderr, "Non-free chunk in the free chunk list\\n");
return FALSE;
}
if (!chunk_is_valid(w, g_heap_start, g_heap_end))
return FALSE;
Chunk_T n = chunk_get_next_adjacent(w, g_heap_start, g_heap_end);
if (n != NULL && n == chunk_get_next_free_chunk(w)) {
fprintf(stderr, "Uncoalesced chunks\\n");
return FALSE;
}
}
return TRUE;
}
#endif
4. Utility Functions
4.1 size_to_units
c
복사편집
static size_t size_to_units(size_t size) {
return (size + (CHUNK_UNIT-1)) / CHUNK_UNIT;
}
- Converts a byte‐count request into the number of
CHUNK_UNIT
‑sized units needed (rounding up).