Skip to content

Commit fd719b7

Browse files
committed
add custom allocator test
1 parent 34940da commit fd719b7

5 files changed

Lines changed: 188 additions & 0 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
{
2+
"transfer_files": [
3+
"bin/DEMO.8xp"
4+
],
5+
"target": {
6+
"name": "DEMO",
7+
"isASM": true
8+
},
9+
"sequence": [
10+
"action|launch",
11+
"delay|1000",
12+
"hashWait|1",
13+
"key|enter",
14+
"delay|400",
15+
"hashWait|2",
16+
"key|enter",
17+
"delay|400",
18+
"hashWait|3",
19+
"key|enter",
20+
"delay|400",
21+
"hashWait|4"
22+
],
23+
"hashes": {
24+
"1": {
25+
"description": "calloc should clear the memory from custom malloc",
26+
"start": "vram_start",
27+
"size": "vram_16_size",
28+
"expected_CRCs": [
29+
"8CC9FD0C"
30+
]
31+
},
32+
"2": {
33+
"description": "we expect malloc to be called twice (for calloc and atexit)",
34+
"start": "vram_start",
35+
"size": "vram_16_size",
36+
"expected_CRCs": [
37+
"C1BC5A5C"
38+
]
39+
},
40+
"3": {
41+
"description": "custom free should print a custom message",
42+
"start": "vram_start",
43+
"size": "vram_16_size",
44+
"expected_CRCs": [
45+
"BD82EEA3"
46+
]
47+
},
48+
"4": {
49+
"description": "Exit",
50+
"start": "vram_start",
51+
"size": "vram_16_size",
52+
"expected_CRCs": [
53+
"FFAF89BA",
54+
"101734A5",
55+
"9DA19F44",
56+
"A32840C8",
57+
"349F4775"
58+
]
59+
}
60+
}
61+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# ----------------------------
2+
# Makefile Options
3+
# ----------------------------
4+
5+
NAME = DEMO
6+
ICON = icon.png
7+
DESCRIPTION = "CE C Toolchain Demo"
8+
COMPRESSED = NO
9+
ARCHIVED = NO
10+
11+
CFLAGS = -Wall -Wextra -Wshadow -Oz
12+
CXXFLAGS = -Wall -Wextra -Wshadow -Oz
13+
14+
PREFER_OS_LIBC = NO
15+
PREFER_OS_CRT = NO
16+
HAS_PRINTF = NO
17+
ALLOCATOR = CUSTOM
18+
19+
# ----------------------------
20+
21+
include $(shell cedev-config --makefile)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.assume adl=1
2+
3+
.section .rodata._free_string
4+
.local _free_string
5+
_free_string:
6+
.asciz "called free"
7+
8+
.section .text._free
9+
.global __custom_free
10+
.type __custom_free, @function
11+
__custom_free:
12+
ld hl, _free_string
13+
push hl
14+
call _puts
15+
pop hl
16+
.L.wait_loop:
17+
call _os_GetCSC
18+
or a, a
19+
jr z, .L.wait_loop
20+
ret
21+
22+
.extern _puts
23+
.extern _os_GetCSC
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <string.h>
2+
#include <stdlib.h>
3+
4+
static unsigned char arr[4096];
5+
6+
static unsigned char *arr_ptr = &arr[0];
7+
8+
int malloc_calls = 0;
9+
10+
void *_custom_malloc(size_t size) __attribute__((__malloc__));
11+
12+
void *_custom_malloc(size_t size) {
13+
if (size >= sizeof(arr)) {
14+
return NULL;
15+
}
16+
unsigned char *ret = arr_ptr;
17+
arr_ptr += size;
18+
memset(ret, 0xAA, size);
19+
malloc_calls++;
20+
return ret;
21+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
#include <ti/screen.h>
2+
#include <ti/getcsc.h>
3+
#include <ti/sprintf.h>
4+
#include <stdio.h>
5+
#include <stdlib.h>
6+
7+
extern int malloc_calls;
8+
9+
void atexit_func(void) {
10+
/*
11+
* The custom free function is supposed to print a string if it is called,
12+
* however, it is unspecified if atexit_func or free will be called first.
13+
* This means that we cannot print anything in this function since we
14+
* cannot guarantee the order. However, this function must be non-empty so
15+
* Clang does not optimize away the call to atexit. Now some of this could
16+
* be fixed with -ffreestanding, but that may also hide the assumptions
17+
* that Clang makes.
18+
*/
19+
if (*(const char*)-1 != 0) {
20+
puts("0xFFFFFF should be zero");
21+
while (!os_GetCSC());
22+
}
23+
}
24+
25+
int main(void) {
26+
char buf[50];
27+
os_ClrHome();
28+
29+
// CRT0 may use malloc/free so we cannot assume this is zero
30+
int malloc_calls_before = malloc_calls;
31+
32+
// calloc should call the custom malloc
33+
int *ptr = calloc(1, sizeof(int[3]));
34+
35+
if (ptr == NULL) {
36+
puts("calloc failed");
37+
while (!os_GetCSC());
38+
return 0;
39+
}
40+
41+
for (int n = 0; n < 3; ++n) {
42+
boot_sprintf(buf, "ptr(%d) == %d", n, ptr[n]);
43+
puts(buf);
44+
}
45+
46+
while (!os_GetCSC());
47+
48+
if (atexit(atexit_func) != 0) {
49+
puts("atexit(atexit_func) failed");
50+
while (!os_GetCSC());
51+
return 0;
52+
}
53+
54+
// we expect malloc to be called twice (for calloc and atexit)
55+
int malloc_call_count = malloc_calls - malloc_calls_before;
56+
boot_sprintf(buf, "malloc calls: %d", malloc_call_count);
57+
puts(buf);
58+
59+
while (!os_GetCSC());
60+
61+
exit(EXIT_SUCCESS);
62+
}

0 commit comments

Comments
 (0)