Waiting for a periodic event with wait_event_interruptible - linux-kernel

I am writing a kernel module that performs timing functions using an external clock. Basically, the module counts pulses from the clock, rolling over the count every so often. User processes can use an ioctl to ask to be woken up at a specific count; they then perform some task and invoke the same ioctl to wait until the next time the same count comes up. In this way they can execute periodically using this external timing.
I have created an array of wait_queue_head_ts, one for each available schedule slot (i.e. each "count", as described above). When a user process invokes the ioctl, I simply call sleep_on() with the ioctl argument specifying the schedule slot and thus the wait queue. When the kernel module receives a clock pulse and increments the count, it wakes up the wait queue corresponding to that count.
I know that it is considered bad practice to use sleep_on(), because there is potential for state to change between a test to see if a process should sleep, and the corresponding call to sleep_on(). But in this case I do not perform such a test before sleeping because the waking event is periodic. It doesn't matter if I "just miss" a waking event because another will come shortly (in fact, if the ioctl is invoked very close to the specified schedule slot, then something went wrong and I would prefer to wait until the next slot anyway).
I have looked at using wait_event_interruptible(), which is considered safer, but I do not know what to put for the condition argument that wait_event_interruptible requires. wait_event_interruptible will check this condition before sleeping, but I want it to always sleep when the ioctl is invoked. I could use a flag that I clear before sleeping and set before waking up, but I'm worried this might not work in the case that there are multiple processes in the wait queue - one process might finish and clear the flag before the next is woken up.
Am I right to be worried about this? Or are all processes in a wait_queue guaranteed to be woken up before any of them run (and could therefore clear the flag)? Is there a better way to go about implementing a system such as this one? Is it actually okay to just use sleep_on()? (If so, is there a version of sleep_on() that is interruptible?)

Interruptible version of sleep_on is interruptible_sleep_on. Note, that sleep-functions have been removed since kernel 3.15.
As for wait_event_interruptible, requirement I want it to always sleep when the ioctl is invoked. is uncommon for it. You may use a flag, but this flag should be per-process (or per-schedule slot). Or you may modify count for wait to be at least current_count + 1.
In such uncommon scenario, instead of macro wait_event_interruptible you may use blocks it consist of, and arrange them in the way you need. Generally, any waiting can be achived in that way.

Related

Which is best way to wait event until expire in golang, timer or goroutine loop?

the state machine's first state is waiting for one event, if the event doesn't happen in certain days, the status machine will switch to the second state. If the event happened in the period, the state machine will switch to the third state.
I have two option:
1, Use a timer. Set up a timer as certain days. When time is up, checking does the event happened or not. If happened, switch to the third state. If not, switch to the second state. It is possible that thousands of timers will be created in the period.
2, Use a looping with routine. Start a routine to run a loop. Every half hour, the goroutine will check the event happened or not. If the event happened, switch to the third state. Else, keep looping until expired the certain days, then switch to the second state.
My question is time.Timer vs goroutine, which is more suit for this case?
Since you mention a time period of days, of the two given, you should probably go with the second option. This way you can store state to a file (or database) and restart the process if necessary. The first option makes storing the state more difficult, but still possible.

How to force GetQueuedCompletionStatus() to return immediately?

