1 | #include <string.h> |
2 | #include <glib.h> |
3 | |
4 | /* We test deprecated functionality here */ |
5 | G_GNUC_BEGIN_IGNORE_DEPRECATIONS |
6 | |
7 | #ifdef G_ENABLE_DEBUG |
8 | static void |
9 | test_slice_nodebug (void) |
10 | { |
11 | const gchar *oldval; |
12 | |
13 | oldval = g_getenv (variable: "G_SLICE" ); |
14 | g_unsetenv (variable: "G_SLICE" ); |
15 | |
16 | if (g_test_subprocess ()) |
17 | { |
18 | gpointer p, q; |
19 | |
20 | p = g_slice_alloc (block_size: 237); |
21 | q = g_slice_alloc (block_size: 259); |
22 | g_slice_free1 (block_size: 237, mem_block: p); |
23 | g_slice_free1 (block_size: 259, mem_block: q); |
24 | |
25 | g_slice_debug_tree_statistics (); |
26 | return; |
27 | } |
28 | g_test_trap_subprocess (NULL, usec_timeout: 1000000, test_flags: 0); |
29 | g_test_trap_assert_passed (); |
30 | g_test_trap_assert_stderr ("*GSlice: MemChecker: root=NULL*" ); |
31 | |
32 | if (oldval) |
33 | g_setenv (variable: "G_SLICE" , value: oldval, TRUE); |
34 | } |
35 | |
36 | static void |
37 | test_slice_debug (void) |
38 | { |
39 | const gchar *oldval; |
40 | |
41 | oldval = g_getenv (variable: "G_SLICE" ); |
42 | g_setenv (variable: "G_SLICE" , value: "debug-blocks:always-malloc" , TRUE); |
43 | |
44 | if (g_test_subprocess ()) |
45 | { |
46 | gpointer p, q; |
47 | |
48 | p = g_slice_alloc (block_size: 237); |
49 | q = g_slice_alloc (block_size: 259); |
50 | g_slice_free1 (block_size: 237, mem_block: p); |
51 | g_slice_free1 (block_size: 259, mem_block: q); |
52 | |
53 | g_slice_debug_tree_statistics (); |
54 | return; |
55 | } |
56 | g_test_trap_subprocess (NULL, usec_timeout: 1000000, test_flags: 0); |
57 | g_test_trap_assert_passed (); |
58 | g_test_trap_assert_stderr ("*GSlice: MemChecker: * trunks, * branches, * old branches*" ); |
59 | |
60 | if (oldval) |
61 | g_setenv (variable: "G_SLICE" , value: oldval, TRUE); |
62 | else |
63 | g_unsetenv (variable: "G_SLICE" ); |
64 | } |
65 | #endif |
66 | |
67 | static void |
68 | test_slice_copy (void) |
69 | { |
70 | const gchar *block = "0123456789ABCDEF" ; |
71 | gpointer p; |
72 | |
73 | p = g_slice_copy (block_size: 12, mem_block: block); |
74 | g_assert (memcmp (p, block, 12) == 0); |
75 | g_slice_free1 (block_size: 12, mem_block: p); |
76 | } |
77 | |
78 | typedef struct { |
79 | gint int1; |
80 | gint int2; |
81 | gchar byte; |
82 | gpointer next; |
83 | gint64 more; |
84 | } TestStruct; |
85 | |
86 | static void |
87 | test_chain (void) |
88 | { |
89 | TestStruct *ts, *head; |
90 | |
91 | head = ts = g_slice_new (TestStruct); |
92 | ts->next = g_slice_new (TestStruct); |
93 | ts = ts->next; |
94 | ts->next = g_slice_new (TestStruct); |
95 | ts = ts->next; |
96 | ts->next = NULL; |
97 | |
98 | g_slice_free_chain (TestStruct, head, next); |
99 | } |
100 | |
101 | static gpointer chunks[4096][30]; |
102 | |
103 | static gpointer |
104 | thread_allocate (gpointer data) |
105 | { |
106 | gint i; |
107 | gint b; |
108 | gint size; |
109 | gpointer p; |
110 | gpointer *loc; /* (atomic) */ |
111 | |
112 | for (i = 0; i < 10000; i++) |
113 | { |
114 | b = g_random_int_range (begin: 0, end: 30); |
115 | size = g_random_int_range (begin: 0, end: 4096); |
116 | loc = &(chunks[size][b]); |
117 | |
118 | p = g_atomic_pointer_get (loc); |
119 | if (p == NULL) |
120 | { |
121 | p = g_slice_alloc (block_size: size + 1); |
122 | if (!g_atomic_pointer_compare_and_exchange (loc, NULL, p)) |
123 | g_slice_free1 (block_size: size + 1, mem_block: p); |
124 | } |
125 | else |
126 | { |
127 | if (g_atomic_pointer_compare_and_exchange (loc, p, NULL)) |
128 | g_slice_free1 (block_size: size + 1, mem_block: p); |
129 | } |
130 | } |
131 | |
132 | return NULL; |
133 | } |
134 | |
135 | static void |
136 | test_allocate (void) |
137 | { |
138 | GThread *threads[30]; |
139 | gint size; |
140 | gsize i; |
141 | |
142 | for (i = 0; i < 30; i++) |
143 | for (size = 1; size <= 4096; size++) |
144 | chunks[size - 1][i] = NULL; |
145 | |
146 | for (i = 0; i < G_N_ELEMENTS(threads); i++) |
147 | threads[i] = g_thread_create (func: thread_allocate, NULL, TRUE, NULL); |
148 | |
149 | for (i = 0; i < G_N_ELEMENTS(threads); i++) |
150 | g_thread_join (thread: threads[i]); |
151 | } |
152 | |
153 | int |
154 | main (int argc, char **argv) |
155 | { |
156 | g_test_init (argc: &argc, argv: &argv, NULL); |
157 | |
158 | #ifdef G_ENABLE_DEBUG |
159 | g_test_add_func (testpath: "/slice/nodebug" , test_func: test_slice_nodebug); |
160 | g_test_add_func (testpath: "/slice/debug" , test_func: test_slice_debug); |
161 | #endif |
162 | g_test_add_func (testpath: "/slice/copy" , test_func: test_slice_copy); |
163 | g_test_add_func (testpath: "/slice/chain" , test_func: test_chain); |
164 | g_test_add_func (testpath: "/slice/allocate" , test_func: test_allocate); |
165 | |
166 | return g_test_run (); |
167 | } |
168 | |