Hi,
thank you for the stripped down example and the trace. After a while I found the reason of the bug, which handles the pending bit wrong for semaphore_down_timed calls. The fix is checked in and will be in the next days in the public svn repository.
Thank you Marc for reporting,
Alex.
Alexander Boettcher wrote:
Hi,
can you please provide us with a (stripped down) example of your consumer/producer problem. Currently I don't see why or when you are using/mixing down_timed and down in the consumer thread (do you check the result of down_timed ?)
Alex.
Marc CHALAND wrote:
Alexander Boettcher boettcher@os.inf.tu-dresden.de:
Marc CHALAND wrote:
- thread 08 calls semaphore_up inline assembler code. Before IPC
call, the semaphore structure is as follow : counter = 0 pending = 0 queue = 03
2.1 Now, Thread 02 (the semaphore thread) have to run, because this is the only one which remove threads from the queue. Otherwise the 3. step below isn't possible (empty queue, so thread 03 must be removed by thread 02 from the queue).
Is there a mecanism which prevents thread 03 from running before IPC call ?
Thread 03 can be preempted by the kernel and another thread can be scheduled (between decrementing counter and sending the IPC).
- Thread 03 gains the CPU after timeout and calls IPC RELEASETIMED :
counter = 1 pending = 0 queue = empty
Thread 03 increment the counter only if it gets really a timeout, however the queue is already empty that means that thread 02 executed between 2. and 3. step (2.1). Therefore Thread 03 should get a wakeup IPC from Thread 02 instead of a timeout.
Into the code, it seams that after IPC timeout, counter is incremented immediately, isn't it ?
After the IPC call is finished (for whatever reason), the result (res != 0) is checked. If it is a timeout, a abort or was canceled than the counter is incremented, otherwise not.
After, 03 sends IPC RELEASETIMED and thread 02 removes thread from queue.
- Thread 02 doesn't find thread into queue, so that pending is set to 1.
counter = 1 pending = 1 queue = empty
This matches what you said into 2.1. In fact, I think 08 is interrupted in such a way that when IPC is sent, there is nothing into queue, so pending is set to 1.
Please provide us with your example code.
In state 5. and 6. the same thread (thread 03) calls semaphore_down twice without any semaphore_ups in between by other threads.
Yes, 03 is a consumer, not a producer. I don't use semaphore for critical section but for a producer/consumer mecanism. 03 only makes down_timed before a pop from queue and others make up after a push into queue.
Why the thread 03 acquires the semaphore again when it has it already ?
First time, counter is > 0 so, no ipc is called. Second time, pending is also >0, so thread is imediately awaken even if counter is < 0.
This will cause strange behavior of your application/semaphore or will cause dead locks.
It causes semaphore_down exits without error code as my queue is empty which is annoying.
Marc