nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* slice-threadinit.c - test GSlice across g_thread_init |
2 | * Copyright (C) 2007 Tim Janik |
||
3 | * |
||
4 | * This work is provided "as is"; redistribution and modification |
||
5 | * in whole or in part, in any medium, physical or electronic is |
||
6 | * permitted without restriction. |
||
7 | * |
||
8 | * This work is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
11 | * |
||
12 | * In no event shall the authors or contributors be liable for any |
||
13 | * direct, indirect, incidental, special, exemplary, or consequential |
||
14 | * damages (including, but not limited to, procurement of substitute |
||
15 | * goods or services; loss of use, data, or profits; or business |
||
16 | * interruption) however caused and on any theory of liability, whether |
||
17 | * in contract, strict liability, or tort (including negligence or |
||
18 | * otherwise) arising in any way out of the use of this software, even |
||
19 | * if advised of the possibility of such damage. |
||
20 | */ |
||
21 | #include <glib.h> |
||
22 | |||
23 | #define N_PAGES (101) /* number of pages to sample */ |
||
24 | #define SAMPLE_SIZE (7) |
||
25 | #define PAGE_SIZE (128) /* must be <= minimum GSlice alignment block */ |
||
26 | #define MAGAZINE_PROBES { 97, 265, 347 } /* block sizes hopefully unused by g_thread_init */ |
||
27 | #define MAX_PROBE_TRIALS (1031) /* must be >= maximum magazine size */ |
||
28 | |||
29 | #define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base))) |
||
30 | |||
31 | static struct { |
||
32 | void *page; |
||
33 | void *sample; |
||
34 | } pages[N_PAGES] = { { NULL, }, }; |
||
35 | |||
36 | static const guint magazine_probes[] = MAGAZINE_PROBES; |
||
37 | #define N_MAGAZINE_PROBES G_N_ELEMENTS (magazine_probes) |
||
38 | |||
39 | static void |
||
40 | release_trash_list (GSList **trash_list, |
||
41 | gsize block_size) |
||
42 | { |
||
43 | while (*trash_list) |
||
44 | { |
||
45 | g_slice_free1 (block_size, (*trash_list)->data); |
||
46 | *trash_list = g_slist_delete_link (*trash_list, *trash_list); |
||
47 | } |
||
48 | } |
||
49 | |||
50 | static GSList *free_list = NULL; |
||
51 | |||
52 | static gboolean |
||
53 | allocate_from_known_page (void) |
||
54 | { |
||
55 | guint i, j, n_trials = N_PAGES * PAGE_SIZE / SAMPLE_SIZE; /* upper bound */ |
||
56 | for (i = 0; i < n_trials; i++) |
||
57 | { |
||
58 | void *b = g_slice_alloc (SAMPLE_SIZE); |
||
59 | void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE)); |
||
60 | free_list = g_slist_prepend (free_list, b); |
||
61 | /* find page */ |
||
62 | for (j = 0; j < N_PAGES; j++) |
||
63 | if (pages[j].page == p) |
||
64 | return TRUE; |
||
65 | } |
||
66 | return FALSE; |
||
67 | } |
||
68 | |||
69 | int |
||
70 | main (int argc, |
||
71 | char *argv[]) |
||
72 | { |
||
73 | int j, n_pages = 0; |
||
74 | void *mps[N_MAGAZINE_PROBES]; |
||
75 | |||
76 | /* probe some magazine sizes */ |
||
77 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
78 | mps[j] = g_slice_alloc (magazine_probes[j]); |
||
79 | /* mps[*] now contains pointers to allocated slices */ |
||
80 | |||
81 | /* allocate blocks from N_PAGES different pages */ |
||
82 | while (n_pages < N_PAGES) |
||
83 | { |
||
84 | void *b = g_slice_alloc (SAMPLE_SIZE); |
||
85 | void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE)); |
||
86 | for (j = 0; j < N_PAGES; j++) |
||
87 | if (pages[j].page == p) |
||
88 | break; |
||
89 | if (j < N_PAGES) /* known page */ |
||
90 | free_list = g_slist_prepend (free_list, b); |
||
91 | else /* new page */ |
||
92 | { |
||
93 | j = n_pages++; |
||
94 | pages[j].page = p; |
||
95 | pages[j].sample = b; |
||
96 | } |
||
97 | } |
||
98 | /* release intermediate allocations */ |
||
99 | release_trash_list (&free_list, SAMPLE_SIZE); |
||
100 | |||
101 | /* ensure that we can allocate from known pages */ |
||
102 | if (!allocate_from_known_page()) |
||
103 | g_error ("failed to allocate from magazine/page cache (before g_thread_init)"); |
||
104 | /* release intermediate allocations */ |
||
105 | release_trash_list (&free_list, SAMPLE_SIZE); |
||
106 | |||
107 | /* release magazine probes to be retained */ |
||
108 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
109 | g_slice_free1 (magazine_probes[j], mps[j]); |
||
110 | /* mps[*] now contains pointers to releaed slices */ |
||
111 | |||
112 | /* ensure probes were retained */ |
||
113 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
114 | { |
||
115 | GSList *trash = NULL; |
||
116 | guint k; |
||
117 | for (k = 0; k < MAX_PROBE_TRIALS; k++) |
||
118 | { |
||
119 | void *mem = g_slice_alloc (magazine_probes[j]); |
||
120 | if (mem == mps[j]) |
||
121 | break; /* reallocated previously freed slice */ |
||
122 | trash = g_slist_prepend (trash, mem); |
||
123 | } |
||
124 | release_trash_list (&trash, magazine_probes[j]); |
||
125 | if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */ |
||
126 | g_error ("failed to reallocate slice from magazine (before g_thread_init): size=%d", magazine_probes[j]); |
||
127 | } |
||
128 | /* mps[*] now contains pointers to reallocated slices */ |
||
129 | |||
130 | /* release magazine probes to be retained across g_thread_init */ |
||
131 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
132 | g_slice_free1 (magazine_probes[j], mps[j]); |
||
133 | /* mps[*] now contains pointers to released slices */ |
||
134 | |||
135 | /* initialize threading (should retain allocator state) */ |
||
136 | g_thread_init (NULL); |
||
137 | |||
138 | /* ensure probes were retained */ |
||
139 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
140 | { |
||
141 | GSList *trash = NULL; |
||
142 | guint k; |
||
143 | for (k = 0; k < MAX_PROBE_TRIALS; k++) |
||
144 | { |
||
145 | void *mem = g_slice_alloc (magazine_probes[j]); |
||
146 | if (mem == mps[j]) |
||
147 | break; /* reallocated previously freed slice */ |
||
148 | trash = g_slist_prepend (trash, mem); |
||
149 | } |
||
150 | release_trash_list (&trash, magazine_probes[j]); |
||
151 | if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */ |
||
152 | g_error ("failed to reallocate slice from magazine (after g_thread_init): size=%d", magazine_probes[j]); |
||
153 | } |
||
154 | /* mps[*] now contains pointers to reallocated slices */ |
||
155 | |||
156 | /* ensure that we can allocate from known pages */ |
||
157 | if (!allocate_from_known_page()) |
||
158 | g_error ("failed to allocate from magazine/page cache (after g_thread_init)"); |
||
159 | |||
160 | /* some cleanups */ |
||
161 | for (j = 0; j < N_MAGAZINE_PROBES; j++) |
||
162 | g_slice_free1 (magazine_probes[j], mps[j]); |
||
163 | release_trash_list (&free_list, SAMPLE_SIZE); |
||
164 | |||
165 | return 0; |
||
166 | } |