Add reccondition to threads, make its functionality complete
With this the threads are now usable, despite still a mockup implementation. Some basic tests to show their use included.
This commit is contained in:
parent
323724b623
commit
dd9b7a174f
6 changed files with 198 additions and 33 deletions
|
|
@ -29,10 +29,10 @@ liblumierabackend_la_SOURCES = \
|
||||||
$(liblumierabackend_la_srcdir)/file.c \
|
$(liblumierabackend_la_srcdir)/file.c \
|
||||||
$(liblumierabackend_la_srcdir)/filehandle.c \
|
$(liblumierabackend_la_srcdir)/filehandle.c \
|
||||||
$(liblumierabackend_la_srcdir)/filedescriptor.c \
|
$(liblumierabackend_la_srcdir)/filedescriptor.c \
|
||||||
|
$(liblumierabackend_la_srcdir)/filehandlecache.c \
|
||||||
$(liblumierabackend_la_srcdir)/mmap.c \
|
$(liblumierabackend_la_srcdir)/mmap.c \
|
||||||
$(liblumierabackend_la_srcdir)/mmapings.c \
|
$(liblumierabackend_la_srcdir)/mmapings.c \
|
||||||
$(liblumierabackend_la_srcdir)/mmapcache.c \
|
$(liblumierabackend_la_srcdir)/mmapcache.c \
|
||||||
$(liblumierabackend_la_srcdir)/filehandlecache.c \
|
|
||||||
$(liblumierabackend_la_srcdir)/enginefacade.cpp \
|
$(liblumierabackend_la_srcdir)/enginefacade.cpp \
|
||||||
$(liblumierabackend_la_srcdir)/scriptrunnerfacade.cpp \
|
$(liblumierabackend_la_srcdir)/scriptrunnerfacade.cpp \
|
||||||
$(liblumierabackend_la_srcdir)/netnodefacade.cpp
|
$(liblumierabackend_la_srcdir)/netnodefacade.cpp
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
//TODO: Support library includes//
|
//TODO: Support library includes//
|
||||||
|
|
||||||
|
#include "include/logging.h"
|
||||||
|
|
||||||
//TODO: Lumiera header includes//
|
//TODO: Lumiera header includes//
|
||||||
#include "threads.h"
|
#include "threads.h"
|
||||||
|
|
@ -41,8 +42,29 @@
|
||||||
|
|
||||||
//code goes here//
|
//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_once_t attr_once = PTHREAD_ONCE_INIT;
|
||||||
static pthread_attr_t attrs;
|
static pthread_attr_t attrs;
|
||||||
|
|
@ -51,24 +73,7 @@ static void thread_attr_init (void)
|
||||||
{
|
{
|
||||||
pthread_attr_init (&attrs);
|
pthread_attr_init (&attrs);
|
||||||
pthread_attr_setdetachstate (&attrs, PTHREAD_CREATE_DETACHED);
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -76,17 +81,14 @@ LumieraThread
|
||||||
lumiera_thread_run (enum lumiera_thread_class kind,
|
lumiera_thread_run (enum lumiera_thread_class kind,
|
||||||
void (*start_routine)(void *),
|
void (*start_routine)(void *),
|
||||||
void * arg,
|
void * arg,
|
||||||
LumieraCondition finished,
|
LumieraReccondition finished,
|
||||||
const char* purpose,
|
const char* purpose,
|
||||||
struct nobug_flag* flag)
|
struct nobug_flag* flag)
|
||||||
{
|
{
|
||||||
(void) kind;
|
(void) kind;
|
||||||
(void) finished;
|
|
||||||
(void) purpose;
|
(void) purpose;
|
||||||
(void) flag;
|
(void) flag;
|
||||||
|
|
||||||
REQUIRE (!finished, "Condition variable for finish notification not yet implemented");
|
|
||||||
|
|
||||||
if (attr_once == PTHREAD_ONCE_INIT)
|
if (attr_once == PTHREAD_ONCE_INIT)
|
||||||
pthread_once (&attr_once, thread_attr_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.fn = start_routine;
|
||||||
thread.arg = arg;
|
thread.arg = arg;
|
||||||
|
thread.finished = finished;
|
||||||
pthread_mutex_lock (&threads_mutex);
|
|
||||||
|
|
||||||
pthread_t dummy;
|
pthread_t dummy;
|
||||||
int error = pthread_create (&dummy, &attrs, pthread_runner, &thread);
|
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?
|
if (error) return 0; /////TODO temporary addition by Ichthyo; probably we'll set lumiera_error?
|
||||||
return (LumieraThread) 1;
|
return (LumieraThread) 1;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
#define LUMIERA_THREADS_H
|
#define LUMIERA_THREADS_H
|
||||||
|
|
||||||
//TODO: Support library includes//
|
//TODO: Support library includes//
|
||||||
#include "lib/condition.h"
|
#include "lib/reccondition.h"
|
||||||
|
|
||||||
|
|
||||||
//TODO: Forward declarations//
|
//TODO: Forward declarations//
|
||||||
|
|
@ -96,7 +96,7 @@ LumieraThread
|
||||||
lumiera_thread_run (enum lumiera_thread_class kind,
|
lumiera_thread_run (enum lumiera_thread_class kind,
|
||||||
void (*start_routine)(void *),
|
void (*start_routine)(void *),
|
||||||
void * arg,
|
void * arg,
|
||||||
LumieraCondition finished,
|
LumieraReccondition finished,
|
||||||
const char* purpose,
|
const char* purpose,
|
||||||
struct nobug_flag* flag);
|
struct nobug_flag* flag);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -105,4 +105,10 @@ test_interfaces_LDADD = \
|
||||||
-lboost_program_options-mt \
|
-lboost_program_options-mt \
|
||||||
-lboost_regex-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
|
TESTS = $(tests_srcdir)/test.sh
|
||||||
|
|
|
||||||
159
tests/backend/test-threads.c
Normal file
159
tests/backend/test-threads.c
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
/*
|
||||||
|
test-threads.c - test thread management
|
||||||
|
|
||||||
|
Copyright (C) Lumiera.org
|
||||||
|
2008, Christian Thaeter <ct@pipapo.org>
|
||||||
|
|
||||||
|
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 <stdio.h>
|
||||||
|
//#include <string.h>
|
||||||
|
|
||||||
|
#include "common/config.h"
|
||||||
|
|
||||||
|
#include "include/logging.h"
|
||||||
|
#include "lib/mutex.h"
|
||||||
|
#include "backend/threads.h"
|
||||||
|
#include "tests/test.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
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
|
||||||
|
|
@ -254,6 +254,7 @@ TEST ("conditionsection")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TEST ("conditionforgotunlock")
|
TEST ("conditionforgotunlock")
|
||||||
{
|
{
|
||||||
lumiera_condition cond;
|
lumiera_condition cond;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue