1 
2 #if defined(_WIN32) && !defined(_CRT_SECURE_NO_WARNINGS)
3 #  define _CRT_SECURE_NO_WARNINGS
4 #endif
5 
6 #include <rpmalloc.h>
7 #include <thread.h>
8 #include <test.h>
9 
10 #include <stdint.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include <string.h>
14 #include <math.h>
15 
16 static size_t _hardware_threads;
17 
18 static void
19 test_initialize(void);
20 
21 static int
test_fail(const char * reason)22 test_fail(const char* reason) {
23 	fprintf(stderr, "FAIL: %s\n", reason);
24 	return -1;
25 }
26 
27 static int
test_alloc(void)28 test_alloc(void) {
29 	void* p = malloc(371);
30 	if (!p)
31 		return test_fail("malloc failed");
32 	if ((rpmalloc_usable_size(p) < 371) || (rpmalloc_usable_size(p) > (371 + 16)))
33 		return test_fail("usable size invalid (1)");
34 	rpfree(p);
35 
36 	p = new int;
37 	if (!p)
38 		return test_fail("new failed");
39 	if (rpmalloc_usable_size(p) != 16)
40 		return test_fail("usable size invalid (2)");
41 	delete static_cast<int*>(p);
42 
43 	p = new int[16];
44 	if (!p)
45 		return test_fail("new[] failed");
46 	if (rpmalloc_usable_size(p) != 16*sizeof(int))
47 		return test_fail("usable size invalid (3)");
48 	delete[] static_cast<int*>(p);
49 
50 	printf("Allocation tests passed\n");
51 	return 0;
52 }
53 
54 static int
test_free(void)55 test_free(void) {
56 	free(rpmalloc(371));
57 	free(new int);
58 	free(new int[16]);
59 	printf("Free tests passed\n");
60 	return 0;
61 }
62 
63 static void
basic_thread(void * argp)64 basic_thread(void* argp) {
65 	(void)sizeof(argp);
66 	int res = test_alloc();
67 	if (res) {
68 		thread_exit(static_cast<uintptr_t>(res));
69 		return;
70 	}
71 	res = test_free();
72 	if (res) {
73 		thread_exit(static_cast<uintptr_t>(res));
74 		return;
75 	}
76 	thread_exit(0);
77 }
78 
79 static int
test_thread(void)80 test_thread(void) {
81 	uintptr_t thread[2];
82 	uintptr_t threadres[2];
83 
84 	thread_arg targ;
85 	memset(&targ, 0, sizeof(targ));
86 	targ.fn = basic_thread;
87 	for (int i = 0; i < 2; ++i)
88 		thread[i] = thread_run(&targ);
89 
90 	for (int i = 0; i < 2; ++i) {
91 		threadres[i] = thread_join(thread[i]);
92 		if (threadres[i])
93 			return -1;
94 	}
95 
96 	printf("Thread tests passed\n");
97 	return 0;
98 }
99 
100 int
test_run(int argc,char ** argv)101 test_run(int argc, char** argv) {
102 	(void)sizeof(argc);
103 	(void)sizeof(argv);
104 	test_initialize();
105 	if (test_alloc())
106 		return -1;
107 	if (test_free())
108 		return -1;
109 	if (test_thread())
110 		return -1;
111 	printf("All tests passed\n");
112 	return 0;
113 }
114 
115 #if (defined(__APPLE__) && __APPLE__)
116 #  include <TargetConditionals.h>
117 #  if defined(__IPHONE__) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)
118 #    define NO_MAIN 1
119 #  endif
120 #elif (defined(__linux__) || defined(__linux))
121 #  include <sched.h>
122 #endif
123 
124 #if !defined(NO_MAIN)
125 
126 int
main(int argc,char ** argv)127 main(int argc, char** argv) {
128 	return test_run(argc, argv);
129 }
130 
131 #endif
132 
133 #ifdef _WIN32
134 #include <Windows.h>
135 
136 static void
test_initialize(void)137 test_initialize(void) {
138 	SYSTEM_INFO system_info;
139 	GetSystemInfo(&system_info);
140 	_hardware_threads = static_cast<size_t>(system_info.dwNumberOfProcessors);
141 }
142 
143 #elif (defined(__linux__) || defined(__linux))
144 
145 static void
test_initialize(void)146 test_initialize(void) {
147 	cpu_set_t prevmask, testmask;
148 	CPU_ZERO(&prevmask);
149 	CPU_ZERO(&testmask);
150 	sched_getaffinity(0, sizeof(prevmask), &prevmask);     //Get current mask
151 	sched_setaffinity(0, sizeof(testmask), &testmask);     //Set zero mask
152 	sched_getaffinity(0, sizeof(testmask), &testmask);     //Get mask for all CPUs
153 	sched_setaffinity(0, sizeof(prevmask), &prevmask);     //Reset current mask
154 	int num = CPU_COUNT(&testmask);
155 	_hardware_threads = static_cast<size_t>(num > 1 ? num : 1);
156 }
157 
158 #else
159 
160 static void
test_initialize(void)161 test_initialize(void) {
162 	_hardware_threads = 1;
163 }
164 
165 #endif
166