efl/src/tests/eina/eina_suite.c

146 lines
4.2 KiB
C
Raw Normal View History

/* EINA - EFL data type library
* Copyright (C) 2008 Cedric Bail
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library;
* if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <Eina.h>
#include "eina_suite.h"
#include "eina_suite.x"
#include "../efl_check.h"
static const Efl_Test_Case etc[] = {
{ "FixedPoint", eina_test_fp },
{ "Inarray", eina_test_inarray },
{ "Array", eina_test_array },
{ "Binary Share", eina_test_binshare },
{ "String Share", eina_test_stringshare },
{ "UString Share", eina_test_ustringshare },
{ "Log", eina_test_log },
{ "Error", eina_test_error },
{ "Magic", eina_test_magic },
{ "Inlist", eina_test_inlist },
{ "Lazy alloc", eina_test_lalloc },
{ "Main", eina_test_main },
{ "Counter", eina_test_counter },
{ "Hash", eina_test_hash },
{ "List", eina_test_list },
{ "CList", eina_test_clist },
{ "Iterator", eina_test_iterator },
{ "Accessor", eina_test_accessor },
{ "Module", eina_test_module },
{ "Convert", eina_test_convert },
{ "Rbtree", eina_test_rbtree },
{ "File", eina_test_file },
{ "Benchmark", eina_test_benchmark },
{ "Mempool", eina_test_mempool },
{ "Rectangle", eina_test_rectangle },
{ "Matrix Sparse", eina_test_matrixsparse },
{ "Eina Tiler", eina_test_tiler },
{ "Eina Strbuf", eina_test_strbuf },
{ "Eina Binbuf", eina_test_binbuf },
{ "String", eina_test_str },
{ "Unicode String", eina_test_ustr },
{ "QuadTree", eina_test_quadtree },
{ "Sched", eina_test_sched },
{ "Simple Xml Parser", eina_test_simple_xml_parser},
{ "Value", eina_test_value },
{ "COW", eina_test_cow },
{ "Barrier", eina_test_barrier },
{ "Tmp String", eina_test_tmpstr },
{ "Locking", eina_test_locking },
{ "ABI", eina_test_abi },
{ "Trash", eina_test_trash },
#ifdef XATTR_TEST_DIR
{ "Xattr", eina_test_xattr },
#endif
{ "Crc", eina_test_crc },
{ "Quad", eina_test_quad },
{ "Matrix", eina_test_matrix },
{ "Quaternion", eina_test_quaternion },
{ "Vector", eina_test_vector },
{ "Bezier", eina_test_bezier },
{ "SafePointer", eina_test_safepointer },
{ "Slice", eina_test_slice },
{ "Free Queue", eina_test_freeq },
{ "Util", eina_test_util },
{ "Short Lived Strings", eina_test_slstr },
eina: add Eina_Coro - coroutine support. Coroutines are cooperative tasks, in the sense that the caller will stop until the target function runs. The target function must either yield control back to the caller (main thread), or exit. There is no preemption of the two tasks, thus no special care needs to be taken regarding shared data. If the target coroutine yields control using eina_coro_yield(), then it will be paused until it's manually ran again by caller (main thread), which is executed with eina_coro_run(). Another common usage is to await for another task to be completed, this can be done by waiting for a future to be resolved. It will automatically yield and inform the caller of the future so it can schedule properly instead of keep calling the task. Waiting for many tasks can be achieved by using eina_future_all() or eina_future_race(). This is done with eina_coro_await(). Due portability it was implemented using Eina_Thread, Eina_Lock and Eina_Condition. Regular threads will ensure that the state is fully preserved (stack, registers) in a platform independent way. Each thread will wait on its own turn using the Eina_Lock and Eina_Condition, thus it's guaranteed that only one is being executed at the same time. The API is small and should allow different implementations shall we need them, like manually saving the stack and registers, then restoring those -- problem is doing that in a portable way, setjmp()/longjmp() won't save the stack, makecontext()/swapcontext() doesn't work right on MacOS... Hooks can be used to be informed when the main routine exits and then enters, likewise when the coroutine enters and exits. These will be used, for instance, to automatically get, adopt and return Efl_Domain_Data needed to make Efl_Object work in such environment. The flow is simple: - main exit (called from main thread) - coroutine enter (called from worker thread) - coroutine exit (called from worker thread) - main enter (called from main thead) Performance may not be optimal, however this is meant as easy-to-use and it shouldn't be an issue in real life. It will be mostly exposed in two layers: - Efl.Loop.coro: will wrap eina_coro and and schedule using its main loop instance, returns an Eina_Future so it's easy to chain. - Eina_Promise/Eina_Future "async/await"-like behavior: will allow to write "synchronous" code that can wait for promises to be resolved. When eina_future_await(), it will actually register a new Eina_Future in the chain and then eina_coro_yield(). Once the future is called back it will call eina_coro_run() and allow the coroutine to resume. This is done on top fo eina_coro_await().
2017-08-25 11:54:34 -07:00
{ "Coroutines", eina_test_coro },
{ NULL, NULL }
};
/* FIXME this is a copy from eina_test_mempool
* we should remove the duplication
*/
static Eina_Array *_modules;
static void _mempool_init(void)
{
eina_init();
/* force modules to be loaded in case they are not installed */
_modules = eina_module_list_get(NULL,
PACKAGE_BUILD_DIR "/src/modules",
EINA_TRUE,
NULL,
NULL);
eina_module_list_load(_modules);
}
static void _mempool_shutdown(void)
{
unsigned int i;
Eina_Array_Iterator it;
Eina_Module *module;
eina_module_list_free(_modules);
if (_modules)
{
EINA_ARRAY_ITER_NEXT(_modules, i, module, it)
free(module);
eina_array_free(_modules);
}
eina_shutdown();
}
int
main(int argc, char **argv)
{
int failed_count;
if (!_efl_test_option_disp(argc, argv, etc))
return 0;
#ifdef NEED_RUN_IN_TREE
putenv("EFL_RUN_IN_TREE=1");
#endif
_mempool_init();
failed_count = _efl_suite_build_and_run(argc - 1, (const char **)argv + 1,
"Eina", etc);
_mempool_shutdown();
return (failed_count == 0) ? 0 : 255;
}