1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/glib/tests/slice-threadinit.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,173 @@
1.4 +/* slice-threadinit.c - test GSlice across g_thread_init
1.5 + * Copyright (C) 2007 Tim Janik
1.6 + * Portions copyright (c) 2009 Nokia Corporation. All rights reserved.
1.7 + * This work is provided "as is"; redistribution and modification
1.8 + * in whole or in part, in any medium, physical or electronic is
1.9 + * permitted without restriction.
1.10 + *
1.11 + * This work is distributed in the hope that it will be useful,
1.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
1.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1.14 + *
1.15 + * In no event shall the authors or contributors be liable for any
1.16 + * direct, indirect, incidental, special, exemplary, or consequential
1.17 + * damages (including, but not limited to, procurement of substitute
1.18 + * goods or services; loss of use, data, or profits; or business
1.19 + * interruption) however caused and on any theory of liability, whether
1.20 + * in contract, strict liability, or tort (including negligence or
1.21 + * otherwise) arising in any way out of the use of this software, even
1.22 + * if advised of the possibility of such damage.
1.23 + */
1.24 +#include <glib.h>
1.25 +#ifdef __SYMBIAN32__
1.26 +#include "mrt2_glib2_test.h"
1.27 +#endif /*__SYMBIAN32__*/
1.28 +#define N_PAGES (101) /* number of pages to sample */
1.29 +#define SAMPLE_SIZE (7)
1.30 +#define PAGE_SIZE (128) /* must be <= minimum GSlice alignment block */
1.31 +#define MAGAZINE_PROBES { 81, 265, 347 } /* block sizes hopefully unused by g_thread_init */
1.32 +#define MAX_PROBE_TRIALS (1031) /* must be >= maximum magazine size */
1.33 +
1.34 +#define ALIGN(size, base) ((base) * (gsize) (((size) + (base) - 1) / (base)))
1.35 +
1.36 +static struct {
1.37 + void *page;
1.38 + void *sample;
1.39 +} pages[N_PAGES] = { { NULL, }, };
1.40 +
1.41 +static const guint magazine_probes[] = MAGAZINE_PROBES;
1.42 +#define N_MAGAZINE_PROBES G_N_ELEMENTS (magazine_probes)
1.43 +
1.44 +static void
1.45 +release_trash_list (GSList **trash_list,
1.46 + gsize block_size)
1.47 +{
1.48 + while (*trash_list)
1.49 + {
1.50 + g_slice_free1 (block_size, (*trash_list)->data);
1.51 + *trash_list = g_slist_delete_link (*trash_list, *trash_list);
1.52 + }
1.53 +}
1.54 +
1.55 +static GSList *free_list = NULL;
1.56 +
1.57 +static gboolean
1.58 +allocate_from_known_page (void)
1.59 +{
1.60 + guint i, j, n_trials = N_PAGES * PAGE_SIZE / SAMPLE_SIZE; /* upper bound */
1.61 + for (i = 0; i < n_trials; i++)
1.62 + {
1.63 + void *b = g_slice_alloc (SAMPLE_SIZE);
1.64 + void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE));
1.65 + free_list = g_slist_prepend (free_list, b);
1.66 + /* find page */
1.67 + for (j = 0; j < N_PAGES; j++)
1.68 + if (pages[j].page == p)
1.69 + return TRUE;
1.70 + }
1.71 + return FALSE;
1.72 +}
1.73 +
1.74 +int
1.75 +main (int argc,
1.76 + char *argv[])
1.77 +{
1.78 + int j, n_pages = 0;
1.79 + void *mps[N_MAGAZINE_PROBES];
1.80 +#ifdef __SYMBIAN32__
1.81 + g_log_set_handler (NULL, G_LOG_FLAG_FATAL| G_LOG_FLAG_RECURSION | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO | G_LOG_LEVEL_DEBUG, &mrtLogHandler, NULL);
1.82 + g_set_print_handler(mrtPrintHandler);
1.83 + #endif /*__SYMBIAN32__*/
1.84 + /* probe some magazine sizes */
1.85 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.86 + mps[j] = g_slice_alloc (magazine_probes[j]);
1.87 + /* mps[*] now contains pointers to allocated slices */
1.88 +
1.89 + /* allocate blocks from N_PAGES different pages */
1.90 + while (n_pages < N_PAGES)
1.91 + {
1.92 + void *b = g_slice_alloc (SAMPLE_SIZE);
1.93 + void *p = (void*) (PAGE_SIZE * ((gsize) b / PAGE_SIZE));
1.94 + for (j = 0; j < N_PAGES; j++)
1.95 + if (pages[j].page == p)
1.96 + break;
1.97 + if (j < N_PAGES) /* known page */
1.98 + free_list = g_slist_prepend (free_list, b);
1.99 + else /* new page */
1.100 + {
1.101 + j = n_pages++;
1.102 + pages[j].page = p;
1.103 + pages[j].sample = b;
1.104 + }
1.105 + }
1.106 + /* release intermediate allocations */
1.107 + release_trash_list (&free_list, SAMPLE_SIZE);
1.108 +
1.109 + /* ensure that we can allocate from known pages */
1.110 + if (!allocate_from_known_page())
1.111 + g_error ("failed to allocate from magazine/page cache (before g_thread_init)");
1.112 + /* release intermediate allocations */
1.113 + release_trash_list (&free_list, SAMPLE_SIZE);
1.114 +
1.115 + /* release magazine probes to be retained */
1.116 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.117 + g_slice_free1 (magazine_probes[j], mps[j]);
1.118 + /* mps[*] now contains pointers to releaed slices */
1.119 +
1.120 + /* ensure probes were retained */
1.121 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.122 + {
1.123 + GSList *trash = NULL;
1.124 + guint k;
1.125 + for (k = 0; k < MAX_PROBE_TRIALS; k++)
1.126 + {
1.127 + void *mem = g_slice_alloc (magazine_probes[j]);
1.128 + if (mem == mps[j])
1.129 + break; /* reallocated previously freed slice */
1.130 + trash = g_slist_prepend (trash, mem);
1.131 + }
1.132 + release_trash_list (&trash, magazine_probes[j]);
1.133 + if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */
1.134 + g_error ("failed to reallocate slice from magazine (before g_thread_init): size=%d", magazine_probes[j]);
1.135 + }
1.136 + /* mps[*] now contains pointers to reallocated slices */
1.137 +
1.138 + /* release magazine probes to be retained across g_thread_init */
1.139 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.140 + g_slice_free1 (magazine_probes[j], mps[j]);
1.141 + /* mps[*] now contains pointers to released slices */
1.142 +
1.143 + /* initialize threading (should retain allocator state) */
1.144 + g_thread_init (NULL);
1.145 +
1.146 + /* ensure probes were retained */
1.147 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.148 + {
1.149 + GSList *trash = NULL;
1.150 + guint k;
1.151 + for (k = 0; k < MAX_PROBE_TRIALS; k++)
1.152 + {
1.153 + void *mem = g_slice_alloc (magazine_probes[j]);
1.154 + if (mem == mps[j])
1.155 + break; /* reallocated previously freed slice */
1.156 + trash = g_slist_prepend (trash, mem);
1.157 + }
1.158 + release_trash_list (&trash, magazine_probes[j]);
1.159 + if (k >= MAX_PROBE_TRIALS) /* failed to reallocate slice */
1.160 + g_error ("failed to reallocate slice from magazine (after g_thread_init): size=%d", magazine_probes[j]);
1.161 + }
1.162 + /* mps[*] now contains pointers to reallocated slices */
1.163 +
1.164 + /* ensure that we can allocate from known pages */
1.165 + if (!allocate_from_known_page())
1.166 + g_error ("failed to allocate from magazine/page cache (after g_thread_init)");
1.167 +
1.168 + /* some cleanups */
1.169 + for (j = 0; j < N_MAGAZINE_PROBES; j++)
1.170 + g_slice_free1 (magazine_probes[j], mps[j]);
1.171 + release_trash_list (&free_list, SAMPLE_SIZE);
1.172 +#if __SYMBIAN32__
1.173 + testResultXml("slice-threadinit");
1.174 + #endif /* EMULATOR */
1.175 + return 0;
1.176 +}