~pbatch/patchwerk

patchwerk/memory.w -rw-r--r-- 2.4 KiB
9c265356 — paul plan9 additions from Sigrid 3 months ago
                                                                                
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
@** Memory Handling.

Many parts of Patchwerk require dynamically allocated memory. When porting
the Patchwerk API to other languages and systems, memory allocation schemes
may need to change. For example, bindings to a scripting language like
Lua may want to take advantage of that garbage collector.

This section describes the memory allocation system process.

@<Top@>+=
@<Memory Handling@>

@ The memory handling functions in Patchwerk are |pw_memory_alloc| and
|pw_memory_free| for allocating and freeing memory, respectively.

The function |pw_memory_alloc| will allocate a chunk of memory that is
|size| bytes and store it in the the pointer address in |ud|.

The function |pw_memory_free| will free a chunk of memory in |ud| previously
allocated by |pw_memory_alloc|.

@<Header@>+=
int pw_memory_alloc(pw_patch *p, size_t size, void **ud);
int pw_memory_free(pw_patch *p, void **ud);

@
@<Memory Handling@>+=
int pw_memory_alloc(pw_patch *p, size_t size, void **ud)
{
    void *ptr;

    ptr = malloc(size);

    if(ptr == NULL) return PW_NOT_OK;

    *ud = ptr;
    return PW_OK;
}

int pw_memory_free(pw_patch *p, void **ud)
{
    free(*ud);
    return PW_OK;
}

@ Internally, these functions call on internal function pointers which
are stored in the top-level |pw_patch| struct.

@<Variables in Patch Data@>+=
pw_mallocfun malloc;
pw_freefun free;

@ These function callbacks mirror |pw_memory_alloc| and |pw_memory_free|.

@<Type Declarations@>+=
typedef int (*pw_mallocfun)(pw_patch *, size_t, void **);
typedef int (*pw_freefun)(pw_patch *, void **);

@ These two functions can be overridden by the user at init-time. With
the function |pw_memory_override|.

@<Header@>+=
void pw_memory_override(pw_patch *p, pw_mallocfun m, pw_freefun f);

@
@<Memory Handling@>+=
void pw_memory_override(pw_patch *p, pw_mallocfun m, pw_freefun f)
{
    p->malloc = m;
    p->free = f;
}

@ If left alone, the default memory allocation functions are wrappers
around |free| and |malloc|. This can also be set with the function
|pw_memory_defaults|.

@<Header@>+=
void pw_memory_defaults(pw_patch *p);

@
@<Memory Handling@>+=
static int default_malloc(pw_patch *p, size_t size, void **ud)
{
    void *ptr;

    ptr = malloc(size);

    if(ptr == NULL) return PW_NOT_OK;

    *ud = ptr;
    return PW_OK;
}

static int default_free(pw_patch *p, void **ud)
{
    free(*ud);
    return PW_OK;
}


void pw_memory_defaults(pw_patch *p)
{
    pw_memory_override(p, default_malloc, default_free);
}