I have hand-made thread pool. Threads read from completion port and do some other stuff. One particular thread has to be ended. How to interrupt it's waiting if it hangs on GetQueuedCompletionStatus() or GetQueuedCompletionStatusEx()?
Finite timeout (100-1000 ms) and exiting variable are far from elegant, cause delays and left as last resort.
CancelIo(completionPortHandle) within APC in target thread causes ERROR_INVALID_HANDLE.
CancelSynchronousIo(completionPortHandle) causes ERROR_NOT_FOUND.
PostQueuedCompletionStatus() with termination packet doesn't allow to choose thread.
Rough TerminateThread() with mutex should work. (I haven't tested it.) But is it ideologically good?
I tried to wait on special event and completion port. WaitForMultipleObjects() returned immediately as if completion port was signalled. GetQueuedCompletionStatus() shows didn't return anything.
I read Overlapped I/O: How to wake a thread on a completion port event or a normal event? and googled a lot.
Probably, the problem itself – ending thread's work – is sign of bad design and all my threads should be equal and compounded into normal thread pool. In this case, PostQueuedCompletionStatus() approach should work. (Although I have doubts that this approach is beautiful and laconic especially if threads use GetQueuedCompletionStatusEx() to get multiple packets at once.)
If you just want to reduce the size of the thread pool it doesn't matter which thread exits.
However if for some reason you need to signal to an particular thread that it needs to exit, rather than allowing any thread to exit, you can use this method.
If you use GetQueuedCompletionStatusEx you can do an alertable wait, by passing TRUE for fAlertable. You can then use QueueUserAPC to queue an APC to the thread you want to quit.
https://msdn.microsoft.com/en-us/library/windows/desktop/ms684954(v=vs.85).aspx
If the thread is busy then you will still have to wait for the current work item to be completed.
Certainly don't call TerminateThread.
Unfortunately, I/O completion port handles are always in a signaled state and as such cannot really be used in WaitFor* functions.
GetQueuedCompletionStatus[Ex] is the only way to block on the completion port. With an empty queue, the function will return only if the thread becomes alerted. As mentioned by #Ben, the QueueUserAPC will make the the thread alerted and cause GetQueuedCompletionStatus to return.
However, QueueUserAPC allocates memory and thus can fail in low-memory conditions or when memory quotas are in effect. The same holds for PostQueuedCompletionStatus. As such, using any of these functions on an exit path is not a good idea.
Unfortunately, the only robust way seems to be calling the undocumented NtAlertThread exported by ntdll.dll.
extern "C" NTSTATUS __stdcall NtAlertThread(HANDLE hThread);
Link with ntdll.lib. This function will put the target thread into an alerted state without queuing anything.

Inter-process communication in C

I have a scenario, where one process should wait for a signal from another process, and this wait should be blocking wait, and as soon as it gets a signal, it should wake up.
However, with mechanisms like kill() or raise(), the first process goes to wait state, but periodically checks after a specified amount of time, whether the even/signal occurred or not, and decides to wait or go on.
My requirement is a bit stringent, I want that process should wake up at the same instant as signal is received.
Please suggest something.
This can be achieved using semaphore,mutex or conditional variable. Or You can write wait and signal function by your own and you can control the behavior of these as per need. For reference see here: IPC examples
IPC concept and Examples Mutex and Conditional Variables

Is it possible to advance a deadlocked thread? stuck at WaitForSingleObject

If I have an app that is creating threads which do their work and then exit, and one or more threads get themselves into a deadlock (possibly through no fault of my own!), is there a way of programmatically forcing one of the threads to advance past the WaitForSingleObject it might be stuck at, and thus resolving the deadlock?
I don't necessarily want to terminate the thread, I just want to have it move on (and thus allow the threads to exit "gracefully".
(yes, I know this sounds like a duplicate of my earlier question Delphi 2006 - What's the best way to gracefully kill a thread and still have the OnTerminate handler fire?, but the situation is slightly different - what I'm asking here is whether it is possible to make a WaitForSingleObject (Handle, INFINTE) behave like a WaitForSingleObject (Handle, ItCantPossiblyBeWorkingProperlyAfterThisLong)).
Please be gentle with me.
* MORE INFO *
The problem is not necessarily in code I have the source to. The actual situation is a serial COM port library (AsyncFree) that is thread based. When the port is USB-based, the library seems to have a deadlock between two of the threads it creates on closing the port. I've already discussed this at length in this forum. I did recode one of the WaitForSingleObject calls to not be infinite, and that cured that deadlock, but then another one appeared later in the thread shutdown sequence, this time in the Delphi TThread.Destroy routine.
So my rationale for this is simple: when my threads deadlock, I fix the code if I can. If I can't, or one appears that I don't know about, I just want the thread to finish. I doesn't have to be pretty. I can't afford to have my app choke.
You can make a handle used in WaitForSingleObject invalid by closing it (from some other thread). In this case WaitForSingleObject should return WAIT_FAILED and your thread will be 'moved on'
If you don't use INFINITE but just set a given timeout time, you can check if the call returned because the time out time expired or because the handle you were waiting for got into the signalled state. Then your code can decide what to do next. Enter another waiting cycle, or simply exit anyway maybe showing somewhere 'hey, I was waiting but it was too long and I terminated anyway).
Another options is to use WaitForMultipleObjects and use something alike an event to have the wait terminate if needed. The advantage it doesn't need the timeout to expire.
Of course one the thread is awaken it must be able to handle the "exceptional" condition of continuing even if the "main" handle it was waiting for didn't return in time.

