I was thinking about it and I was curious as to how one would code an efficient repeating alarm clock in C? Would you set an alarm time and then offset the time with the ms time equivalent of a day (or two days or a week depending on how often it needed to repeat)? And then poll periodically to see if the times are equal? That sounds like a very inefficient solution, to me at least. I was am interested in how an alarm clock would work programatically.
Design – Efficient Repeating Alarm Clock in Low Level Language like C
cconceptsdesignefficiency
Related Solutions
In general, the lower level the language, the more rigorous you have to be about style. Many of the same style rules to any language are important. Keep functions short. Keep like methods together. Generalize repeated code. Also, lower level code demands more comments as the code is itself less readable.
In most cases, the methods you'd use to keep things organized are more verbose and more manual. Basically, in C, you get something like encapsulation by keeping related functions in a single source file and using static globals for any data they need to share. You can use this to simulate private data in a class. Or more correctly, this creates something like a "Module", which was the structured programming world's answer to large scale program development before OO came along.
In a similar manner, you can use the same handle method used by system libraries like fopen
to create something like a class. Internally you have a table that maps handles to the "instance data". Or you can also pass a raw pointer back and forth.
In general, try to be as "functional" as you can. Avoid globals and side effects and do as much communication as you can with parameter passing.
One big problem is that you have no help with memory management, so you need to be very rigorous about when you allocate and free memory. Allocated data that goes together should be tied together somehow so that it can all be freed in a single destroy
function. Try to have a general structure to when things are allocated and freed. Also, allocate on the stack whenever you possibly can. One big help is the new dynamic arrays in C99.
The other big problem is the complete lack of collection classes. Best way to solve this is to go looking for third party solutions. You don't want to spend all of your time debugging custom hash table implementations.
You can go all out and fully implement OO by doing by hand what C++ compilers do for you. Make classes by creating structs with function pointers for virtual methods. You can use the same hack C++ does to derive classes by having the "child" class have function pointers to the base class methods in the same order in memory. This is a bad idea for a real program, but can be an interesting learning exercise.
Microsoft has done some very interesting research in this direction, if you look into Singularity:
http://research.microsoft.com/en-us/projects/singularity/
Also, Mothy Roscoe et al have been working on Barrelfish which uses the Eclipse constraint programming language as an OS service to sort out all kinds of OS management and resource allocation problems:
Best Answer
There's numerous ways to acheive this, all depending on what kind of environment you're working with. Another concern is of course the latency you can afford.
If you are working on a modern operating system, you most likely have an API that will put your thread to sleep until the given time has arrived. Posix has
nanosleep()
and C11 has thethread_sleep()
function to do this.If you're on more primitive operating systems or programming directly for embedded hardware you may have to resort to waiting for periodic interrupts, or even using busy loops.
Update: To handle multiple alarms using the
thread_sleep()
approach, you could for instance store all coming alarms in a sorted list. Sleep until the first alarm triggers, do what you're supposed to and then calculate the time until the next alarm and go back to sleep. This approach uses only one timer thread, which will be very efficient as long as it satisfies your latency requirements.