diff --git a/.gitignore b/.gitignore index c89dffc5e..f66bd5b09 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ autom4te.cache semantic.cache wiki/backups/* doc/devel/draw/*.png +m4/* diff --git a/Makefile.am b/Makefile.am index c23c7611c..8fc724603 100644 --- a/Makefile.am +++ b/Makefile.am @@ -36,8 +36,7 @@ CLEANFILES = # global pre-processor flags. Per-target variables should include # these at the front (if possible) for consistency AM_CPPFLAGS = -I$(top_srcdir)/src/ \ - $(NOBUGMT_LUMIERA_CFLAGS) \ - $(VALGRIND_CFLAGS) + $(LUMIERA_CFLAGS) # Only use subdirs if really needed, prefer the include scheme below #SUBDIRS += diff --git a/admin/render_icon.py b/admin/render_icon.py index 0f9cee294..e3f76c129 100755 --- a/admin/render_icon.py +++ b/admin/render_icon.py @@ -1,6 +1,6 @@ #!/usr/bin/python # -# render-icons.py - Icon rendering utility script +# render_icons.py - Icon rendering utility script # # Copyright (C) Lumiera.org # 2008, Joel Holdsworth diff --git a/configure.ac b/configure.ac index 297b9c2cc..c93198edf 100644 --- a/configure.ac +++ b/configure.ac @@ -7,8 +7,9 @@ AC_PREREQ(2.59) AC_COPYRIGHT([ Copyright (C) Lumiera.org - 2008, Christian Thaeter + 2008, 2009, 2010 Christian Thaeter Joel Holdsworth + et. al. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -25,12 +26,14 @@ AC_COPYRIGHT([ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ]) +################################################################################# # # Global configuration # AC_GNU_SOURCE AC_DISABLE_STATIC +################################################################################# # # Required programs # @@ -42,26 +45,12 @@ AC_LIBTOOL_DLOPEN AC_PROG_LIBTOOL PKG_PROG_PKG_CONFIG([0.22]) -# -# test for headers -# -AC_STDC_HEADERS - -ACX_PTHREAD -LIBS="$PTHREAD_LIBS $LIBS" -CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -CC="$PTHREAD_CC" - -##AM_CONDITIONAL([HAVE_THREADING], [test x"$acx_pthread_ok" = xyes]) - - - +################################################################################# # # user options # - -############## NoBug build levels +# NoBug build levels AH_TEMPLATE(EBUG_ALPHA, [Define to 1 for selecting NoBug ALPHA build level]) AH_TEMPLATE(EBUG_BETA, [Define to 1 for selecting NoBug BETA build level]) AH_TEMPLATE(NDEBUG, [Define to 1 for selecting NoBug RELEASE build level]) @@ -83,18 +72,44 @@ AC_ARG_ENABLE(release, AC_HELP_STRING([--enable-release], [select NoBug RELEASE )])]) # END NoBug -# C headers and libraries -AC_LANG_PUSH([C]) -AC_CHECK_LIB(dl, dlopen, [LUMIERA_PLUGIN_LIBS="$LUMIERA_PLUGIN_LIBS -ldl"], - [AC_MSG_ERROR([Dynamic linking not supported, report a bug])] + + +################################################################################# +# +# global test for headers and functions +# +AC_STDC_HEADERS + + +ACX_PTHREAD +LIBS="$PTHREAD_LIBS $LIBS" +CFLAGS="$CFLAGS $PTHREAD_CFLAGS" +CC="$PTHREAD_CC" + +# Nobug Dependencies +AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H)) +PKG_CHECK_MODULES(VALGRIND, [valgrind], AC_DEFINE(HAVE_VALGRIND_H), + AC_MSG_NOTICE([valgrind not found (optional)])) + +PKG_CHECK_MODULES(NOBUGMT, [nobugmt >= 201001.1], + AC_DEFINE(HAVE_NOBUGMT_H), + AC_MSG_ERROR([Missing required nobug version (http://www.lumiera.org/nobug_manual.html)]) ) -AC_LANG_POP([C]) +LUMIERA_CFLAGS="$NOBUGMT_CFLAGS $VALGRIND_CFLAGS" +LUMIERA_LIBS="$NOBUGMT_LIBS" + +AC_SUBST(LUMIERA_CFLAGS) +AC_SUBST(LUMIERA_LIBS) +#boost # C++ headers and libraries AC_LANG_PUSH([C++]) +# check for the minimum Boost version +# (http://www.randspringer.de/boost/upt.html) +AX_BOOST_BASE([1.34.1]) AC_CHECK_HEADER([tr1/memory], , @@ -107,22 +122,87 @@ AC_CHECK_HEADER([boost/shared_ptr.hpp], ) AC_CHECK_HEADER([boost/program_options.hpp], - , + [LUMIERA_BOOST_LIBS="$LUMIERA_BOOST_LIBS -lboost_program_options-mt"], AC_MSG_ERROR([boost::program_options missing (http://www.boost.org/)]) ) -# check for the minimum Boost version -# (http://www.randspringer.de/boost/upt.html) -AX_BOOST_BASE([1.34.1]) - AC_CHECK_HEADER([boost/regex.hpp], - , + [LUMIERA_BOOST_LIBS="$LUMIERA_BOOST_LIBS -lboost_regex-mt"], AC_MSG_ERROR([boost::regex missing (http://www.boost.org/)]) ) AC_LANG_POP([C++]) +AC_SUBST(LUMIERA_BOOST_CFLAGS) +AC_SUBST(LUMIERA_BOOST_LIBS) -PKG_CHECK_MODULES(LUMIERA_COMMON_LIBS, [sigc++-2.0 >= 2.0.17]) + + +################################################################################# +# +# Configs for subsystems +# ---------------------- +# + +################################################################################# +# +# library +# + +PKG_CHECK_MODULES(LUMIERA_LIBRARY, [ + gavl >= 1.0.1 + ]) + +LUMIERA_LIBRARY_CFLAGS="$LUMIERA_LIBRARY_CFLAGS $LUMIERA_CFLAGS" +LUMIERA_LIBRARY_LIBS="$LUMIERA_LIBRARY_CFLAGS $LUMIERA_LIBS $LUMIERA_BOOST_LIBS" + +AC_SUBST(LUMIERA_LIBRARY_CFLAGS) +AC_SUBST(LUMIERA_LIBRARY_LIBS) + +################################################################################# +# +# common +# +PKG_CHECK_MODULES(LUMIERA_COMMON, [sigc++-2.0 >= 2.0.17]) + +AC_LANG_PUSH([C]) +AC_CHECK_LIB(dl, dlopen, [LUMIERA_COMMON_LIBS="$LUMIERA_COMMON_LIBS -ldl"], + [AC_MSG_ERROR([Dynamic linking not supported, report a bug])] +) +AC_LANG_POP([C]) + +LUMIERA_COMMON_CFLAGS="$LUMIERA_COMMON_CFLAGS $LUMIERA_CFLAGS" +LUMIERA_COMMON_LIBS="$LUMIERA_COMMON_LIBS $LUMIERA_LIBS" + +AC_SUBST(LUMIERA_COMMON_CFLAGS) +AC_SUBST(LUMIERA_COMMON_LIBS) + +################################################################################# +# +# backend +# + +LUMIERA_BACKEND_CFLAGS="$LUMIERA_CFLAGS" +LUMIERA_BACKEND_LIBS="$LUMIERA_LIBS" + +AC_SUBST(LUMIERA_BACKEND_CFLAGS) +AC_SUBST(LUMIERA_BACKEND_LIBS) + +################################################################################# +# +# proc +# + + +LUMIERA_PROC_CFLAGS="$LUMIERA_PROC_CFLAGS $LUMIERA_CFLAGS" +LUMIERA_PROC_LIBS="$LUMIERA_PROC_CFLAGS $LUMIERA_LIBS" + +AC_SUBST(LUMIERA_PROC_CFLAGS) +AC_SUBST(LUMIERA_PROC_LIBS) + +################################################################################# +# +# gui +# ############## Internatinalization #GETTEXT_PACKAGE=gtk-lumiera @@ -143,14 +223,12 @@ PKG_CHECK_MODULES(LUMIERA_GUI, [ gtkmm-2.4 >= 2.12 cairomm-1.0 >= 0.6.0 librsvg-2.0 >= 2.18.1 - gavl >= 0.2.5 + gavl >= 1.0.1 gthread-2.0 >= 2.12.4]) # Check for gdl-1.0 with a gdl-lum fallback PKG_CHECK_MODULES(GDL, gdl-1.0 >= 2.27.1, , [PKG_CHECK_MODULES(GDL, gdl-lum >= 2.27.1) ]) -LUMIERA_GUI_CFLAGS="$LUMIERA_GUI_CFLAGS $GDL_CFLAGS" -LUMIERA_GUI_LIBS="$LUMIERA_GUI_LIBS $GDL_LIBS" # END Gtk Dependancies @@ -178,21 +256,28 @@ AC_CHECK_LIB(Xv, XvQueryAdaptors, [LUMIERA_GUI_LIBS="$LUMIERA_GUI_LIBS -lXv"], # END X11 Dependancies -AC_SUBST(LUMIERA_COMMON_LIBS) -AC_SUBST(LUMIERA_PLUGIN_LIBS) -AC_SUBST(LUMIERA_GUI_LIBS) +LUMIERA_GUI_CFLAGS="$LUMIERA_GUI_CFLAGS $LUMIERA_CFLAGS $GDL_CFLAGS" +LUMIERA_GUI_LIBS="$LUMIERA_GUI_LIBS $LUMIERA_LIBS $GDL_LIBS" + AC_SUBST(LUMIERA_GUI_CFLAGS) +AC_SUBST(LUMIERA_GUI_LIBS) -############## Nobug Dependancies -AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H)) -PKG_CHECK_MODULES(VALGRIND, [valgrind], AC_DEFINE(HAVE_VALGRIND_H), - AC_MSG_NOTICE([valgrind not found (optional)])) -PKG_CHECK_MODULES(NOBUGMT_LUMIERA, [nobugmt >= 201001.1], - AC_DEFINE(HAVE_NOBUGMT_H), - AC_MSG_ERROR([Missing required nobug version (http://www.lumiera.org/nobug_manual.html)]) -) -# END Nobug Dependancies +################################################################################# +# +# tools +# + +LUMIERA_TOOL_CFLAGS="$LUMIERA_TOOL_CFLAGS $LUMIERA_CFLAGS $LUMIERA_GUI_CFLAGS" +LUMIERA_TOOL_LIBS="$LUMIERA_TOOL_CFLAGS $LUMIERA_LIBS $LUMIERA_BOOST_LIBS $LUMIERA_GUI_LIBS" + +AC_SUBST(LUMIERA_TOOL_CFLAGS) +AC_SUBST(LUMIERA_TOOL_LIBS) + +################################################################################# +# +# Generate output +# # Print a summary AC_MSG_RESULT([ diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index a1f85788c..6b64b35f7 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -19,8 +19,8 @@ liblumierabackend_la_srcdir = $(top_srcdir)/src/backend lib_LTLIBRARIES += liblumierabackend.la liblumierabackend_la_CPPFLAGS = $(AM_CPPFLAGS) -liblumierabackend_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wextra -Wall -Werror -liblumierabackend_la_LIBADD = liblumiera.la +liblumierabackend_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_BACKEND_CFLAGS) -std=gnu99 -Wextra -Wall -Werror +liblumierabackend_la_LIBADD = $(LUMIERA_BACKEND_LIBS) liblumiera.la liblumierabackend_la_SOURCES = \ $(liblumierabackend_la_srcdir)/mediaaccessfacade.cpp \ diff --git a/src/backend/thread-wrapper.hpp b/src/backend/thread-wrapper.hpp index e4056a51b..2355a6f8a 100644 --- a/src/backend/thread-wrapper.hpp +++ b/src/backend/thread-wrapper.hpp @@ -177,10 +177,11 @@ namespace backend { lumiera_thread_run ( kind , &run // invoking the run helper and.. , this // passing this start context as parameter - , joinCond // maybe wait-blocking for the thread to terminate , purpose.c() , logging_flag ); + (void)joinCond; // TODO: this is a temporary fix to match the C API + // we might have to re-write more of this file or even remove it later if (!res) throw lumiera::error::State("failed to create new thread."); diff --git a/src/backend/threadpool.c b/src/backend/threadpool.c index 66ecd4e33..9de1e6d81 100644 --- a/src/backend/threadpool.c +++ b/src/backend/threadpool.c @@ -39,120 +39,171 @@ static lumiera_threadpool threadpool; */ NOBUG_DEFINE_FLAG_PARENT (threadpool, threads_dbg); /*TODO insert a suitable/better parent flag here */ +LUMIERA_ERROR_DEFINE(THREADPOOL_OFFLINE, "tried to acquire thread while threadpool is not available"); //code goes here// -void* pool_thread_loop(void * arg) -{ - (void) arg; - while (1) - { - ; - } - return arg; -} - void -lumiera_threadpool_init(unsigned limit) +lumiera_threadpool_init(void) { + NOBUG_INIT_FLAG (threadpool); + NOBUG_INIT_FLAG (threads); + TRACE (threadpool); + NOBUG_INIT_FLAG (threads); + for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) { - llist_init(&threadpool.pool[i].list); - threadpool.pool[i].max_threads = limit; - threadpool.pool[i].working_thread_count = 0; + llist_init (&threadpool.pool[i].working_list); + llist_init (&threadpool.pool[i].idle_list); + threadpool.pool[i].thread_count = 0; threadpool.pool[i].idle_thread_count = 0; + threadpool.pool[i].status = LUMIERA_THREADPOOL_ONLINE; //TODO: configure each pools' pthread_attrs appropriately pthread_attr_init (&threadpool.pool[i].pthread_attrs); - pthread_attr_setdetachstate (&threadpool.pool[i].pthread_attrs, PTHREAD_CREATE_DETACHED); //cancel... - lumiera_mutex_init(&threadpool.pool[i].lock,"pool of threads", &NOBUG_FLAG(threadpool)); + lumiera_condition_init (&threadpool.pool[i].sync,"pool of threads", &NOBUG_FLAG (threadpool)); } } void lumiera_threadpool_destroy(void) { - ECHO ("destroying threadpool"); + TRACE (threadpool); + + /* set all threadpools offline must be done first, since running threads may attempt to start new ones */ + for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) + LUMIERA_CONDITION_SECTION (threadpool, &threadpool.pool[i].sync) + threadpool.pool[i].status = LUMIERA_THREADPOOL_OFFLINE; + + /* wait that all theads have finished */ for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) { - ECHO ("destroying individual pool #%d", i); - // no locking is done at this point - ECHO ("number of threads in the pool=%d", llist_count(&threadpool.pool[i].list)); - LLIST_WHILE_HEAD(&threadpool.pool[i].list, thread) - lumiera_thread_delete((LumieraThread)thread); - ECHO ("destroying the pool mutex"); - lumiera_mutex_destroy (&threadpool.pool[i].lock, &NOBUG_FLAG (threadpool)); - ECHO ("pool mutex destroyed"); + LUMIERA_CONDITION_SECTION (threadpool, &threadpool.pool[i].sync) + { + TODO ("check threads deadlines, kill them when they are stalled"); + TODO ("for threads without deadline use a timeout from config system, 500ms or so by default"); + LUMIERA_CONDITION_WAIT(llist_is_empty (&threadpool.pool[i].working_list)); + } + } + + /* now we can delete all threads */ + for (int i = 0; i < LUMIERA_THREADCLASS_COUNT; ++i) + { + TRACE (threadpool, "destroying individual pool #%d", i); + + LUMIERA_CONDITION_SECTION (threadpool, &threadpool.pool[i].sync) + { + REQUIRE (threadpool.pool[i].thread_count + == threadpool.pool[i].idle_thread_count + && 0 == llist_count (&threadpool.pool[i].working_list), + "%d(llist_count=%d) threads are still running", + threadpool.pool[i].thread_count + - threadpool.pool[i].idle_thread_count, + llist_count (&threadpool.pool[i].working_list)); + REQUIRE ((int)(llist_count (&threadpool.pool[i].working_list) + + llist_count (&threadpool.pool[i].idle_list)) + == threadpool.pool[i].thread_count, + "threadpool counter miscalculation (working_list count = %u, idle_list count = %u, thread_count = %d )", + llist_count (&threadpool.pool[i].working_list), + llist_count (&threadpool.pool[i].idle_list), + threadpool.pool[i].thread_count); + LLIST_WHILE_HEAD (&threadpool.pool[i].idle_list, t) + { + lumiera_thread_delete ((LumieraThread)t); + threadpool.pool[i].thread_count--; + } + } + lumiera_condition_destroy (&threadpool.pool[i].sync, &NOBUG_FLAG (threadpool)); pthread_attr_destroy (&threadpool.pool[i].pthread_attrs); } } +/** + * + * @return thread handle or NULL on error (lumiera error will be set) + */ LumieraThread -lumiera_threadpool_acquire_thread(enum lumiera_thread_class kind, - const char* purpose, - struct nobug_flag* flag) +lumiera_threadpool_acquire_thread (enum lumiera_thread_class kind, + const char* purpose, + struct nobug_flag* flag) { - LumieraThread ret; + TRACE (threadpool); + LumieraThread ret = NULL; REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "unknown pool kind specified: %d", kind); - if (llist_is_empty (&threadpool.pool[kind].list)) + + LUMIERA_CONDITION_SECTION (threadpool, &threadpool.pool[kind].sync) { - // TODO: fill in the reccondition argument, currently NULL - FIXME ("this max thread logic needs to be deeply thought about and made more efficient as well as rebust"); - if (threadpool.pool[kind].working_thread_count - + threadpool.pool[kind].idle_thread_count - < threadpool.pool[kind].max_threads) { - ret = lumiera_thread_new (kind, NULL, purpose, flag, - &threadpool.pool[kind].pthread_attrs); - threadpool.pool[kind].working_thread_count++; - ENSURE (ret, "did not create a valid thread"); - } + if (threadpool.pool[kind].status != LUMIERA_THREADPOOL_ONLINE) + LUMIERA_ERROR_SET_WARNING (threadpool, THREADPOOL_OFFLINE, purpose); else { - //ERROR (threadpool, "did not create a new thread because per-pool limit was reached: %d", threadpool.pool[kind].max_threads); - LUMIERA_DIE(ERRNO); + if (llist_is_empty (&threadpool.pool[kind].idle_list)) + { + ret = lumiera_thread_new (kind, purpose, flag, + &threadpool.pool[kind].pthread_attrs); + ENSURE (ret, "did not create a valid thread"); + TODO ("no error handing, let the resourcecollector do it, no need when returning the thread"); + threadpool.pool[kind].thread_count++; + LUMIERA_CONDITION_WAIT (!llist_is_empty (&threadpool.pool[kind].idle_list)); + } + // use an existing thread, pick the first one + // remove it from the pool's list + ret = (LumieraThread) (llist_head (&threadpool.pool[kind].idle_list)); + + ENSURE (ret, "did not find a valid thread"); + + REQUIRE (ret->state == LUMIERA_THREADSTATE_IDLE, "trying to return a non-idle thread (state=%s)", lumiera_threadstate_names[ret->state]); + + // move thread to the working_list + llist_insert_head (&threadpool.pool[kind].working_list, &ret->node); + + threadpool.pool[kind].idle_thread_count--; // cheaper than using llist_count + REQUIRE ((int)(llist_count (&threadpool.pool[kind].working_list) + + llist_count (&threadpool.pool[kind].idle_list)) + == threadpool.pool[kind].thread_count, + "threadpool counter miscalculation (working_list count = %u, idle_list count = %u, thread_count = %d )", + llist_count (&threadpool.pool[kind].working_list), + llist_count (&threadpool.pool[kind].idle_list), + threadpool.pool[kind].thread_count); } } - else - { - // use an existing thread, pick the first one - // remove it from the pool's list - LUMIERA_MUTEX_SECTION (threadpool, &threadpool.pool[kind].lock) - { - ret = (LumieraThread)(llist_unlink(llist_head (&threadpool.pool[kind].list))); - threadpool.pool[kind].working_thread_count++; - threadpool.pool[kind].idle_thread_count--; // cheaper than using llist_count - ENSURE (threadpool.pool[kind].idle_thread_count == - llist_count(&threadpool.pool[kind].list), - "idle thread count %d is wrong, should be %d", - threadpool.pool[kind].idle_thread_count, - llist_count(&threadpool.pool[kind].list)); - } - ENSURE (ret, "did not find a valid thread"); - } return ret; } +// TODO: rename to lumiera_threadpool_park_thread void lumiera_threadpool_release_thread(LumieraThread thread) { + TRACE (threadpool); REQUIRE (thread, "invalid thread given"); REQUIRE (thread->kind < LUMIERA_THREADCLASS_COUNT, "thread belongs to an unknown pool kind: %d", thread->kind); - LUMIERA_MUTEX_SECTION (threadpool, &threadpool.pool[thread->kind].lock) + REQUIRE (thread->state != LUMIERA_THREADSTATE_IDLE, "trying to park an already idle thread"); + LUMIERA_CONDITION_SECTION (threadpool, &threadpool.pool[thread->kind].sync) { - REQUIRE (llist_is_single(&thread->node), "thread already belongs to some list"); - llist_insert_head(&threadpool.pool[thread->kind].list, &thread->node); - threadpool.pool[thread->kind].working_thread_count--; - threadpool.pool[thread->kind].idle_thread_count++; // cheaper than using llist_count - ENSURE (threadpool.pool[thread->kind].idle_thread_count == - llist_count(&threadpool.pool[thread->kind].list), - "idle thread count %d is wrong, should be %d", - threadpool.pool[thread->kind].idle_thread_count, - llist_count(&threadpool.pool[thread->kind].list)); - // REQUIRE (!llist_is_empty (&threadpool.pool[thread->kind].list), "thread pool is still empty after insertion"); + REQUIRE (!llist_is_member (&threadpool.pool[thread->kind].idle_list, &thread->node), "thread is already in the idle list"); + REQUIRE (llist_is_member (&threadpool.pool[thread->kind].working_list, &thread->node) + || thread->state == LUMIERA_THREADSTATE_STARTUP, + "thread is not in the working list (state=%s)", + lumiera_threadstate_names[thread->state]); + thread->state = LUMIERA_THREADSTATE_IDLE; + // move thread to the idle_list + llist_insert_head (&threadpool.pool[thread->kind].idle_list, &thread->node); + + threadpool.pool[thread->kind].idle_thread_count++; // cheaper than using llist_count + REQUIRE ((int)(llist_count (&threadpool.pool[thread->kind].working_list) + + llist_count (&threadpool.pool[thread->kind].idle_list)) + == threadpool.pool[thread->kind].thread_count, + "threadpool counter miscalculation (working_list count = %u, idle_list count = %u, thread_count = %d )", + llist_count (&threadpool.pool[thread->kind].working_list), + llist_count (&threadpool.pool[thread->kind].idle_list), + threadpool.pool[thread->kind].thread_count); + + REQUIRE (!llist_is_empty (&threadpool.pool[thread->kind].idle_list), "thread pool is still empty after insertion"); + LUMIERA_CONDITION_BROADCAST; } } diff --git a/src/backend/threadpool.h b/src/backend/threadpool.h index 03b56a4fe..5a3455d39 100644 --- a/src/backend/threadpool.h +++ b/src/backend/threadpool.h @@ -23,9 +23,8 @@ #define LUMIERA_THREADPOOL_H //TODO: Support library includes// -#include "lib/reccondition.h" +#include "lib/condition.h" #include "lib/llist.h" -#include "lib/mutex.h" //TODO: Forward declarations// @@ -55,8 +54,8 @@ lumiera_threadpool_acquire_thread(enum lumiera_thread_class kind, struct nobug_flag* flag); /** - * Release a thread - * This ends up putting a (parked/idle) thread back on the list of an appropriate threadpool. + * Park a thread + * This ends up putting a finished thread back on the list of an appropriate threadpool. * This function doesn't need to be accessible outside of the threadpool implementation. */ void @@ -65,25 +64,30 @@ lumiera_threadpool_release_thread(LumieraThread thread); typedef struct lumiera_threadpool_struct lumiera_threadpool; typedef lumiera_threadpool* LumieraThreadpool; +enum lumiera_threadpool_state { + LUMIERA_THREADPOOL_OFFLINE, + LUMIERA_THREADPOOL_ONLINE +}; + struct lumiera_threadpool_struct { struct { - llist list; - lumiera_mutex lock; - unsigned max_threads; - unsigned working_thread_count; - unsigned idle_thread_count; + llist working_list; + llist idle_list; + int thread_count; + int idle_thread_count; pthread_attr_t pthread_attrs; + lumiera_condition sync; + enum lumiera_threadpool_state status; } pool[LUMIERA_THREADCLASS_COUNT]; }; /** * Initialize the thread pool. - * @param limit the maximum number of threads (idle+working) allowed per pool */ void -lumiera_threadpool_init(unsigned limit); +lumiera_threadpool_init(void); void lumiera_threadpool_destroy(void); diff --git a/src/backend/threads.c b/src/backend/threads.c index 62f0d14a6..ded04a60e 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -22,7 +22,6 @@ //TODO: Support library includes// #include "include/logging.h" -#include "lib/mutex.h" #include "lib/safeclib.h" @@ -34,6 +33,7 @@ //TODO: System includes// #include +#include #include /** @@ -60,94 +60,90 @@ const char* lumiera_threadstate_names[] = { }; #undef LUMIERA_THREAD_STATE -struct lumiera_thread_mockup -{ - void (*fn)(void*); - void* arg; - LumieraReccondition finished; -}; +LUMIERA_ERROR_DEFINE(THREAD, "fatal threads initialization error"); -static void* thread_loop (void* arg) +/* thread local storage pointing back to the thread structure of each thread */ +static pthread_key_t lumiera_thread_tls; +static pthread_once_t lumiera_thread_initialized = PTHREAD_ONCE_INIT; + +static void +lumiera_thread_tls_init (void) { - (void)arg; + if (!!pthread_key_create (&lumiera_thread_tls, NULL)) + LUMIERA_DIE (THREAD); /* should never happen */ +} + + +static void* +thread_loop (void* thread) +{ + TRACE (threads); + NOBUG_THREAD_ID_SET ("worker"); + LumieraThread t = (LumieraThread)thread; + + pthread_setspecific (lumiera_thread_tls, t); + + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); + + REQUIRE (t, "thread does not exist"); + + LUMIERA_CONDITION_SECTION (threads, &t->signal) + { + t->rh = &lumiera_lock_section_.rh; + + do { + // NULL function means: no work to do + INFO (threads, "function %p", t->function); + if (t->function) + t->function (t->arguments); + lumiera_threadpool_release_thread(t); + LUMIERA_CONDITION_WAIT (t->state != LUMIERA_THREADSTATE_IDLE); + INFO (threads, "Thread awaken with state %d", t->state); + } while (t->state != LUMIERA_THREADSTATE_SHUTDOWN); + // SHUTDOWN state + + if (t->kind & LUMIERA_THREAD_JOINABLE) + { + INFO (threads, "Thread zombified"); + /* move error state to data the other thread will it pick up from there */ + t->arguments = (void*)lumiera_error (); + t->state = LUMIERA_THREADSTATE_ZOMBIE; + LUMIERA_CONDITION_WAIT (t->state == LUMIERA_THREADSTATE_JOINED); + INFO (threads, "Thread joined"); + } + + INFO (threads, "Thread Shutdown"); + } + TODO ("no error must be pending here, else do app shutdown"); return 0; } -#if 0 -static void* pthread_runner (void* thread) -{ - pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); - - struct lumiera_thread_mockup* starter = (struct lumiera_thread_mockup*) thread; - LumieraReccondition thread_end_notification = starter->finished; - - starter->fn (starter->arg); - - if (!thread_end_notification) - return NULL; // no signalling of thread termination desired - - LUMIERA_RECCONDITION_SECTION(cond_sync, thread_end_notification) - LUMIERA_RECCONDITION_BROADCAST; - - return NULL; -} -#endif - -#if 0 -// TODO: rewrite this using lumiera_threadpool_acquire() -LumieraThread -lumiera_thread_run (enum lumiera_thread_class kind, - void (*start_routine)(void *), - void * arg, - LumieraReccondition finished, - const char* purpose, - struct nobug_flag* flag) -{ - (void) kind; - (void) purpose; - (void) flag; - - if (attr_once == PTHREAD_ONCE_INIT) - pthread_once (&attr_once, thread_attr_init); - - static struct lumiera_thread_mockup thread; - - thread.fn = start_routine; - thread.arg = arg; - thread.finished = finished; - - pthread_t dummy; - int error = pthread_create (&dummy, &attrs, pthread_runner, &thread); - - if (error) return 0; /////TODO temporary addition by Ichthyo; probably we'll set lumiera_error? - return (LumieraThread) 1; -} -#endif - -// TODO: new implementation, remove the above one -// maybe this shouldn't return LumieraThread at all // when this is called it should have already been decided that the function // shall run in parallel, as a thread LumieraThread lumiera_thread_run (enum lumiera_thread_class kind, void (*function)(void *), void * arg, - LumieraReccondition finished, const char* purpose, struct nobug_flag* flag) { - (void)finished; - (void)function; - (void)arg; - // ask the threadpool for a thread (it might create a new one) - LumieraThread self = lumiera_threadpool_acquire_thread(kind, purpose, flag); + TRACE (threads); + // REQUIRE (function, "invalid function"); - // TODO: set the function and data to be run - // lumiera_thread_set_func_data (self, start_routine, arg, purpose, flag); + // ask the threadpool for a thread (it might create a new one) + LumieraThread self = lumiera_threadpool_acquire_thread (kind, purpose, flag); + + // set the function and data to be run + self->function = function; + self->arguments = arg; + + self->deadline.tv_sec = 0; // and let it really run (signal the condition var, the thread waits on it) - LUMIERA_RECCONDITION_SECTION(cond_sync, self->finished) - LUMIERA_RECCONDITION_SIGNAL; + self->state = LUMIERA_THREADSTATE_WAKEUP; + + LUMIERA_CONDITION_SECTION (cond_sync, &self->signal) + LUMIERA_CONDITION_SIGNAL; // NOTE: example only, add solid error handling! @@ -159,33 +155,29 @@ lumiera_thread_run (enum lumiera_thread_class kind, */ LumieraThread lumiera_thread_new (enum lumiera_thread_class kind, - LumieraReccondition finished, const char* purpose, struct nobug_flag* flag, pthread_attr_t* attrs) { + pthread_once (&lumiera_thread_initialized, lumiera_thread_tls_init); + // TODO: do something with these: (void) purpose; - (void) flag; - REQUIRE (kind < LUMIERA_THREADCLASS_COUNT, "invalid thread kind specified: %d", kind); REQUIRE (attrs, "invalid pthread attributes structure passed"); - //REQUIRE (finished, "invalid finished flag passed"); - - LumieraThread self = lumiera_malloc (sizeof (*self)); - llist_init(&self->node); - self->finished = finished; + llist_init (&self->node); + lumiera_condition_init (&self->signal, "thread-control", flag); self->kind = kind; - self->state = LUMIERA_THREADSTATE_IDLE; + self->state = LUMIERA_THREADSTATE_STARTUP; + self->function = NULL; + self->arguments = NULL; + self->deadline.tv_sec = 0; + self->deadline.tv_nsec = 0; - //REQUIRE (thread_loop); int error = pthread_create (&self->id, attrs, &thread_loop, self); - ENSURE(error == 0 || EAGAIN == error, "pthread returned %d:%s", error, strerror(error)); if (error) { - // error here can only be EAGAIN, given the above ENSURE - FIXME ("error is %d:%s, see if this can be improved", error, strerror(error)); LUMIERA_DIE (ERRNO); } return self; @@ -194,24 +186,161 @@ lumiera_thread_new (enum lumiera_thread_class kind, LumieraThread lumiera_thread_destroy (LumieraThread self) { + TRACE (threads); REQUIRE (self, "trying to destroy an invalid thread"); - // TODO: stop the pthread - llist_unlink(&self->node); - //finished = NULL; // or free(finished)? - lumiera_reccondition_destroy (self->finished, &NOBUG_FLAG(threads)); - //kind = 0; - //state = 0; + llist_unlink (&self->node); + + // get the pthread out of the processing loop + // need to signal to the thread that it should start quitting + // should this be within the section? + LUMIERA_CONDITION_SECTION (threads, &self->signal) + { + REQUIRE (self->state == LUMIERA_THREADSTATE_IDLE, "trying to delete a thread in state other than IDLE (%s)", lumiera_threadstate_names[self->state]); + self->state = LUMIERA_THREADSTATE_SHUTDOWN; + self->function = NULL; + self->arguments = NULL; + LUMIERA_CONDITION_SIGNAL; + } + + int error = pthread_join (self->id, NULL); + ENSURE (0 == error, "pthread_join returned %d:%s", error, strerror (error)); + + // condition has to be destroyed after joining with the thread + lumiera_condition_destroy (&self->signal, &NOBUG_FLAG (threads)); + return self; } void lumiera_thread_delete (LumieraThread self) { - ECHO ("deleting thread"); + TRACE (threads); lumiera_free (lumiera_thread_destroy (self)); } + +LumieraThread +lumiera_thread_self (void) +{ + pthread_once (&lumiera_thread_initialized, lumiera_thread_tls_init); + return pthread_getspecific (lumiera_thread_tls); +} + + +/** + * Set a threads deadline + * A thread must finish before its deadline is hit. Otherwise it counts as stalled + * which is a fatal error which might pull the application down. + */ +LumieraThread +lumiera_thread_deadline_set (struct timespec deadline) +{ + LumieraThread self = lumiera_thread_self (); + if (self) + self->deadline = deadline; + return self; +} + + +/** + * Extend a threads deadline + * sets the deadline to now+ms in future. This can be used to implement a heartbeat. + */ +LumieraThread +lumiera_thread_deadline_extend (unsigned ms) +{ + LumieraThread self = lumiera_thread_self (); + if (self) + { + struct timespec deadline; + clock_gettime (CLOCK_REALTIME, &deadline); + deadline.tv_sec += ms / 1000; + deadline.tv_nsec += 1000000 * (ms % 1000); + if (deadline.tv_nsec > 1000000000) + { + deadline.tv_sec += (deadline.tv_nsec / 1000000000); + deadline.tv_nsec %= 1000000000; + } + self->deadline = deadline; + } + + return self; +} + + +/** + * Clear a threads deadline + * Threads without deadline will not be checked against deadlocks (this is the default) + */ +LumieraThread +lumiera_thread_deadline_clear (void) +{ + LumieraThread self = lumiera_thread_self (); + if (self) + { + self->deadline.tv_sec = 0; + self->deadline.tv_nsec = 0; + } + return self; +} + + + +LumieraThread +lumiera_thread_sync_other (LumieraThread other, int state) +{ + TRACE(threads); + + LUMIERA_CONDITION_SECTION (threads, &other->signal) + { + REQUIRE (other->state == ~state); TODO("Runtime error when state expectation isnt met"); + other->state = state; + LUMIERA_CONDITION_SIGNAL; + } + return other; +} + + +LumieraThread +lumiera_thread_sync (int state) +{ + TRACE(threads); + + LumieraThread self = lumiera_thread_self (); + REQUIRE(self, "not a lumiera thread"); + + self->state = ~state; + + TODO("error handing, maybe timed mutex (using the threads heartbeat timeout, shortly before timeout)"); + + while (self->state != state) { + lumiera_condition_wait (&self->signal, &NOBUG_FLAG(threads), self->rh); + } + + return self; +} + + + +lumiera_err +lumiera_thread_join (LumieraThread thread) +{ + TRACE(threads); + lumiera_err ret = NULL; + + LUMIERA_CONDITION_SECTION (threads, &thread->signal) + { + LUMIERA_CONDITION_WAIT (thread->state == LUMIERA_THREADSTATE_ZOMBIE); + ret = (lumiera_err)thread->arguments; + thread->state = LUMIERA_THREADSTATE_JOINED; + LUMIERA_CONDITION_SIGNAL; /* kiss it a last goodbye */ + } + return ret; +} + + + /* // Local Variables: // mode: C diff --git a/src/backend/threads.h b/src/backend/threads.h index e8b774299..131d25911 100644 --- a/src/backend/threads.h +++ b/src/backend/threads.h @@ -23,7 +23,7 @@ #define LUMIERA_THREADS_H //TODO: Support library includes// -#include "lib/reccondition.h" +#include "lib/condition.h" //TODO: Forward declarations// @@ -34,6 +34,7 @@ //TODO: System includes// #include +NOBUG_DECLARE_FLAG (threads); /** @@ -79,10 +80,15 @@ enum lumiera_thread_class * flag to let the decision to run the function in a thread open to the backend. * depending on load it might decide to run it sequentially. * This has some constraints: - * The condition variable to signal the finish of the thread must not be used. * The Thread must be very careful with locking, better don't. + * TODO explain syncronization issues **/ - LUMIERA_THREAD_OR_NOT = 1<<16 + LUMIERA_THREAD_OR_NOT = 1<<16, + + /** + * Thread must be joined finally + **/ + LUMIERA_THREAD_JOINABLE = 1<<17 }; #undef LUMIERA_THREAD_CLASS @@ -90,10 +96,18 @@ enum lumiera_thread_class // defined in threads.c extern const char* lumiera_threadclass_names[]; -#define LUMIERA_THREAD_STATES \ - LUMIERA_THREAD_STATE(IDLE) \ - LUMIERA_THREAD_STATE(RUNNING) \ - LUMIERA_THREAD_STATE(ERROR) +// there is some confusion between the meaning of this +// on one hand it could be used to tell the current state of the thread +// on the other, it is used to tell the thread which state to enter on next iteration +#define LUMIERA_THREAD_STATES \ + LUMIERA_THREAD_STATE(ERROR) \ + LUMIERA_THREAD_STATE(IDLE) \ + LUMIERA_THREAD_STATE(RUNNING) \ + LUMIERA_THREAD_STATE(WAKEUP) \ + LUMIERA_THREAD_STATE(SHUTDOWN) \ + LUMIERA_THREAD_STATE(ZOMBIE) \ + LUMIERA_THREAD_STATE(JOINED) \ + LUMIERA_THREAD_STATE(STARTUP) #define LUMIERA_THREAD_STATE(name) LUMIERA_THREADSTATE_##name, @@ -101,9 +115,12 @@ extern const char* lumiera_threadclass_names[]; * Thread state. * These are the only states our threads can be in. */ -typedef enum +typedef enum { LUMIERA_THREAD_STATES + + LUMIERA_THREADSTATE_CUSTOM_START = 1024, + LUMIERA_THREADSTATE_CUSTOM_END = 32768, } lumiera_thread_state; @@ -120,16 +137,24 @@ extern const char* lumiera_threadstate_names[]; struct lumiera_thread_struct { llist node; // this should be first for easy casting - // the function and argument can be passed to the thread at creation time - // void (*function)(void*); - // void* arg; + pthread_t id; - LumieraReccondition finished; + // TODO: maybe this condition variable should be renamed when we have a better understanding of how it will be used + lumiera_condition signal; // control signal, state change signal + + struct timespec deadline; + + struct nobug_resource_user** rh; + // the following member could have been called "class" except that it would conflict with C++ keyword // as consequence, it's been decided to leave the type name containing the word "class", // while all members/variables called "kind" - enum lumiera_thread_class kind; - lumiera_thread_state state; + int kind; + + // this is used both as a command and as a state tracker + int state; + void (*function)(void *); + void * arguments; }; /** @@ -137,14 +162,21 @@ struct lumiera_thread_struct */ LumieraThread lumiera_thread_new (enum lumiera_thread_class kind, - LumieraReccondition finished, const char* purpose, struct nobug_flag* flag, pthread_attr_t* attrs); +/** + * Destroy and de-initialize a thread structure. + * Memory is not freed by this function. + */ LumieraThread lumiera_thread_destroy (LumieraThread self); +/** + * Actually free the memory used by the thread structure. + * Make sure to destroy the structure first. + */ void lumiera_thread_delete (LumieraThread self); @@ -161,8 +193,6 @@ lumiera_thread_delete (LumieraThread self); * @param kind class of the thread to start * @param function pointer to a function to execute in a thread (returning void, not void* as in pthreads) * @param arg generic pointer passed to the thread - * @param finished a condition variable to be broadcasted, if not NULL. - * The associated mutex should be locked at thread_run time already, else the signal can get lost. * @param purpose descriptive name of this thread, used by NoBug * @param flag NoBug flag used for logging the thread startup and return */ @@ -170,10 +200,89 @@ LumieraThread lumiera_thread_run (enum lumiera_thread_class kind, void (*function)(void *), void * arg, - LumieraReccondition finished, const char* purpose, struct nobug_flag* flag); +/** + * Query the LumieraThread handle of the current thread + * + * + * @return pointer to the (opaque) handle of the current lumiera thread or NULL when this is not a lumiera thread + */ +LumieraThread +lumiera_thread_self (void); + +/** + * Heartbeat and Deadlines + * + * Any thread can have an optional 'deadline' which must never be hit. + * This deadlines are lazily checked and if hit this is a fatal error which triggers + * an emergency shutdown. Thus threads are obliged to set and extend their deadlines + * accordingly. + * + */ + +/** + * Set a threads deadline + * A thread must finish before its deadline is hit. Otherwise it counts as stalled + * which is a fatal error which might pull the application down. + */ +LumieraThread +lumiera_thread_deadline_set (struct timespec deadline); + + +/** + * Extend a threads deadline + * sets the deadline to now+ms in future. This can be used to implement a heartbeat. + */ +LumieraThread +lumiera_thread_deadline_extend (unsigned ms); + + +/** + * Clear a threads deadline + * Threads without deadline will not be checked against deadlocks (this is the default) + */ +LumieraThread +lumiera_thread_deadline_clear (void); + + +/** + * Thread syncronization + * Lumiera threads can be syncronized with custom states. + * The syncronization primitives act as barrier over 2 threads, any thread reaching a syncronization + * point first is blocked until the other one reaches it with the same state. + * Providing different states is errorneous! + */ + + +/** + * Syncronize with another threads state + * + * this blocks until/unless the other thread reaches 'state' + */ +LumieraThread +lumiera_thread_sync_other (LumieraThread other, int state); + +/** + * Syncronize current thread + * + * signifies that this thread reached 'state' and blocks until/unless + * some other thread synced with this state + * @return on success pointer to self (opaque), or NULL on error + */ +LumieraThread +lumiera_thread_sync (int state); + +/** + * Joining threads + * a thread can be set up with the LUMEIRA_THREAD_JOINABLE flag, if so + * then it must be joined finally. Joining clears the error state of the joined thread + * and returns it to the joiner. + * + */ +lumiera_err +lumiera_thread_join (LumieraThread thread); #endif /* diff --git a/src/common/Makefile.am b/src/common/Makefile.am index 451b0a982..5defb5b98 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -18,10 +18,13 @@ liblumieracommon_la_srcdir = $(top_srcdir)/src/common lib_LTLIBRARIES += liblumieracommon.la -liblumieracommon_la_CPPFLAGS = $(AM_CPPFLAGS) -DLUMIERA_CONFIG_PATH="\"$(pkgdatadir)/config:.\"" -DLUMIERA_PLUGIN_PATH="\"$(pkglibdir)/:./.libs\"" -liblumieracommon_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wextra -Wall -Werror -liblumieracommon_la_CXXFLAGS = $(AM_CXXFLAGS) -Wextra -Wall -liblumieracommon_la_LIBADD = liblumiera.la +liblumieracommon_la_CPPFLAGS = $(AM_CPPFLAGS) -DLUMIERA_CONFIG_PATH="\"$(pkgdatadir)/config:.\"" -DLUMIERA_PLUGIN_PATH="\"$(pkglibdir)/:./.libs\"" +liblumieracommon_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_COMMON_CFLAGS) -std=gnu99 -Wextra -Wall -Werror +liblumieracommon_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_COMMON_CFLAGS) -Wextra -Wall +liblumieracommon_la_LIBADD = \ + $(LUMIERA_COMMON_LIBS) \ + liblumiera.la + liblumieracommon_la_SOURCES = \ $(liblumieracommon_la_srcdir)/config.c \ diff --git a/src/gui/Makefile.am b/src/gui/Makefile.am index 14cd4c8fe..021f29ddd 100644 --- a/src/gui/Makefile.am +++ b/src/gui/Makefile.am @@ -32,15 +32,15 @@ lumiera_ui.rc: # pkglib_LTLIBRARIES += gtk_gui.la -gtk_gui_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -gtk_gui_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +gtk_gui_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +gtk_gui_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_GUI_CFLAGS) -Wall -Wextra gtk_gui_la_CPPFLAGS = $(AM_CPPFLAGS) \ $(LUMIERA_GUI_CFLAGS) \ -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \ - -DLUMIERA_PLUGIN -I$(top_srcdir)/src/ \ - $(LUMIERA_GUI_CFLAGS) + -DLUMIERA_PLUGIN -I$(top_srcdir)/src/ + gtk_gui_la_LDFLAGS = -module -avoid-version -no-undefined -rpath /dev/null -shrext .lum gtk_gui_la_LIBADD = \ @@ -48,8 +48,7 @@ gtk_gui_la_LIBADD = \ liblumierabackend.la \ liblumieracommon.la \ liblumiera.la \ - $(LUMIERA_GUI_LIBS) \ - $(NOBUGMT_LUMIERA_LIBS) + $(LUMIERA_GUI_LIBS) gtk_gui_la_SOURCES = \ $(lumigui_srcdir)/guistart.cpp \ diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am index eb1a20548..7b6218ad8 100644 --- a/src/lib/Makefile.am +++ b/src/lib/Makefile.am @@ -18,8 +18,19 @@ liblumiera_la_srcdir = $(top_srcdir)/src/lib lib_LTLIBRARIES += liblumiera.la -liblumiera_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiera_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiera_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(LUMIERA_LIBRARY_CFLAGS) \ + -std=gnu99 -Wall -Wextra -Werror + +liblumiera_la_CXXFLAGS = \ + $(AM_CXXFLAGS) \ + $(LUMIERA_LIBRARY_CFLAGS) \ + -Wall -Wextra + +liblumiera_la_LIBADD = \ + $(LUMIERA_LIBRARY_LIBS) + liblumiera_la_SOURCES = \ $(liblumiera_la_srcdir)/error.c \ diff --git a/src/lib/condition.h b/src/lib/condition.h index 51abfb61a..9ad3370d7 100644 --- a/src/lib/condition.h +++ b/src/lib/condition.h @@ -92,12 +92,12 @@ * @param expr Conditon which must become true, else the condition variable goes back into sleep */ #define LUMIERA_CONDITION_WAIT(expr) \ - do { \ + while (!(expr)) { \ REQUIRE (lumiera_lock_section_.lock, "Condition mutex not locked"); \ lumiera_condition_wait (lumiera_lock_section_.lock, \ lumiera_lock_section_.flag, \ &lumiera_lock_section_.rh); \ - } while (!(expr)) + } /** @@ -108,15 +108,14 @@ * sets LUMIERA_ERROR_LOCK_TIMEOUT when the timeout passed */ #define LUMIERA_CONDITION_TIMEDWAIT(expr, timeout) \ - do { \ + while (!(expr)) { \ REQUIRE (lumiera_lock_section_.lock, "Condition mutex not locked"); \ if (!lumiera_condition_timedwait (lumiera_lock_section_.lock, \ timeout, \ lumiera_lock_section_.flag, \ &lumiera_lock_section_.rh)) \ break; \ - } while (!(expr)) - + } /** * Signal a condition variable diff --git a/src/lib/reccondition.h b/src/lib/reccondition.h index bbb321861..b8b8fbd97 100644 --- a/src/lib/reccondition.h +++ b/src/lib/reccondition.h @@ -91,12 +91,12 @@ * @param expr Condition which must become true, else the condition variable goes back into sleep */ #define LUMIERA_RECCONDITION_WAIT(expr) \ - do { \ + while (!(expr)) { \ REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \ lumiera_reccondition_wait (lumiera_lock_section_.lock, \ lumiera_lock_section_.flag, \ &lumiera_lock_section_.rh); \ - } while (!(expr)) + } /** @@ -107,15 +107,14 @@ * sets LUMIERA_ERROR_LOCK_TIMEOUT when the timeout passed */ #define LUMIERA_RECCONDITION_TIMEDWAIT(expr, timeout) \ - do { \ + while (!(expr)) { \ REQUIRE (lumiera_lock_section_.lock, "Reccondition mutex not locked"); \ if (!lumiera_reccondition_timedwait (lumiera_lock_section_.lock, \ timeout, \ lumiera_lock_section_.flag, \ &lumiera_lock_section_.rh)) \ break; \ - } while (!(expr)) - + } diff --git a/src/lumiera/Makefile.am b/src/lumiera/Makefile.am index 7085d32db..5f346beb7 100644 --- a/src/lumiera/Makefile.am +++ b/src/lumiera/Makefile.am @@ -18,20 +18,16 @@ lumiera_srcdir = $(top_srcdir)/src/lumiera bin_PROGRAMS += lumiera -lumiera_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -lumiera_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -lumiera_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +lumiera_CPPFLAGS = $(AM_CPPFLAGS) +lumiera_CFLAGS = $(AM_CFLAGS) $(LUMIERA_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +lumiera_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_CFLAGS) -Wall -Wextra lumiera_LDADD = \ + $(LUMIERA_LIBS) \ liblumieracommon.la \ liblumierabackend.la \ liblumieraproc.la \ - liblumiera.la \ - $(LUMIERA_PLUGIN_LIBS) \ - $(LUMIERA_GUI_LIBS) \ - $(NOBUGMT_LUMIERA_LIBS) \ - -lboost_program_options-mt \ - -lboost_regex-mt + liblumiera.la lumiera_SOURCES = \ $(lumiera_srcdir)/main.cpp diff --git a/src/proc/Makefile.am b/src/proc/Makefile.am index 7d4d331df..4c220197c 100644 --- a/src/proc/Makefile.am +++ b/src/proc/Makefile.am @@ -21,8 +21,8 @@ liblumiproc_la_srcdir = $(top_srcdir)/src/proc noinst_LTLIBRARIES += liblumiproc.la -liblumiproc_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiproc_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiproc_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiproc_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiproc_la_SOURCES = \ $(liblumiproc_la_srcdir)/controllerfacade.cpp \ @@ -36,8 +36,8 @@ liblumiproc_la_SOURCES = \ liblumiprocasset_la_srcdir = $(top_srcdir)/src/proc/asset noinst_LTLIBRARIES += liblumiprocasset.la -liblumiprocasset_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocasset_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocasset_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocasset_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocasset_la_SOURCES = \ $(liblumiprocasset_la_srcdir)/codec.cpp \ @@ -61,8 +61,8 @@ liblumiprocasset_la_SOURCES = \ liblumiprocengine_la_srcdir = $(top_srcdir)/src/proc/engine noinst_LTLIBRARIES += liblumiprocengine.la -liblumiprocengine_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocengine_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocengine_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocengine_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocengine_la_SOURCES = \ $(liblumiprocengine_la_srcdir)/buffhandle.cpp \ @@ -84,8 +84,8 @@ liblumiprocengine_la_SOURCES = \ liblumiprocmobject_la_srcdir = $(top_srcdir)/src/proc/mobject noinst_LTLIBRARIES += liblumiprocmobject.la -liblumiprocmobject_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocmobject_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocmobject_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocmobject_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocmobject_la_SOURCES = \ $(liblumiprocmobject_la_srcdir)/builderfacade.cpp \ @@ -101,8 +101,8 @@ liblumiprocmobject_la_SOURCES = \ liblumiprocmobjectbuilder_la_srcdir = $(top_srcdir)/src/proc/mobject/builder noinst_LTLIBRARIES += liblumiprocmobjectbuilder.la -liblumiprocmobjectbuilder_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocmobjectbuilder_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocmobjectbuilder_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocmobjectbuilder_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocmobjectbuilder_la_SOURCES = \ $(liblumiprocmobjectbuilder_la_srcdir)/assembler.cpp \ @@ -115,8 +115,8 @@ liblumiprocmobjectbuilder_la_SOURCES = \ liblumiproccontrol_la_srcdir = $(top_srcdir)/src/proc/control noinst_LTLIBRARIES += liblumiproccontrol.la -liblumiproccontrol_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiproccontrol_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiproccontrol_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiproccontrol_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiproccontrol_la_SOURCES = \ $(liblumiproccontrol_la_srcdir)/command.cpp \ @@ -130,8 +130,8 @@ liblumiproccontrol_la_SOURCES = \ liblumiprocplay_la_srcdir = $(top_srcdir)/src/proc/play noinst_LTLIBRARIES += liblumiprocplay.la -liblumiprocplay_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocplay_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocplay_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocplay_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocplay_la_SOURCES = \ $(liblumiprocplay_la_srcdir)/dummy-player-service.cpp \ @@ -141,8 +141,8 @@ liblumiprocplay_la_SOURCES = \ liblumiprocmobjectsession_la_srcdir = $(top_srcdir)/src/proc/mobject/session noinst_LTLIBRARIES += liblumiprocmobjectsession.la -liblumiprocmobjectsession_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumiprocmobjectsession_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumiprocmobjectsession_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumiprocmobjectsession_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumiprocmobjectsession_la_SOURCES = \ $(liblumiprocmobjectsession_la_srcdir)/abstractmo.cpp \ @@ -265,12 +265,13 @@ noinst_HEADERS += \ liblumieraproc_la_srcdir = $(top_srcdir)/src/proc lib_LTLIBRARIES += liblumieraproc.la -liblumieraproc_la_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wall -Wextra -Werror -liblumieraproc_la_CXXFLAGS = $(AM_CXXFLAGS) -Wall -Wextra +liblumieraproc_la_CFLAGS = $(AM_CFLAGS) $(LUMIERA_PROC_CFLAGS) -std=gnu99 -Wall -Wextra -Werror +liblumieraproc_la_CXXFLAGS = $(AM_CXXFLAGS) $(LUMIERA_PROC_CFLAGS) -Wall -Wextra liblumieraproc_la_SOURCES = liblumieraproc_la_LIBADD = \ + $(LUMIERA_PROC_LIBS) \ liblumiproc.la \ liblumiprocasset.la \ liblumiprocengine.la \ @@ -279,4 +280,3 @@ liblumieraproc_la_LIBADD = \ liblumiproccontrol.la \ liblumiprocplay.la \ liblumiprocmobjectsession.la - diff --git a/src/proc/mobject/placement.hpp b/src/proc/mobject/placement.hpp index 1ebb966ac..569dc6686 100644 --- a/src/proc/mobject/placement.hpp +++ b/src/proc/mobject/placement.hpp @@ -242,6 +242,7 @@ namespace mobject { /** @todo cleanup uses of ref-to-placement. See Ticket #115 */ typedef Placement PlacementMO; + //‘typedef class mobject::Placement mobject::PlacementMO’ typedef Placement PMO; diff --git a/src/tool/Makefile.am b/src/tool/Makefile.am index bacd925d8..d3851349b 100644 --- a/src/tool/Makefile.am +++ b/src/tool/Makefile.am @@ -18,13 +18,14 @@ lumitool_srcdir = $(top_srcdir)/src/tool noinst_PROGRAMS += luidgen -luidgen_CFLAGS = $(CFLAGS) $(NOBUGMT_LUMIERA_CFLAGS) -std=gnu99 -Wall -Werror + +luidgen_CFLAGS = $(CFLAGS) $(LUMIERA_TOOL_CFLAGS) -std=gnu99 -Wall -Werror luidgen_CPPFLAGS = -I$(top_srcdir)/src/ -luidgen_LDADD = liblumiera.la $(NOBUGMT_LUMIERA_LIBS) -lboost_regex-mt -lboost_program_options-mt +luidgen_LDADD = liblumiera.la $(LUMIERA_TOOL_LIBS) luidgen_SOURCES = $(lumitool_srcdir)/luidgen.c noinst_PROGRAMS += rsvg-convert -rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_GUI_CFLAGS) -std=gnu99 -Wall -Werror -rsvg_convert_LDADD = -lcairo -lglib-2.0 -lgthread-2.0 -lrsvg-2 +rsvg_convert_CPPFLAGS = $(AM_CPPFLAGS) $(LUMIERA_TOOL_CFLAGS) -std=gnu99 -Wall -Werror +rsvg_convert_LDADD = $(LUMIERA_TOOL_LIBS) rsvg_convert_SOURCES = $(lumitool_srcdir)/rsvg-convert.c diff --git a/tests/15locking.tests b/tests/15locking.tests index 0936499f2..7401d4b58 100644 --- a/tests/15locking.tests +++ b/tests/15locking.tests @@ -86,3 +86,12 @@ PLANNED "reccondition broadcasting" < #include +#include +#include + +void is_prime(void * arg) +{ + int number = *(int *)arg; + int prime = 1; + + for (int x = number; x >= sqrt(number); --x) + { + if (number % x == 0) + { + prime = 0; + break; + } + } + *(int *)arg = prime; +} TESTS_BEGIN +TEST ("threadpool-basic") +{ + lumiera_threadpool_init(); + lumiera_threadpool_destroy(); +} + +TEST ("threadpool1") +{ + ECHO("start by initializing the threadpool"); + lumiera_threadpool_init(); + LumieraThread t1 = + lumiera_threadpool_acquire_thread(LUMIERA_THREADCLASS_INTERACTIVE, + "test purpose", + &NOBUG_FLAG(NOBUG_ON)); + // lumiera_threadpool_release_thread(t1); + ECHO("acquired thread 1 %p",t1); + lumiera_threadpool_destroy(); +} + TEST ("basic-acquire-release") { ECHO("start by initializing the threadpool"); - lumiera_threadpool_init(100); + lumiera_threadpool_init(); ECHO("acquiring thread 1"); LumieraThread t1 = lumiera_threadpool_acquire_thread(LUMIERA_THREADCLASS_INTERACTIVE, "test purpose", - NULL); + &NOBUG_FLAG(NOBUG_ON)); ECHO("acquiring thread 2"); LumieraThread t2 = lumiera_threadpool_acquire_thread(LUMIERA_THREADCLASS_IDLE, "test purpose", - NULL); + &NOBUG_FLAG(NOBUG_ON)); ECHO("thread 1 kind=%s", lumiera_threadclass_names[t1->kind]); CHECK(LUMIERA_THREADCLASS_INTERACTIVE == t1->kind); @@ -54,16 +91,17 @@ TEST ("basic-acquire-release") CHECK(LUMIERA_THREADSTATE_IDLE == t2->state); ECHO("releasing thread 1"); - lumiera_threadpool_release_thread(t1); + //lumiera_threadpool_release_thread(t1); ECHO("thread 1 has been released"); ECHO("releasing thread 2"); - lumiera_threadpool_release_thread(t2); + //lumiera_threadpool_release_thread(t2); ECHO("thread 2 has been released"); lumiera_threadpool_destroy(); } +#if 0 TEST ("many-acquire-release") { @@ -79,7 +117,7 @@ TEST ("many-acquire-release") threads[i+kind*threads_per_pool_count] = lumiera_threadpool_acquire_thread(kind, "test purpose", - NULL); + &NOBUG_FLAG(NOBUG_ON)); } } @@ -107,7 +145,7 @@ TEST ("toomany-acquire-release") threads[i+kind*threads_per_pool_count] = lumiera_threadpool_acquire_thread(kind, "test purpose", - NULL); + &NOBUG_FLAG(NOBUG_ON)); } } @@ -119,5 +157,44 @@ TEST ("toomany-acquire-release") lumiera_threadpool_destroy(); } +#endif + +TEST ("no-function") +{ + LumieraThread t; + + lumiera_threadpool_init(); + + t = lumiera_thread_run (LUMIERA_THREADCLASS_INTERACTIVE, + NULL, + NULL, + "process my test function", + &NOBUG_FLAG(NOBUG_ON)); + + // cleanup + ECHO("finished waiting"); + lumiera_threadpool_destroy(); +} + +TEST ("process-function") +{ + // this is what the scheduler would do once it figures out what function a job needs to run + LumieraThread t; + int number = 440616; + + lumiera_threadpool_init(); + + ECHO ("the input to the function is %d", number); + + t = lumiera_thread_run (LUMIERA_THREADCLASS_INTERACTIVE, + &is_prime, + (void *)&number, //void * arg, + "process my test function", + &NOBUG_FLAG(NOBUG_ON)); // struct nobug_flag* flag) + + // cleanup + ECHO("finished waiting"); + lumiera_threadpool_destroy(); +} TESTS_END diff --git a/tests/backend/test-threads.c b/tests/backend/test-threads.c index 76da2f450..ddf43214e 100644 --- a/tests/backend/test-threads.c +++ b/tests/backend/test-threads.c @@ -47,15 +47,15 @@ void threadfn(void* blah) void threadsyncfn(void* blah) { struct timespec wait = {0,200000000}; - LumieraReccondition sync = (LumieraReccondition) blah; + LumieraCondition sync = (LumieraCondition) blah; ECHO ("thread starting up %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_SECTION(cond_sync, sync) + LUMIERA_CONDITION_SECTION(cond_sync, sync) { ECHO ("send startup signal %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_SIGNAL; + LUMIERA_CONDITION_SIGNAL; ECHO ("wait for trigger %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_WAIT(1); + LUMIERA_CONDITION_WAIT(1); } ECHO ("thread running %s", NOBUG_THREAD_ID_GET); @@ -91,7 +91,6 @@ TEST ("simple_thread") lumiera_thread_run (LUMIERA_THREADCLASS_WORKER, threadfn, NULL, - NULL, argv[1], NULL); @@ -102,32 +101,31 @@ TEST ("simple_thread") TEST ("thread_synced") { - lumiera_reccondition cnd; - lumiera_reccondition_init (&cnd, "threadsync", &NOBUG_FLAG(NOBUG_ON)); + lumiera_condition cnd; + lumiera_condition_init (&cnd, "threadsync", &NOBUG_FLAG(NOBUG_ON)); - LUMIERA_RECCONDITION_SECTION(cond_sync, &cnd) + LUMIERA_CONDITION_SECTION(cond_sync, &cnd) { ECHO ("main before thread %s", NOBUG_THREAD_ID_GET); lumiera_thread_run (LUMIERA_THREADCLASS_WORKER, threadsyncfn, &cnd, - &cnd, argv[1], NULL); ECHO ("main wait for thread being ready %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_WAIT(1); + LUMIERA_CONDITION_WAIT(1); ECHO ("main trigger thread %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_SIGNAL; + LUMIERA_CONDITION_SIGNAL; ECHO ("wait for thread end %s", NOBUG_THREAD_ID_GET); - LUMIERA_RECCONDITION_WAIT(1); + LUMIERA_CONDITION_WAIT(1); ECHO ("thread ended %s", NOBUG_THREAD_ID_GET); } - lumiera_reccondition_destroy (&cnd, &NOBUG_FLAG(NOBUG_ON)); + lumiera_condition_destroy (&cnd, &NOBUG_FLAG(NOBUG_ON)); } @@ -143,7 +141,6 @@ TEST ("mutex_thread") lumiera_thread_run (LUMIERA_THREADCLASS_WORKER, mutexfn, NULL, - NULL, argv[1], NULL); diff --git a/tests/components/Makefile.am b/tests/components/Makefile.am index 04eb5a685..a62bfcdf4 100644 --- a/tests/components/Makefile.am +++ b/tests/components/Makefile.am @@ -31,7 +31,7 @@ test_components_LDADD = \ liblumierabackend.la \ liblumieracommon.la \ liblumiera.la \ - $(NOBUGMT_LUMIERA_LIBS) -ldl -lboost_program_options-mt -lboost_regex-mt + $(LUMIERA_LIBS) test_components_SOURCES = \ $(testcomponents_srcdir)/backend/mediaaccessmock.cpp \ diff --git a/tests/lib/Makefile.am b/tests/lib/Makefile.am index d3626c720..d70cd432e 100644 --- a/tests/lib/Makefile.am +++ b/tests/lib/Makefile.am @@ -19,9 +19,12 @@ testlib_srcdir = $(top_srcdir)/tests/lib check_PROGRAMS += test-lib -test_lib_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(testlib_srcdir) $(LUMIERA_GUI_CFLAGS) +test_lib_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(testlib_srcdir) $(LUMIERA_GUI_CFLAGS) +#why gui cflags/libs? test_lib_LDADD = \ + $(LUMIERA_LIBRARY_LIBS) \ + $(LUMIERA_GUI_LIBS) \ liblumiprocmobjectbuilder.la \ liblumiprocmobjectsession.la \ liblumiprocmobject.la \ @@ -31,9 +34,7 @@ test_lib_LDADD = \ liblumiprocasset.la \ liblumierabackend.la \ liblumieracommon.la \ - liblumiera.la \ - $(LUMIERA_GUI_LIBS) \ - $(NOBUGMT_LUMIERA_LIBS) -ldl -lboost_program_options-mt -lboost_regex-mt + liblumiera.la test_lib_SOURCES = \ $(testlib_srcdir)/mainsuite.cpp \ diff --git a/tests/library/test-locking.c b/tests/library/test-locking.c index 14ec0c458..c073c18de 100644 --- a/tests/library/test-locking.c +++ b/tests/library/test-locking.c @@ -318,5 +318,41 @@ TEST ("recconditionforgotunlock") lumiera_reccondition_destroy (&reccond, &NOBUG_FLAG(NOBUG_ON)); } +TEST ("chainedrecconditionsection") +{ + lumiera_reccondition outer, inner; + lumiera_reccondition_init (&outer, "outer_recconditionsection", &NOBUG_FLAG(NOBUG_ON)); + lumiera_reccondition_init (&inner, "inner_recconditionsection", &NOBUG_FLAG(NOBUG_ON)); + + LUMIERA_RECCONDITION_SECTION (NOBUG_ON, &outer) + { + printf ("outer reccondition locked section\n"); + LUMIERA_RECCONDITION_SECTION_CHAIN (NOBUG_ON, &inner) + { + printf ("inner reccondition locked section\n"); + } + } + lumiera_reccondition_destroy (&outer, &NOBUG_FLAG(NOBUG_ON)); + lumiera_reccondition_destroy (&inner, &NOBUG_FLAG(NOBUG_ON)); +} + +TEST ("nestedrecconditionsection") +{ + lumiera_reccondition outer, inner; + lumiera_reccondition_init (&outer, "outer_recconditionsection", &NOBUG_FLAG(NOBUG_ON)); + lumiera_reccondition_init (&inner, "inner_recconditionsection", &NOBUG_FLAG(NOBUG_ON)); + + LUMIERA_RECCONDITION_SECTION (NOBUG_ON, &outer) + { + printf ("outer reccondition locked section\n"); + LUMIERA_RECCONDITION_SECTION (NOBUG_ON, &inner) + { + printf ("inner reccondition locked section\n"); + } + } + lumiera_reccondition_destroy (&outer, &NOBUG_FLAG(NOBUG_ON)); + lumiera_reccondition_destroy (&inner, &NOBUG_FLAG(NOBUG_ON)); +} + TESTS_END diff --git a/tests/test.conf b/tests/test.conf index c86e03260..38cdca9cc 100755 --- a/tests/test.conf +++ b/tests/test.conf @@ -1 +1 @@ -LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}: \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\):' +LOGSUPPRESS='^\(\*\*[0-9]*\*\* \)\?[0-9]\{10,\}: \(TRACE\|INFO\|NOTICE\|WARNING\|ERR\|TODO\|PLANNED\|FIXME\|DEPRECATED\|UNIMPLEMENTED\|RESOURCE_ANNOUNCE\):' diff --git a/tests/tool/Makefile.am b/tests/tool/Makefile.am index 7cd7e7e6b..b4762e9b1 100644 --- a/tests/tool/Makefile.am +++ b/tests/tool/Makefile.am @@ -19,6 +19,6 @@ lumitesttool_srcdir = $(top_srcdir)/tests/tool noinst_PROGRAMS += vgsuppression vgsuppression_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -vgsuppression_LDADD = $(NOBUGMT_LUMIERA_LIBS) liblumieraproc.la liblumierabackend.la liblumieracommon.la liblumiera.la -lboost_regex-mt -lboost_program_options-mt -ldl +vgsuppression_LDADD = $(LUMIERA_LIBS) liblumieraproc.la liblumierabackend.la liblumieracommon.la liblumiera.la -lboost_regex-mt -lboost_program_options-mt -ldl vgsuppression_SOURCES = $(lumitesttool_srcdir)/vgsuppression.c