Is sleep() a good idea for the main loop of a job-scheduling app

I'm writing a job-scheduling app in Ruby for my work (primarily to move files using various protocol at a given frequency)
My main loop looks like this :
while true do
# some code to launch the proper job
sleep CONFIG["interval"]
end
It's working like a charm, but I'm not really sure if it is safe enough as the application might run on a server with cpu-intensive software running.
Is there another way to do the same thing, or is sleep() safe enough in my case ?
Any time I feel the need to block, I use an event loop; usually libev. Here is a Ruby binding:
http://rev.rubyforge.org/rdoc/
Basically, sleep is perfectly fine if you want your process to go to sleep without having anything else going on in the background. If you ever want to do other things, though, like sleep and also wait for TCP connections or a filehandle to become readable, then you're going to have to use an event loop. So, why not just use one at the beginning?
The flow of your application will be:
main {
Timer->new( after => 0, every => 60 seconds, run => { <do your work> } )
loop();
}
When you want to do other stuff, you just create the watcher, and it happens for you. (The jobs that you are running can also create watchers.)
Using sleep is likely OK for quick and dirty things. But for things that need a bit more robustness or reliability I suggest that sleep is evil :) The problem with sleeping is that the thread is (I'm assuming Windows here...) is truly asleep - the scheduler will not run the thread until some time after sleep interval has passed.
During this time, the thread will not wake up for anything. This means it cannot be canceled, or wake up to process some kind of event. Of course, the process can be killed, but that doesn't give the sleeping thread an opportunity to wake up and clean anything up.
I'm not familiar with Ruby, but I assume it has some kind of facility for waiting on multiple things. If you can, I suggest that instead of using sleep, you waint on two things\
A timer that wakes the thread periodically to do its work.
An event that is set when he process needs to cancel or quite (trapping control-C for example).
It would be even better if there is some kind of event that can be used to signal the need to do work. This would avoid polling on a timer. This generally leads to lower resource utilization and a more responsive system.
If you don't need an exact interval, then it makes sense to me. If you need to be awoken at regular times without drift, you probably want to use some kind of external timer. But when you're asleep, you're not using CPU resources. It's the task switch that's expensive.
While sleep(timeout) is perfectly appropriate for some designs, there's one important caveat to bear in mind.
Ruby installs signal handlers with SA_RESTART (see here), meaning that your sleep (or equivalent select(nil, nil, nil, timeout)) cannot easily be interrupted. Your signal handler will fire, but the program will go right back to sleep. This may be inconvenient if you wished to react timely to, say, a SIGTERM.
Consider that ...
#! /usr/bin/ruby
Signal.trap("USR1") { puts "Hey, wake up!" }
Process.fork() { sleep 2 and Process.kill("USR1", Process.ppid) }
sleep 30
puts "Zzz. I enjoyed my nap."
... will take about 30 seconds to execute, rather than 2.
As a workaround, you might instead throw an exception in your signal handler, which would interrupt the sleep (or anything else!) above. You might also switch to a select-based loop and use a variant of the self-pipe trick to wake up "early" upon receipt of a signal. As others have pointed out, fully-featured event libraries are available, too.
It wont use CPU while it is sleeping but if you are sleeping for a long time I would be more concerned of the running ruby interpreter holding up memory while it wasn't doing anything. This is not that big of a deal tho.

Resources