[kdbus] Do not set body message if signature field is empty
[platform/upstream/glib.git] / tests / slice-concurrent.c
1 /* test for gslice cross thread allocation/free
2  * Copyright (C) 2006 Stefan Westerfeld
3  * Copyright (C) 2007 Tim Janik
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
17  */
18 #include <glib.h>
19 #include <stdlib.h>
20 #ifdef G_OS_UNIX
21 #include <unistd.h>
22 #endif
23
24 #define N_THREADS       8
25 #define N_ALLOCS        50000
26 #define MAX_BLOCK_SIZE  64
27
28 struct ThreadData
29 {
30   int      thread_id;
31   GThread* gthread;
32
33   GMutex   to_free_mutex;
34   void*    to_free [N_THREADS * N_ALLOCS];
35   int      bytes_to_free [N_THREADS * N_ALLOCS];
36   int      n_to_free;
37   int      n_freed;
38 } tdata[N_THREADS];
39
40 static void *
41 thread_func (void *arg)
42 {
43   struct ThreadData *td = arg;
44   int i;
45 /*   g_print ("Thread %d starting\n", td->thread_id); */
46   for (i = 0; i < N_ALLOCS; i++)
47     {
48       int bytes;
49       char *mem;
50       int f;
51       int t;
52
53       if (rand() % (N_ALLOCS / 20) == 0)
54         g_print ("%c", 'a' - 1 + td->thread_id);
55
56       /* allocate block of random size and randomly fill */
57       bytes = rand() % MAX_BLOCK_SIZE + 1;
58       mem = g_slice_alloc (bytes);
59
60       for (f = 0; f < bytes; f++)
61         mem[f] = rand();
62
63       /* associate block with random thread */
64       t = rand() % N_THREADS;
65       g_mutex_lock (&tdata[t].to_free_mutex);
66       tdata[t].to_free[tdata[t].n_to_free] = mem;
67       tdata[t].bytes_to_free[tdata[t].n_to_free] = bytes;
68       tdata[t].n_to_free++;
69       g_mutex_unlock (&tdata[t].to_free_mutex);
70
71       /* shuffle thread execution order every once in a while */
72       if (rand() % 97 == 0)
73         {
74           if (rand() % 2)
75             g_thread_yield();   /* concurrent shuffling for single core */
76           else
77             g_usleep (1000);    /* concurrent shuffling for multi core */
78         }
79
80       /* free a block associated with this thread */
81       g_mutex_lock (&td->to_free_mutex);
82       if (td->n_to_free > 0)
83         {
84           td->n_to_free--;
85           g_slice_free1 (td->bytes_to_free[td->n_to_free], td->to_free[td->n_to_free]);
86           td->n_freed++;
87         }
88       g_mutex_unlock (&td->to_free_mutex);
89     }
90
91   return NULL;
92 }
93
94 int
95 main (void)
96 {
97   int t;
98
99   for (t = 0; t < N_THREADS; t++)
100     {
101       tdata[t].thread_id = t + 1;
102       tdata[t].n_to_free = 0;
103       tdata[t].n_freed = 0;
104     }
105   g_print ("Starting %d threads for concurrent GSlice usage...\n", N_THREADS);
106   for (t = 0; t < N_THREADS; t++)
107     {
108       tdata[t].gthread   = g_thread_create (thread_func, &tdata[t], TRUE, NULL);
109       g_assert (tdata[t].gthread != NULL);
110     }
111   for (t = 0; t < N_THREADS; t++)
112     {
113       g_thread_join (tdata[t].gthread);
114     }
115   g_print ("\n");
116   for (t = 0; t < N_THREADS; t++)
117     {
118       g_print ("Thread %d: %d blocks freed, %d blocks not freed\n",
119                     tdata[t].thread_id, tdata[t].n_freed, tdata[t].n_to_free);
120     }
121   return 0;
122 }