From 8226e63bf77d4ee44d66c3c3a79453e8e6d5c596 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 19 Jan 2010 00:27:49 +0100 Subject: [PATCH 1/7] FIX:add extra dependencie on precreated icons, fixes #111 this could prolly made simpler, but fixes the issue for now --- icons/Makefile.am | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/icons/Makefile.am b/icons/Makefile.am index ce0990f26..8bffefd44 100644 --- a/icons/Makefile.am +++ b/icons/Makefile.am @@ -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) From 995d81370912a147c2fad8e868274f0e371354ad Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 19 Jan 2010 18:46:02 +0100 Subject: [PATCH 2/7] add threadpool init/destroy to the global backend init/destroy --- src/backend/backend.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backend/backend.c b/src/backend/backend.c index f0099f6f6..5440632a1 100644 --- a/src/backend/backend.c +++ b/src/backend/backend.c @@ -27,6 +27,7 @@ #include "backend/filehandlecache.h" #include "backend/filedescriptor.h" #include "backend/mmapcache.h" +#include "backend/threadpool.h" #include #include @@ -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 (); } From cd39533899a711f0790181c7004856a9e20ef873 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Tue, 19 Jan 2010 18:46:32 +0100 Subject: [PATCH 3/7] the thread-wrapper tests need to init/destroy the threadpool --- tests/lib/thread-wrapper-join-test.cpp | 7 +++++++ tests/lib/thread-wrapper-test.cpp | 6 ++++++ 2 files changed, 13 insertions(+) diff --git a/tests/lib/thread-wrapper-join-test.cpp b/tests/lib/thread-wrapper-join-test.cpp index 93257e794..aff2ffab7 100644 --- a/tests/lib/thread-wrapper-join-test.cpp +++ b/tests/lib/thread-wrapper-join-test.cpp @@ -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(); } + }; diff --git a/tests/lib/thread-wrapper-test.cpp b/tests/lib/thread-wrapper-test.cpp index edd9660f1..af8a6f149 100644 --- a/tests/lib/thread-wrapper-test.cpp +++ b/tests/lib/thread-wrapper-test.cpp @@ -104,6 +104,12 @@ namespace backend { ASSERT (sum==checksum); } + public: + ThreadWrapper_test() + { lumiera_threadpool_init(); } + + ~ThreadWrapper_test() + { lumiera_threadpool_destroy(); } }; From 32217debe8d5b3762f06c66bd8da7c99b5ee9e03 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 20 Jan 2010 00:33:08 +0100 Subject: [PATCH 4/7] Fix threadloop * joining must be done inside the loop, doh * a thread must release itself first in the loop, new threads have to go idle when created --- src/backend/threads.c | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/backend/threads.c b/src/backend/threads.c index 4aeebbf23..2ec076978 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -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"); } From 12968bb78473dd49cfdc73cf8b96a85f67f2a346 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 20 Jan 2010 00:43:11 +0100 Subject: [PATCH 5/7] thread kind and flag handling * 256 states are enough for anyone (else fix the source) * add proper masking and handling of flags --- src/backend/threadpool.c | 1 + src/backend/threads.c | 6 +++--- src/backend/threads.h | 8 ++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/backend/threadpool.c b/src/backend/threadpool.c index 9de1e6d81..72a8bc32f 100644 --- a/src/backend/threadpool.c +++ b/src/backend/threadpool.c @@ -179,6 +179,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"); diff --git a/src/backend/threads.c b/src/backend/threads.c index 2ec076978..a47f3de50 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -126,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, @@ -136,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) diff --git a/src/backend/threads.h b/src/backend/threads.h index 980a168e3..cc264d188 100644 --- a/src/backend/threads.h +++ b/src/backend/threads.h @@ -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, From 95fed7fd0e8213e6395450a0857b8f693fb120cb Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 20 Jan 2010 01:03:41 +0100 Subject: [PATCH 6/7] remove thread counters (for now) counting the threads had a race when creating threads, with moving threads only between idle and working list we don't need the counters for operation anyways. Maybe later when we find out that we need them we can re-add them in a sane way --- src/backend/threadpool.c | 42 +++------------------------------------- src/backend/threadpool.h | 2 -- 2 files changed, 3 insertions(+), 41 deletions(-) diff --git a/src/backend/threadpool.c b/src/backend/threadpool.c index 72a8bc32f..98af4aa1a 100644 --- a/src/backend/threadpool.c +++ b/src/backend/threadpool.c @@ -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; @@ -194,16 +168,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; } } diff --git a/src/backend/threadpool.h b/src/backend/threadpool.h index 5a3455d39..28bb21020 100644 --- a/src/backend/threadpool.h +++ b/src/backend/threadpool.h @@ -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; From 6f07e4eedc6b624b1f9ae1004ad3e6a77027e028 Mon Sep 17 00:00:00 2001 From: Christian Thaeter Date: Wed, 20 Jan 2010 01:04:12 +0100 Subject: [PATCH 7/7] one more signal/wait for syncing --- src/backend/threads.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend/threads.c b/src/backend/threads.c index a47f3de50..abc2e1eb1 100644 --- a/src/backend/threads.c +++ b/src/backend/threads.c @@ -299,7 +299,7 @@ lumiera_thread_sync_other (LumieraThread other) LUMIERA_CONDITION_SECTION (threads, &other->signal) { - REQUIRE (other->state == LUMIERA_THREADSTATE_SYNCING); TODO("Runtime error when state expectation isnt met"); + LUMIERA_CONDITION_WAIT (other->state == LUMIERA_THREADSTATE_SYNCING); other->state = LUMIERA_THREADSTATE_RUNNING; LUMIERA_CONDITION_SIGNAL; } @@ -316,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)");