Opened at 2009-09-29T01:14:24Z
Closed at 2010-01-16T11:35:40Z
#274 closed fixme (done)
sporadic false resource tracker alarms
| Reported by: | Ichthyostega | Owned by: | Ichthyostega |
|---|---|---|---|
| Priority: | normal | Milestone: | 0integration |
| Component: | lumiera | Keywords: | |
| Sub Tickets: | Parent Tickets: |
Description
NOBUG_RESOURCE_LEAVE happens after releasing the lock (sectionlock.h)
It is likely that another competing thread immediately aquires the lock when it gets available. In the observed cases, on thread termination, the other thread after unblocking proceeded with the dtor and pulled away the condition var, thus causing the alarm.
Change history (9)
comment:1 by , at 2009-09-29T01:45:10Z
| Status: | new → assigned |
|---|
comment:2 by , at 2009-12-15T19:28:35Z
| Status: | assigned → accepted |
|---|
comment:3 by , at 2009-12-17T01:48:04Z
fixed in nobug/devel but needs changes on the Lumiera code, i am working on this.
comment:4 by , at 2009-12-17T03:08:08Z
| Resolution: | → done |
|---|---|
| Status: | accepted → closed |
Fixed in:
http://git.lumiera.org/gitweb?p=lumiera/ct;a=commit;h=5c7abbded99585d7334f075f57c1b43437b3909a
This breaks 40components.test "Type-based contexts" TypedCounter_test, which hangs from the testsuite here, this needs to be investigated.
follow-up: 7 comment:5 by , at 2009-12-18T00:57:18Z
| Priority: | lesser → normal |
|---|---|
| Resolution: | done |
| Status: | closed → reopened |
Hi cehteh,
read your changes (including NoBug) and they look OK. I can't see why the test would hang.
Thus reopening and assigning this ticket to myself, as a reminder to investigate it
further with the debugger (after updating the NoBug package, which I'll do in some days)
For later referral, I'll reiterate the sequence of events:
- JoinHandle locks the mutex of the reccondition and handes it into the tread starter
- in the spawned child thread, after the end of the thread function, the thread starter
if (!thread_end_notification) return NULL; // no signalling of thread termination desired LUMIERA_RECCONDITION_SECTION(cond_sync, thread_end_notification) LUMIERA_RECCONDITION_BROADCAST;...which causes it to get blocked, as the thread_end_notification condition is already locked - in the destructor of the managing class, which inherits from JoinHandle (see typed-counter-test.cpp):
~SingleCheck () { this->join(); }which is implemented by the "manager" thread going into wait state - this has the sideeffect of releasing the lock, thus the child thread can now enter the LUMIERA_RECCONDITION_SECTION. It does the broadcast, but the manager thread still has to re-gain the lock
- now, the moment the LUMIERA_RECCONDITION_SECTION drops the lock, it could be prempted. Note, this is still in the middle of the LUMIERA_RECCONDITION_SECTION
- assumed this happens, now the manager thread can re-gain the lock and recieve the wakeup. This causes the destructor to continue and finish, thereby releasing the lock and then discarding the object including the condition variable.
- note this means lumiera_reccondition_destroy can be executed while the child thread is still preempted in the middle of the LUMIERA_RECCONDITION_SECTION. But as the resource tracking is now protected by a lock, this should cause no problem (?)
- similarily, as far as I can see, your modified code doesn't touch the lock or the condition anymore after releasing the lock; thus I'd expect it just to release and cleanup the nobug resource handle and then finish executing the child thread.
comment:6 by , at 2009-12-18T00:58:01Z
| Owner: | changed from to |
|---|---|
| Status: | reopened → assigned |
comment:7 by , at 2009-12-18T02:13:51Z
Replying to ichthyo:
Hi cehteh,
read your changes (including NoBug) and they look OK. I can't see why the test would hang.
Thus reopening and assigning this ticket to myself, as a reminder to investigate it
further with the debugger (after updating the NoBug package, which I'll do in some days)
For later referral, I'll reiterate the sequence of events:
- JoinHandle locks the mutex of the reccondition and handes it into the tread starter
- in the spawned child thread, after the end of the thread function, the thread starter
if (!thread_end_notification) return NULL; // no signalling of thread termination desired LUMIERA_RECCONDITION_SECTION(cond_sync, thread_end_notification) LUMIERA_RECCONDITION_BROADCAST;...which causes it to get blocked, as the thread_end_notification condition is already locked- in the destructor of the managing class, which inherits from JoinHandle (see typed-counter-test.cpp):
~SingleCheck () { this->join(); }which is implemented by the "manager" thread going into wait state- this has the sideeffect of releasing the lock, thus the child thread can now enter the LUMIERA_RECCONDITION_SECTION. It does the broadcast, but the manager thread still has to re-gain the lock
- now, the moment the LUMIERA_RECCONDITION_SECTION drops the lock, it could be prempted. Note, this is still in the middle of the LUMIERA_RECCONDITION_SECTION
- assumed this happens, now the manager thread can re-gain the lock and recieve the wakeup. This causes the destructor to continue and finish, thereby releasing the lock and then discarding the object including the condition variable.
- note this means lumiera_reccondition_destroy can be executed while the child thread is still preempted in the middle of the LUMIERA_RECCONDITION_SECTION. But as the resource tracking is now protected by a lock, this should cause no problem (?)
- similarily, as far as I can see, your modified code doesn't touch the lock or the condition anymore after releasing the lock; thus I'd expect it just to release and cleanup the nobug resource handle and then finish executing the child thread.
I am going over some more nobug things right now, next I want to refactor the lumiera locking (mutex/condition/rwlock). While Plouj now works on the threadpool it becomes imminent that the sync.hpp uses the resourcetracker too. I am thinking about factoring a lumiera_mutex_lock and lumiera_mutex_unlock function which includes the resourcetracking (and the same for condition vars and rwlocks). Then sync.hpp can use those and then may_block() enter() left() methods there can bite the dust.
comment:8 by , at 2009-12-18T12:57:12Z
btw, centralizing the locking at one place again will also make the lock profiling easier (contention timing...)
comment:9 by , at 2010-01-16T11:35:40Z
| Resolution: | → done |
|---|---|
| Status: | assigned → closed |

Yes, I had a glimpse of this problems, just didn't realized how often they can happen. Now while you point that out, this needs some fix, possibly changing the NoBug API creating a lock around this actions:
this goes from waiting to state while executing '...code...' inbetween and keeping the resourcetracker lock held
and similar a
which first locks the resource tracker, then executes '...code...' and then calls the leave and unlock the resourcetracker