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