diff --git a/src/backend/Makefile.am b/src/backend/Makefile.am index c2161cc82..5729d910b 100644 --- a/src/backend/Makefile.am +++ b/src/backend/Makefile.am @@ -19,7 +19,7 @@ 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_CFLAGS = $(AM_CFLAGS) -std=gnu99 -Wextra -Wall -Werror liblumierabackend_la_LIBADD = liblumiera.la liblumierabackend_la_SOURCES = \ @@ -29,10 +29,10 @@ liblumierabackend_la_SOURCES = \ $(liblumierabackend_la_srcdir)/file.c \ $(liblumierabackend_la_srcdir)/filehandle.c \ $(liblumierabackend_la_srcdir)/filedescriptor.c \ + $(liblumierabackend_la_srcdir)/filehandlecache.c \ $(liblumierabackend_la_srcdir)/mmap.c \ $(liblumierabackend_la_srcdir)/mmapings.c \ $(liblumierabackend_la_srcdir)/mmapcache.c \ - $(liblumierabackend_la_srcdir)/filehandlecache.c \ $(liblumierabackend_la_srcdir)/enginefacade.cpp \ $(liblumierabackend_la_srcdir)/scriptrunnerfacade.cpp \ $(liblumierabackend_la_srcdir)/netnodefacade.cpp diff --git a/src/backend/threads.c b/src/backend/threads.c index 794d13b79..1ff7184f9 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -21,6 +21,7 @@ //TODO: Support library includes// +#include "include/logging.h" //TODO: Lumiera header includes// #include "threads.h" @@ -41,8 +42,29 @@ //code goes here// -/* really dumb mutex, to make the mockup little less brittle */ -static pthread_mutex_t threads_mutex = PTHREAD_MUTEX_INITIALIZER; + +struct lumiera_thread_mockup +{ + void (*fn)(void*); + void* arg; + LumieraReccondition finished; +}; + + +static void* pthread_runner (void* thread) +{ + pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); + + struct lumiera_thread_mockup* starter = (struct lumiera_thread_mockup*) thread; + + starter->fn (starter->arg); + + LUMIERA_RECCONDITION_SECTION(cond_sync, starter->finished) + LUMIERA_RECCONDITION_BROADCAST; + + return NULL; +} + static pthread_once_t attr_once = PTHREAD_ONCE_INIT; static pthread_attr_t attrs; @@ -51,42 +73,22 @@ static void thread_attr_init (void) { pthread_attr_init (&attrs); pthread_attr_setdetachstate (&attrs, PTHREAD_CREATE_DETACHED); - pthread_attr_setdetachstate (&attrs, PTHREAD_CREATE_DETACHED); + //cancel ... } -struct lumiera_thread_mockup -{ - void (*fn)(void*); - void* arg; -}; - - -static void* pthread_runner (void* thread) -{ - struct lumiera_thread_mockup* starter = (struct lumiera_thread_mockup*) thread; - (void) starter; - pthread_mutex_lock (&threads_mutex); - pthread_mutex_unlock (&threads_mutex); - starter->fn (starter->arg); - return NULL; -} - - + LumieraThread lumiera_thread_run (enum lumiera_thread_class kind, void (*start_routine)(void *), void * arg, - LumieraCondition finished, + LumieraReccondition finished, const char* purpose, struct nobug_flag* flag) { (void) kind; - (void) finished; (void) purpose; (void) flag; - REQUIRE (!finished, "Condition variable for finish notification not yet implemented"); - if (attr_once == PTHREAD_ONCE_INIT) pthread_once (&attr_once, thread_attr_init); @@ -94,14 +96,11 @@ lumiera_thread_run (enum lumiera_thread_class kind, thread.fn = start_routine; thread.arg = arg; - - pthread_mutex_lock (&threads_mutex); + thread.finished = finished; pthread_t dummy; int error = pthread_create (&dummy, &attrs, pthread_runner, &thread); - pthread_mutex_unlock (&threads_mutex); - if (error) return 0; /////TODO temporary addition by Ichthyo; probably we'll set lumiera_error? return (LumieraThread) 1; } diff --git a/src/backend/threads.h b/src/backend/threads.h index 50786c729..9d420fa2f 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/condition.h" +#include "lib/reccondition.h" //TODO: Forward declarations// @@ -96,7 +96,7 @@ LumieraThread lumiera_thread_run (enum lumiera_thread_class kind, void (*start_routine)(void *), void * arg, - LumieraCondition finished, + LumieraReccondition finished, const char* purpose, struct nobug_flag* flag); diff --git a/tests/Makefile.am b/tests/Makefile.am index acaf205b6..f5404f3f1 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -105,4 +105,10 @@ test_interfaces_LDADD = \ -lboost_program_options-mt \ -lboost_regex-mt +check_PROGRAMS += test-threads +test_threads_SOURCES = $(tests_srcdir)/backend/test-threads.c +test_threads_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/ +test_threads_CFLAGS = $(AM_CFLAGS) $(PTHREAD_CFLAGS) +test_threads_LDADD = liblumierabackend.la liblumiera.la -lnobugmt -lpthread -ldl -lm liblumieracommon.la liblumieraproc.la -ldl -lboost_program_options-mt -lboost_regex-mt + TESTS = $(tests_srcdir)/test.sh diff --git a/tests/backend/test-threads.c b/tests/backend/test-threads.c new file mode 100644 index 000000000..14237f7a2 --- /dev/null +++ b/tests/backend/test-threads.c @@ -0,0 +1,159 @@ +/* + test-threads.c - test thread management + + Copyright (C) Lumiera.org + 2008, Christian Thaeter + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +//#include +//#include + +#include "common/config.h" + +#include "include/logging.h" +#include "lib/mutex.h" +#include "backend/threads.h" +#include "tests/test.h" + +#include +#include +#include + +void threadfn(void* blah) +{ + (void) blah; + struct timespec wait = {0,300000000}; + + fprintf (stderr, "thread running %s\n", NOBUG_THREAD_ID_GET); + nanosleep (&wait, NULL); + fprintf (stderr, "thread done %s\n", NOBUG_THREAD_ID_GET); +} + + +void threadsyncfn(void* blah) +{ + struct timespec wait = {0,200000000}; + LumieraReccondition sync = (LumieraReccondition) blah; + + ECHO ("thread starting up %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_SECTION(cond_sync, sync) + { + ECHO ("send startup signal %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_SIGNAL; + ECHO ("wait for trigger %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_WAIT(1); + } + + ECHO ("thread running %s", NOBUG_THREAD_ID_GET); + nanosleep (&wait, NULL); + ECHO ("thread done %s", NOBUG_THREAD_ID_GET); +} + + + +lumiera_mutex testmutex; + +void mutexfn(void* blah) +{ + (void) blah; + struct timespec wait = {0,300000000}; + + LUMIERA_MUTEX_SECTION (NOBUG_ON, &testmutex) + { + fprintf (stderr, "mutex thread running %s\n", NOBUG_THREAD_ID_GET); + nanosleep (&wait, NULL); + fprintf (stderr, "thread done %s\n", NOBUG_THREAD_ID_GET); + } +} + + + +TESTS_BEGIN + +TEST ("simple_thread") +{ + fprintf (stderr, "main before thread %s\n", NOBUG_THREAD_ID_GET); + + lumiera_thread_run (LUMIERA_THREAD_WORKER, + threadfn, + NULL, + NULL, + argv[1], + NULL); + + struct timespec wait = {0,600000000}; + nanosleep (&wait, NULL); + fprintf (stderr, "main after thread %s\n", NOBUG_THREAD_ID_GET); +} + +TEST ("thread_synced") +{ + lumiera_reccondition cnd; + lumiera_reccondition_init (&cnd, "threadsync", &NOBUG_FLAG(NOBUG_ON)); + + LUMIERA_RECCONDITION_SECTION(cond_sync, &cnd) + { + ECHO ("main before thread %s", NOBUG_THREAD_ID_GET); + + lumiera_thread_run (LUMIERA_THREAD_WORKER, + threadsyncfn, + &cnd, + &cnd, + argv[1], + NULL); + + ECHO ("main wait for thread being ready %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_WAIT(1); + + ECHO ("main trigger thread %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_SIGNAL; + + ECHO ("wait for thread end %s", NOBUG_THREAD_ID_GET); + LUMIERA_RECCONDITION_WAIT(1); + ECHO ("thread ended %s", NOBUG_THREAD_ID_GET); + } + + lumiera_reccondition_destroy (&cnd, &NOBUG_FLAG(NOBUG_ON)); +} + + + +TEST ("mutex_thread") +{ + lumiera_mutex_init (&testmutex, "test", &NOBUG_FLAG(NOBUG_ON)); + + LUMIERA_MUTEX_SECTION (NOBUG_ON, &testmutex) + { + fprintf (stderr, "main before thread %s\n", NOBUG_THREAD_ID_GET); + + lumiera_thread_run (LUMIERA_THREAD_WORKER, + mutexfn, + NULL, + NULL, + argv[1], + NULL); + + struct timespec wait = {0,600000000}; + nanosleep (&wait, NULL); + fprintf (stderr, "main after thread %s\n", NOBUG_THREAD_ID_GET); + } + + lumiera_mutex_destroy (&testmutex, &NOBUG_FLAG(NOBUG_ON)); +} + + +TESTS_END diff --git a/tests/library/test-locking.c b/tests/library/test-locking.c index 5728783ec..14ec0c458 100644 --- a/tests/library/test-locking.c +++ b/tests/library/test-locking.c @@ -254,6 +254,7 @@ TEST ("conditionsection") } + TEST ("conditionforgotunlock") { lumiera_condition cond;