aboutsummaryrefslogtreecommitdiff
path: root/malloclab-handout/util/mm-implicit.h
blob: 64b2eaaf22f2efd9c2ce378cb92ae70088bb35ab (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111

#pragma once

#include <cstring>

#include "../mm.h"
#include "../memlib.h"


using namespace std;

/* single word (4) or double word (8) alignment */
#define ALIGNMENT 8

/* rounds up to the nearest multiple of ALIGNMENT */
inline size_t align(size_t size)
{
    return (((size) + (ALIGNMENT-1)) & ~0x7);
}

inline constexpr size_t SIZE_T_SIZE = 8;

inline bool is_alloc(size_t status)
{
    return (status&0x1);
}
inline bool is_prev_alloc(size_t status)
{
    return (status&0x2) >> 1;
}
inline void set_alloc(size_t &status, bool is_alloc)
{
    if (is_alloc)
        status |= 0x1;
    else
        status &= 0xfffffffe;
}
inline void set_prev_alloc(size_t &status, bool is_prev_alloc)
{
    if (is_prev_alloc)
        status |= 0x2;
    else
        status &= 0xfffffffd;
}
inline size_t get_size(size_t status)
{
    // ignore lowest 2 bits
    return status&0xfffffffc;
}
inline void set_size(size_t &status, size_t size)
{
    status &= 0x3;
    status |= (size & 0xfffffffc);
}
inline size_t offset(size_t p)
{
    return (size_t)((size_t)p-(size_t)mem_heap_lo());
}
inline void next(size_t &p)
{
    p += get_size(*(size_t*)p);
}

template< class... Args >
void loggerln( std::format_string<Args...> fmt, Args&&... args ) 
{ 
#ifdef OV4_VERBOSE
    println(fmt, forward<Args>(args)...); 
#endif
}

template< class... Args >
inline void logger( std::format_string<Args...> fmt, Args&&... args ) 
{ 
#ifdef OV4_VERBOSE
    print(fmt, forward<Args>(args)...); 
    fflush(stdout);
#endif
}


inline void print_list()
{
#ifdef OV4_VERBOSE
    logger("print_list: ");
    size_t p = (size_t)mem_heap_lo();
    while (true)
    {
        if (p >= (size_t)mem_heap_hi())
            break;
        
        logger("{}({},{}) ", offset(p), is_alloc(*(size_t*)p) ? "alloc" : "free", get_size(*(size_t*)p));
        p += get_size(*(size_t*)p);
    }
    loggerln("");
#endif  
}

inline void sync_footer(size_t header)
{
    size_t footer = header + get_size(*(size_t*)header) - SIZE_T_SIZE;
    *(size_t*)footer = *(size_t*)header;
}

inline size_t stat_pack(size_t size, bool alloc, bool prev_alloc)
{
    size_t status = 0;
    set_size(status, size);
    set_alloc(status, alloc);
    set_prev_alloc(status, prev_alloc);
    return status;
}