Schol-R-LEA wrote:
Just to clarify, could you provide a use case for how you want it to work?
Since you mentioned that the timer is asynchronous, my impression is that you intend to use it for event-driven code, in which a thread would set a timer, continue working on some task, then when the timer notification comes in it would interrupt the processing to service the timer event. Is this correct, or am I misconstruing the goal?
If this is the use case you have in mind, then the general solution is to have an event loop polling an event queue, either in a single thread which captures all of the events and handles them directly, or in a master thread which then dispatches various waiting threads to service the events.
Most libraries/languages which support event-driven programming (e.g., MFC, .Net, the various Java frameworks, etc.) hide this loop behind callbacks, but it is present.
No, that's not how I want it to work. This can easily be implemented without real timers. The only thing that is required is to have some form of timestamp function.
Schol-R-LEA wrote:
Either way, it may not have the timing resolution you want, since it involves polling the event queue, and relies on the thread to pause periodically to handle the event loop. You could special-case timers to put them at the front of the event queue, but that still depends on how long the processing loop is.
I don't want polling, and ideally, the solution should minimize syscalls too.
Schol-R-LEA wrote:
This would work, I think, but you would still have the problem of notifying the working thread that the timer it is waiting for has expired.
Not necessarily. It could also modify some shared variable or trigger a multiwait wakeup. In the file system case, a thread would write to a file, start a timer, write some more, retrigger the timer and so on until the timer expires and scans the memory mapped file for modified pages and writes them to disc. The same can be used with sockets, where timeouts typically cause things to be sent (I typically use a push method, but this is not part of the typical socket API). It's mostly this function I want. The problem is that it needs to be retriggered frequently without issuing syscalls more than sporadically.
Schol-R-LEA wrote:
It would help with the timing resolution, perhaps, but this would still require the operating thread to have an event loop with a very short operation time.
It's more a problem of being able to read the current timestamp without syscalls. This is because when you start a timer and you want it to expire in x ms, you will need the current timestamp and then you add the expire time to this and set the new expire timestamp for the timer. If the timestamp can be acquired without syscalls, then retriggering the timer will not require syscalls. The timer thread will wait for the earliest expire timestamp, and when it comes back it will read the expire timestamp again, and if it hasn't occurred yet, it will do another wait. The only case when the timer thread will need to be triggered directly is when a new earlier expire timestamp is added.
There is probably also a need for synchronizing the timers, but the futex-based "sections" I have will only do syscalls when there is contention, which should be the exceptional case.
So, the main problem is to create a millisecond timestamp that can be read from user mode. There is a kernel timestamp that the kernel timers update. The preemption timer for threads is one millisecond, and so the kernel timestamp should have at least one millisecond resolution even when only read. I think it should be possible to create a 4k page, map this in all user mode address spaces, and then write a copy of the kernel timestamp there every time it is updated.