
please wait
The only peculiarity is that a handler runs at interrupt time and therefore suffers some restrictions on what it can do. ... Handlers also cannot do anything that would sleep, such as calling sleep_on, allocating memory with anything other than GFP_ATOMIC, or locking a semaphore. Finally, handlers cannot call schedule. |
|
|
A simple FIFO buffer made up of an array and 2 pointers (like first and last) won't work for this situation since this could lead to some serious synchronization problems when the buffer gets either empty or full. The problem here is that it is possible for FifoBuffer::pop() to get stopped in the middle of its execution by an interrupt that will then call FifoBuffer::push(). When it's done, control would be given back to FifoBuffer::pop(). |
|
|
|
|
So you got the following requirements, right? 1) "interrupt" can interrupt "main" unconditionally at any non-atomic instruction. 2) No other interruptions: "main" can not interrupt "interrupt". "interrupt" can not interrupt itself. "main" can not interrupt itself. 3) "interrupt" always call "push", "main" always call "pop" 4) "interrupt" must not do any fancy things that would block, including allocating memory on the heap (since new usually uses malloc and malloc usually do some locking stuff). As of requirement 4), it is not possible to find a solution that works perfectly in the case of buffer overflows ("interrupt" could be executed until any pre-allocated buffer overflows) |
I fail to see a problem with empty buffers. If pop and push can run concurently, everthing is fine. Actually, it should be even less problematic that other multi-threading scenarios because of 2) and 3) Use a ring-buffer and let "push" only writes to the write-pointer whereas "pop" only writes the read-pointer. |
The code is completely untested and written off the cuff. Excpect some typos :-D. But I hope you get the basic idea. |
write+1 == read
. Shame on me. Of course, it should be (write+1)%100 == read
;-)