* eina: improve chained mempool speed.
[profile/ivi/eina.git] / src / lib / eina_main.c
1 /* EINA - EFL data type library
2  * Copyright (C) 2008 Cedric Bail
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library;
16  * if not, see <http://www.gnu.org/licenses/>.
17  */
18
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
22
23 #include <stdio.h>
24
25 #ifdef EFL_HAVE_POSIX_THREADS
26 # include <pthread.h>
27 #endif
28
29 #ifdef EFL_HAVE_WIN32_THREADS
30 # define WIN32_LEAN_AND_MEAN
31 # include <windows.h>
32 # undef WIN32_LEAN_AND_MEAN
33 #endif
34
35 #include "eina_config.h"
36 #include "eina_private.h"
37 #include "eina_types.h"
38 #include "eina_main.h"
39 #include "eina_error.h"
40 #include "eina_log.h"
41 #include "eina_hash.h"
42 #include "eina_binshare.h"
43 #include "eina_stringshare.h"
44 #include "eina_ustringshare.h"
45 #include "eina_list.h"
46 #include "eina_matrixsparse.h"
47 #include "eina_array.h"
48 #include "eina_counter.h"
49 #include "eina_benchmark.h"
50 #include "eina_magic.h"
51 #include "eina_rectangle.h"
52 #include "eina_safety_checks.h"
53
54 /*============================================================================*
55 *                                  Local                                     *
56 *============================================================================*/
57
58 /**
59  * @cond LOCAL
60  */
61
62 static Eina_Version _version = { VMAJ, VMIN, VMIC, VREV };
63
64 static int _eina_main_count = 0;
65 #ifdef EFL_HAVE_THREADS
66 static int _eina_main_thread_count = 0;
67 #endif
68 static int _eina_log_dom = -1;
69
70 #ifdef ERR
71 #undef ERR
72 #endif
73 #define ERR(...) EINA_LOG_DOM_ERR(_eina_log_dom, __VA_ARGS__)
74
75 #ifdef DBG
76 #undef DBG
77 #endif
78 #define DBG(...) EINA_LOG_DOM_DBG(_eina_log_dom, __VA_ARGS__)
79
80 Eina_Bool _threads_activated = EINA_FALSE;
81
82 #ifdef EFL_HAVE_THREADS
83 # ifdef EFL_HAVE_POSIX_THREADS
84 static pthread_mutex_t _mutex = PTHREAD_MUTEX_INITIALIZER;
85 #  define LOCK() if(_threads_activated) pthread_mutex_lock(&_mutex)
86 #  define UNLOCK() if(_threads_activated) pthread_mutex_unlock(&_mutex)
87 #  define UNLOCK_FORCE() pthread_mutex_unlock(&_mutex)
88 # else /* EFL_HAVE_WIN32_THREADS */
89 static HANDLE _mutex = NULL;
90 #  define LOCK() if(_threads_activated) WaitForSingleObject(_mutex, INFINITE)
91 #  define UNLOCK() if(_threads_activated) ReleaseMutex(_mutex)
92 #  define UNLOCK_FORCE() ReleaseMutex(_mutex)
93 # endif
94 #else
95 # define LOCK() do {} while (0)
96 # define UNLOCK() do {} while (0)
97 # define UNLOCK_FORCE() do {} while (0)
98 #endif
99
100 /* place module init/shutdown functions here to avoid other modules
101  * calling them by mistake.
102  */
103 #define S(x) extern Eina_Bool eina_ ## x ## _init(void); \
104    extern Eina_Bool eina_ ## x ## _shutdown(void)
105    S(log);
106    S(error);
107    S(safety_checks);
108    S(magic_string);
109    S(iterator);
110    S(accessor);
111    S(array);
112    S(module);
113    S(mempool);
114    S(list);
115    S(binshare);
116    S(stringshare);
117    S(ustringshare);
118    S(matrixsparse);
119    S(convert);
120    S(counter);
121    S(benchmark);
122    S(rectangle);
123    S(strbuf);
124    S(ustrbuf);
125    S(quadtree);
126 #undef S
127
128 struct eina_desc_setup
129 {
130    const char *name;
131    Eina_Bool (*init)(void);
132    Eina_Bool (*shutdown)(void);
133 };
134
135 static const struct eina_desc_setup _eina_desc_setup[] = {
136 #define S(x) {# x, eina_ ## x ## _init, eina_ ## x ## _shutdown}
137    /* log is a special case as it needs printf */
138    S(error),
139    S(safety_checks),
140    S(magic_string),
141    S(iterator),
142    S(accessor),
143    S(array),
144    S(module),
145    S(mempool),
146    S(list),
147    S(binshare),
148    S(stringshare),
149    S(ustringshare),
150    S(matrixsparse),
151    S(convert),
152    S(counter),
153    S(benchmark),
154    S(rectangle),
155    S(strbuf),
156    S(ustrbuf),
157    S(quadtree)
158 #undef S
159 };
160 static const size_t _eina_desc_setup_len = sizeof(_eina_desc_setup) /
161    sizeof(_eina_desc_setup[0]);
162
163 static void
164 _eina_shutdown_from_desc(const struct eina_desc_setup *itr)
165 {
166    for (itr--; itr >= _eina_desc_setup; itr--)
167      {
168         if (!itr->shutdown())
169            ERR("Problems shutting down eina module '%s', ignored.", itr->name);
170      }
171
172    eina_log_domain_unregister(_eina_log_dom);
173    _eina_log_dom = -1;
174    eina_log_shutdown();
175 }
176
177 /**
178  * @endcond
179  */
180
181 /*============================================================================*
182 *                                 Global                                     *
183 *============================================================================*/
184
185
186 /*============================================================================*
187 *                                   API                                      *
188 *============================================================================*/
189
190 /**
191  * @addtogroup Eina_Main_Group Main
192  *
193  * @brief These functions provide general initialisation and shut down
194  * functions.
195  *
196  * @{
197  */
198
199 /**
200  * @var eina_version
201  * @brief Eina version (defined at configuration time)
202  */
203 EAPI Eina_Version *eina_version = &_version;
204
205 /**
206  * @brief Initialize the Eina library.
207  *
208  * @return 1 or greater on success, 0 on error.
209  *
210  * This function sets up all the eina modules. It returns 0 on
211  * failure (that is, when one of the module fails to initialize),
212  * otherwise it returns the number of times it has already been
213  * called.
214  *
215  * When Eina is not used anymore, call eina_shutdown() to shut down
216  * the Eina library.
217  */
218 EAPI int
219 eina_init(void)
220 {
221    const struct eina_desc_setup *itr, *itr_end;
222
223    if (EINA_LIKELY(_eina_main_count > 0))
224       return ++_eina_main_count;
225
226    if (!eina_log_init())
227      {
228         fprintf(stderr, "Could not initialize eina logging system.\n");
229         return 0;
230      }
231
232    _eina_log_dom = eina_log_domain_register("eina", EINA_LOG_COLOR_DEFAULT);
233    if (_eina_log_dom < 0)
234      {
235         EINA_LOG_ERR("Could not register log domain: eina");
236         eina_log_shutdown();
237         return 0;
238      }
239
240    itr = _eina_desc_setup;
241    itr_end = itr + _eina_desc_setup_len;
242    for (; itr < itr_end; itr++)
243      {
244         if (!itr->init())
245           {
246              ERR("Could not initialize eina module '%s'.", itr->name);
247              _eina_shutdown_from_desc(itr);
248              return 0;
249           }
250      }
251
252    _eina_main_count = 1;
253    return 1;
254 }
255
256 /**
257  * @brief Shut down the Eina library.
258  *
259  * @return 0 when all the modules is completely shut down, 1 or
260  * greater otherwise.
261  *
262  * This function shuts down the Eina library. It returns 0 when it has
263  * been called the same number of times than eina_init(). In that case
264  * it shut down all the Eina modules.
265  *
266  * Once this function succeeds (that is, @c 0 is returned), you must
267  * not call any of the Eina function anymore. You must call
268  * eina_init() again to use the Eina functions again.
269  */
270 EAPI int
271 eina_shutdown(void)
272 {
273    _eina_main_count--;
274    if (EINA_UNLIKELY(_eina_main_count == 0))
275              _eina_shutdown_from_desc(_eina_desc_setup + _eina_desc_setup_len);
276
277    return _eina_main_count;
278 }
279
280
281 /**
282  * @brief Initialize the mutexes of the Eina library.
283  *
284  * @return 1 or greater on success, 0 on error.
285  *
286  * This function sets up all the mutexes in all eina modules. It returns 0 on
287  * failure (that is, when one of the module fails to initialize),
288  * otherwise it returns the number of times it has already been
289  * called.
290  *
291  * When the mutexes are not used anymore, call eina_threads_shutdown() to shut down
292  * the mutexes.
293  */
294 EAPI int
295 eina_threads_init(void)
296 {
297 #ifdef EFL_HAVE_THREADS
298    int ret;
299
300 # ifdef EFL_HAVE_WIN32_THREADS
301    if (!_mutex)
302       _mutex = CreateMutex(NULL, FALSE, NULL);
303
304    if (!_mutex)
305       return 0;
306
307 # endif
308
309    LOCK();
310    ++_eina_main_thread_count;
311    ret = _eina_main_thread_count;
312
313    if(_eina_main_thread_count > 1)
314      {
315         UNLOCK();
316         return ret;
317      }
318
319    eina_share_common_threads_init();
320    eina_log_threads_init();
321    _threads_activated = EINA_TRUE;
322
323    return ret;
324 #else
325    return 0;
326 #endif
327 }
328
329 /**
330  * @brief Shut down mutexes in the Eina library.
331  *
332  * @return 0 when all mutexes are completely shut down, 1 or
333  * greater otherwise.
334  *
335  * This function shuts down the mutexes in the Eina library. It returns 0 when it has
336  * been called the same number of times than eina_threads_init(). In that case
337  * it shut down all the mutexes.
338  *
339  * Once this function succeeds (that is, @c 0 is returned), you must
340  * not call any of the Eina function in a thread anymore. You must call
341  * eina_threads_init() again to use the Eina functions in a thread again.
342  */
343 EAPI int
344 eina_threads_shutdown(void)
345 {
346 #ifdef EFL_HAVE_THREADS
347    int ret;
348
349    LOCK();
350    ret = --_eina_main_thread_count;
351    if(_eina_main_thread_count > 0)
352      {
353         UNLOCK();
354         return ret;
355      }
356
357    eina_share_common_threads_shutdown();
358    eina_log_threads_shutdown();
359
360    _threads_activated = EINA_FALSE;
361
362    UNLOCK_FORCE();
363
364 # ifdef EFL_HAVE_WIN32_THREADS
365    if (_mutex)
366       CloseHandle(_mutex);
367
368 # endif
369
370    return ret;
371 #else
372    return 0;
373 #endif
374 }
375
376 /**
377  * @}
378  */