Merge commit '6f07e4eedc6b624b1f9ae1004ad3e6a77027e028' into second-tp-attempt
Conflicts: src/backend/threads.c
This commit is contained in:
commit
fc15a2ac2c
8 changed files with 60 additions and 69 deletions
|
|
@ -32,7 +32,7 @@ iconcommand = python $(top_srcdir)/admin/render_icon.py
|
|||
32x32pre = $(prerendereddir)/32x32
|
||||
48x48pre = $(prerendereddir)/48x48
|
||||
|
||||
dist_pkgdata_DATA += \
|
||||
icons = \
|
||||
$(16x16)/app-icon.png $(22x22)/app-icon.png $(24x24)/app-icon.png $(32x32)/app-icon.png $(48x48)/app-icon.png \
|
||||
$(16x16)/tool-arrow.png $(22x22)/tool-arrow.png $(24x24)/tool-arrow.png $(32x32)/tool-arrow.png $(48x48)/tool-arrow.png \
|
||||
$(16x16)/tool-i-beam.png $(22x22)/tool-i-beam.png $(24x24)/tool-i-beam.png $(32x32)/tool-i-beam.png $(48x48)/tool-i-beam.png \
|
||||
|
|
@ -44,6 +44,10 @@ dist_pkgdata_DATA += \
|
|||
$(16x16)/panel-timeline.png \
|
||||
$(16x16)/panel-viewer.png $(22x22)/panel-viewer.png $(32x32)/panel-viewer.png
|
||||
|
||||
dist_pkgdata_DATA += $(icons)
|
||||
|
||||
all: $(icons)
|
||||
|
||||
clean-local:
|
||||
rm -rf $(16x16) $(22x22) $(24x24) $(32x32) $(48x48)
|
||||
|
||||
|
|
@ -75,19 +79,19 @@ $(16x16)/track-unlocked.png : $(svgdir)/track-unlocked.svg $(top_builddir)/rsvg-
|
|||
|
||||
# Panels
|
||||
|
||||
$(16x16)/panel-resources.png:
|
||||
$(16x16)/panel-resources.png: $(16x16pre)/panel-resources.png
|
||||
cp $(16x16pre)/panel-resources.png $(16x16)
|
||||
$(22x22)/panel-resources.png:
|
||||
$(22x22)/panel-resources.png: $(22x22pre)/panel-resources.png
|
||||
cp $(22x22pre)/panel-resources.png $(22x22)
|
||||
$(32x32)/panel-resources.png:
|
||||
$(32x32)/panel-resources.png: $(32x32pre)/panel-resources.png
|
||||
cp $(32x32pre)/panel-resources.png $(32x32)
|
||||
|
||||
$(16x16)/panel-timeline.png:
|
||||
$(16x16)/panel-timeline.png: $(16x16pre)/panel-timeline.png
|
||||
cp $(16x16pre)/panel-timeline.png $(16x16)
|
||||
|
||||
$(16x16)/panel-viewer.png:
|
||||
$(16x16)/panel-viewer.png: $(16x16pre)/panel-viewer.png
|
||||
cp $(16x16pre)/panel-viewer.png $(16x16)
|
||||
$(22x22)/panel-viewer.png:
|
||||
$(22x22)/panel-viewer.png: $(22x22pre)/panel-viewer.png
|
||||
cp $(22x22pre)/panel-viewer.png $(22x22)
|
||||
$(32x32)/panel-viewer.png:
|
||||
$(32x32)/panel-viewer.png: $(32x32pre)/panel-viewer.png
|
||||
cp $(32x32pre)/panel-viewer.png $(32x32)
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "backend/filehandlecache.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
#include "backend/mmapcache.h"
|
||||
#include "backend/threadpool.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/resource.h>
|
||||
|
|
@ -63,6 +64,9 @@ lumiera_backend_init (void)
|
|||
//NOBUG_INIT_FLAG (mmapcache);
|
||||
|
||||
TRACE (backend_dbg);
|
||||
|
||||
lumiera_threadpool_init ();
|
||||
|
||||
lumiera_filedescriptor_registry_init ();
|
||||
|
||||
lumiera_backend_pagesize = sysconf(_SC_PAGESIZE);
|
||||
|
|
@ -112,4 +116,5 @@ lumiera_backend_destroy (void)
|
|||
lumiera_mmapcache_delete ();
|
||||
lumiera_filehandlecache_delete ();
|
||||
lumiera_filedescriptor_registry_destroy ();
|
||||
lumiera_threadpool_destroy ();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ lumiera_threadpool_init(void)
|
|||
{
|
||||
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
|
||||
|
|
@ -95,24 +93,12 @@ lumiera_threadpool_destroy(void)
|
|||
|
||||
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);
|
||||
ENSURE (llist_is_empty (&threadpool.pool[i].working_list),
|
||||
"threads are still running");
|
||||
|
||||
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));
|
||||
|
|
@ -146,28 +132,16 @@ lumiera_threadpool_acquire_thread (enum lumiera_thread_class kind,
|
|||
&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);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -178,6 +152,7 @@ lumiera_threadpool_release_thread(LumieraThread thread)
|
|||
{
|
||||
TRACE (threadpool);
|
||||
REQUIRE (thread, "invalid thread given");
|
||||
thread->kind = thread->kind&0xff;
|
||||
REQUIRE (thread->kind < LUMIERA_THREADCLASS_COUNT, "thread belongs to an unknown pool kind: %d", thread->kind);
|
||||
|
||||
REQUIRE (thread->state != LUMIERA_THREADSTATE_IDLE, "trying to park an already idle thread");
|
||||
|
|
@ -192,16 +167,6 @@ lumiera_threadpool_release_thread(LumieraThread thread)
|
|||
// 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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -75,8 +75,6 @@ struct lumiera_threadpool_struct
|
|||
{
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -92,25 +92,30 @@ thread_loop (void* thread)
|
|||
t->rh = &lumiera_lock_section_.rh;
|
||||
|
||||
do {
|
||||
lumiera_threadpool_release_thread(t);
|
||||
LUMIERA_CONDITION_WAIT (t->state != LUMIERA_THREADSTATE_IDLE);
|
||||
INFO (threads, "Thread awaken with state %d", t->state);
|
||||
|
||||
// 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);
|
||||
TRACE (threads, "function done");
|
||||
|
||||
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_SIGNAL;
|
||||
LUMIERA_CONDITION_WAIT (t->state == LUMIERA_THREADSTATE_JOINED);
|
||||
INFO (threads, "Thread joined");
|
||||
}
|
||||
|
||||
} 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");
|
||||
}
|
||||
|
|
@ -121,7 +126,7 @@ thread_loop (void* thread)
|
|||
// 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,
|
||||
lumiera_thread_run (int kind,
|
||||
void (*function)(void *),
|
||||
void * arg,
|
||||
const char* purpose,
|
||||
|
|
@ -131,12 +136,12 @@ lumiera_thread_run (enum lumiera_thread_class kind,
|
|||
// REQUIRE (function, "invalid function");
|
||||
|
||||
// ask the threadpool for a thread (it might create a new one)
|
||||
LumieraThread self = lumiera_threadpool_acquire_thread (kind, purpose, flag);
|
||||
LumieraThread self = lumiera_threadpool_acquire_thread (kind&0xff, purpose, flag);
|
||||
|
||||
// set the function and data to be run
|
||||
self->function = function;
|
||||
self->arguments = arg;
|
||||
|
||||
self->kind = kind;
|
||||
self->deadline.tv_sec = 0;
|
||||
|
||||
// and let it really run (signal the condition var, the thread waits on it)
|
||||
|
|
@ -294,7 +299,7 @@ lumiera_thread_sync_other (LumieraThread other)
|
|||
|
||||
LUMIERA_CONDITION_SECTION (threads, &other->signal)
|
||||
{
|
||||
REQUIRE (other->state == LUMIERA_THREADSTATE_SYNCING, "the other thread is in the wrong state: %s", lumiera_threadstate_names[other->state]); TODO("Runtime error when state expectation isn't met");
|
||||
LUMIERA_CONDITION_WAIT (other->state == LUMIERA_THREADSTATE_SYNCING);
|
||||
other->state = LUMIERA_THREADSTATE_RUNNING;
|
||||
LUMIERA_CONDITION_SIGNAL;
|
||||
}
|
||||
|
|
@ -311,6 +316,7 @@ lumiera_thread_sync (void)
|
|||
REQUIRE(self, "not a lumiera thread");
|
||||
|
||||
self->state = LUMIERA_THREADSTATE_SYNCING;
|
||||
lumiera_condition_signal (&self->signal, &NOBUG_FLAG(threads));
|
||||
|
||||
TODO("error handing, maybe timed mutex (using the threads heartbeat timeout, shortly before timeout)");
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ enum lumiera_thread_class
|
|||
LUMIERA_THREAD_CLASSES
|
||||
/** this just denotes the number of classes listed above,
|
||||
it is used to create arrays **/
|
||||
LUMIERA_THREADCLASS_COUNT,
|
||||
LUMIERA_THREADCLASS_COUNT, /* must be <= 256, thats easy or? */
|
||||
|
||||
// .. various thread flags follow
|
||||
/**
|
||||
|
|
@ -83,12 +83,12 @@ enum lumiera_thread_class
|
|||
* 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<<8,
|
||||
|
||||
/**
|
||||
* Thread must be joined finally
|
||||
**/
|
||||
LUMIERA_THREAD_JOINABLE = 1<<17
|
||||
LUMIERA_THREAD_JOINABLE = 1<<9
|
||||
};
|
||||
|
||||
#undef LUMIERA_THREAD_CLASS
|
||||
|
|
@ -195,7 +195,7 @@ lumiera_thread_delete (LumieraThread self);
|
|||
* @param flag NoBug flag used for logging the thread startup and return
|
||||
*/
|
||||
LumieraThread
|
||||
lumiera_thread_run (enum lumiera_thread_class kind,
|
||||
lumiera_thread_run (int kind,
|
||||
void (*function)(void *),
|
||||
void * arg,
|
||||
const char* purpose,
|
||||
|
|
|
|||
|
|
@ -129,6 +129,13 @@ namespace backend {
|
|||
// while the third thread wasn't created at all.
|
||||
}
|
||||
|
||||
public:
|
||||
ThreadWrapperJoin_test()
|
||||
{ lumiera_threadpool_init(); }
|
||||
|
||||
~ThreadWrapperJoin_test()
|
||||
{ lumiera_threadpool_destroy(); }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,12 @@ namespace backend {
|
|||
ASSERT (sum==checksum);
|
||||
}
|
||||
|
||||
public:
|
||||
ThreadWrapper_test()
|
||||
{ lumiera_threadpool_init(); }
|
||||
|
||||
~ThreadWrapper_test()
|
||||
{ lumiera_threadpool_destroy(); }
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue