Creating a Timer in C - c

How do I create a timer? A timer like the one in Visual Basic; you set an interval, if the timer is enabled it waits until the time is up.
I don't want to use an existing library because I want to know how it works.
So.. I just hope someone could explain me how timers work and maybe give me an example of code to create my own - if it's not too advanced.
Edit:
I wanna create one for a linux system.

The following is a very basic example which will run under Linux. If you look at the manual page of signal you will see it is deprecated in favor of sigaction. Important is not to forget the volatile, otherwise the while loop may not terminate depending on optimizations. Note also how SIGALRM is a highly shared resource which may be used by other timer facilities and there is only one.
The program will print Waiting for three seconds and than quit after printing Finally ... once.
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
volatile int mark = 0;
void trigger(int sig)
{
mark = 1;
}
int main(void)
{
signal(SIGALRM, trigger);
alarm(3);
while (!mark)
{
printf("Waiting\n");
}
printf("Finally ...\n");
return 0;
}

You can do that
#include <stdio.h>
#include <unistd.h>
int main() {
printf("wait\n");
sleep(3);
printf("time elapsed\n");
return 0;
}

Related

Ending terminal application on mac + cleanup process

I am trying to create a c program which has an infinite loop in the main method (multi-threaded application). We are using pthreads and POSIX shared memory between two applications. If I exit one of the programs using the command line (CTL+C), then I want to run a cleanup method to cleanup all allocated memory and removed the POSIX shared memory map.
int main () {
for (;;)
{
}
destroy_shared_object(shm, MEM_MAP_SIZE);
exit(EXIT_SUCCESS);
return 0;
}
Right now this is what I have above, however when I exit the program I don't think it removes the shared memory map and cleans up. Any help would be appreciated!
You may catch CTRL+C with a signal() handler and set a flag variable within the signal handler:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
static volatile sig_atomic_t running = 1;
void sighandler(int signum) {
running = 0;
}
int main() {
signal(SIGINT, sighandler);
while(running) {
sleep(1);
}
printf("Do the cleanup...\n");
return 0;
}
EDIT:
It's probably better to use sigaction() instead:
WARNING: the behavior of signal() varies across UNIX versions,
and has also varied historically across different versions of
Linux. Avoid its use: use sigaction(2) instead. See > Portability
below.

C linux signals and functions

I got this issue, which I will simplify below:
#include <stdio.h>
#include <signal.h>
int main(void) {
signal(SIGALRM, &INThandler);
//get menu options which Im not going to put here
game(...stuff...);
}
void game(..stuff...) {
//do the game stuff AND set an alarm()
}
void INThandler(int sig) {
system("clear");
printf("Time is up!\n");
//I WANT game() TO STOP WHICH WILL EXIT TO MAIN WHERE MORE STUFF IS HAPPENING
}
In game() I have
while(counter <= amount)
So I wanted to pass the variables counter and amount into INThandler so I could change them so the condition is false, however INThandler is only called when the alarm is at 0 and is not called with parameters. game() continues and I don't want it to. If there is a better way please tell me.
Use global variables for counter and amount ?
When a function is called and that function has variables in it, those variables are allocated on the stack. If you define a global variable, it will be instead be allocated as the program loads. Your signal handler should have access to those variables.
#include <stdio.h>
#include <signal.h>
#include <stdlib.h> //Also include this, needed for exit(returncode)
int counter; //Not inside any function
int amount; //All functions may access these
int main(void) {
signal(SIGALRM, &INThandler);
//get menu options which Im not going to put here
game(...stuff...);
}
void game(..stuff...) {
//do the game stuff AND set an alarm()
}
void INThandler(int sig) {
//Do stuff with counter and amount
//system("clear"); I recommend that you do not use system to clear the screen, system(command) is inefficient.
printf("\033[H\033[JTime is up!\n");
//Do that extra stuff you want to do in main here, then
exit(0);
}
Another note: according to signal(2) in the Linux programming manual:
The only portable use of signal() is to set a signal's disposition to
SIG_DFL or SIG_IGN. The semantics when using signal() to establish a
signal handler vary across systems (and POSIX.1 explicitly permits
this variation); do not use it for this purpose.
POSIX.1 solved the portability mess by specifying sigaction(2), which
provides explicit control of the semantics when a signal handler is
invoked; use that interface instead of signal().
To register a signal handler using sigaction,
#include <signal.h>
int main(){
const struct sigaction saSIGALRM = {
.sa_handler = mySignalHandler, //replace this with your signal handler, it takes the same parameters as using signal()
};
sigaction(SIGALRM, &saSIGALRM, 0);
}
It's simpler than it looks. Remember, computers are slow today because of inefficient programming. Please, please, please, for efficient programs, use this instead.
Click here for more cool things sigaction can do, along with why not to use signal()

How to wait for time to expire

I would like to have a function run periodically, given a time step. What is the most efficient way to do this?
I know I could use a while look and just keep checking till the dt period has elapsed. But I'd like to know if there is a better, more efficient/elegant function to use.
I was looking into virtual timers and sigaction. Using this method, I would have the sigaction handler set a flag when the time has elapsed, but I would still need to sit in a while loop checking for that flag to be set in my main function. Alternatively I wonder if I could actually have the handler run the function, but then I would have to pass a lot of arguments, and as far as I have read, handlers don't take arguments, so I would have to use lots of global variables.
What would be the best way to tackled this?
On an *IX'ish system you could
install a handler for SIGALRM, which does nothing
set an alarm using alarm()
call blocking pause()
If the alarm signal is sent pause() will return and
you can run the function in question,
again set the alarm
start over calling pause()
#define _POSIX_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
void handler_SIGALRM(int signo)
{
signo = 0; /* Get rid of warning "unused parameter ‘signo’" (in a portable way). */
/* Do nothing. */
}
int main()
{
/* Override SIGALRM's default handler, as the default handler might end the program. */
{
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = handler_SIGALRM;
if (-1 == sigaction(SIGALRM, &sa, NULL ))
{
perror("sigaction() failed");
exit(EXIT_FAILURE);
}
}
while (1)
{
alarm(2); /* Set alarm to occur in two seconds. */
pause(); /* The call blocks until a signal is received; in theis case typically SIGARLM. */
/* Do what is to be done every 2 seconds. */
}
return EXIT_SUCCESS;
}
The easiest way is to use sleep or usleep as defined in unistd.h.
If neither of those are available then a common workaround is to use a select with a timeout on no file descriptors.
Include time.h and use sleep function like
#include <time.h>
#include <stdio.h>
#include<windows.h>
#include <conio.h>
int main() {
printf("I am going to wait for 4 sec");
Sleep(4000); //sleep for 4000 microsecond= 4 second
printf("Finaaly the wait is over");
getch();
return 0;
}
It will give you a precise delay on microsecond level.
Hope it helped.

CLONE_VM flag makes itimer inaccurate?

Recently I come across a problem about sharing memory with multiprocess. Consider the code below, the main purpose is to let child process alarmed by the itimer's signal handler, do some output. But what confuses me is that when I set the CLONE_VM flag in clone() function, the itimer may go wrong, and the output text will stuff your console.
What I expect is : print "---Alarm!\n---ChildThread is awaked.\n---foo=10" every second.
The actual situation is : repeat printing the text above very fast.
I'd like to know how to spawn a child PROCESS and let it share its parent's memory in the meanwhile. Thanks a lot.
#define _GNU_SOURCE
#include <stdio.h>
#include <signal.h>
#include <sched.h>
#include <stdlib.h>
#include <linux/sched.h>
#include <sys/time.h>
static volatile int foo = 100;
int pidChild;
void AlarmThread(int sig)
{
printf("---Alarm!\n");
kill(pidChild, SIGCONT);
}
int ChildThread(void *arg)
{
raise(SIGSTOP);
while(1)
{
printf("---ChildThread is awaked.\n");
printf("---foo=%d\n", foo); // If CLONE_VM is set, this variable may be changed by main thread.
raise(SIGSTOP);
}
return 0;
}
int main(int argc, char **argv)
{
void *stack = malloc(4000) + 4000;
struct itimerval itimer;
signal(SIGALRM, AlarmThread);
pidChild = clone(ChildThread, stack, CLONE_VM | CLONE_SIGHAND, NULL);
itimer.it_interval.tv_sec = 1;
itimer.it_interval.tv_usec = 0;
itimer.it_value = itimer.it_interval;
setitimer(ITIMER_REAL, &itimer, NULL); // Set up a 1 tick-per-sec timer.
foo = 10; // Test if the child thread shares the main thread's memory.
while(1);
return 0;
}
I would really caution you against doing this. Sharing memory does not mean only application memory, but also library memory (the standard library and any third-party libraries you may use), and they may not be prepared for having other processes clobber their internal data structures, especially when they believe themselves to be running single-threaded.
If you just want a process in order to have a killable PID for a thread as part of the publicly visible interface of your application, why not make the actual code run in a thread, and spawn a useless child process that does nothing but for(;;)pause();? Then, have the thread respond to the death of this child process by exiting.
But what confuses me is that when I set the CLONE_VM flag in clone()
function, the itimer may go wrong, and the output text will stuff your
console.
What does "may go wrong" mean? What happened? What did you expect? You need to be clear when asking questions.
CLONE_VM has almost nothing to do with itimer. The fact that you are using advanced syscalls like this without even being able to formulate what you are trying to do and why leads me to believe this is a school assignment.

How to call function with infinite-loop?

I need help to clear my concepts.
I have a function which toggle the Led status on/off after every second. Now the code for the on/off runs inside infite loop.
Example:
void ToggleLed( int pin_number)
{
// some code
while(1)
{
// code to execute the Led status
}
}
Now when I integrate this code with base line and called that function inside other function it just doesnt work no other functionality of software works.
Question: Function has infinite-loop and that it doesn't come out of control and other functions called after that function doesn't work.
If that is the case do I need to provide separate thread to it?
Any suggestion will be helpful.
Yes you will need a separate thread, or some other form of asynchronous execution. Once you enter that while loop, no other code runs in that thread. Ever.
If I understand correcctly nothing works in your integrated version. In that case, yes you probably need to run the infinite loop on a separate thread, because your function with the infinit loop will never exit, so no other code will ever run on that thread.
You don't say what OS, but yes, set it as a low-priority thread, minimal stack size. I flash a LED in my projects, just so I can easily see if the code has reached the abort-handler yet :)
void LEDflash_task_code(void *p)
{
while (1)
{
FIO1CLR=STATUS_LED;
OSsleep(750);
FIO1SET=STATUS_LED;
OSsleep(250);
};
};
If you have access to hardware peripheral timers (any micrcontroller/microprocessor application), you should use those hardware timers, not threads nor software sleep().
void init_toggle_led (uint32_t interval)
{
setup_hardware_timer(interval);
}
void toggle_led (void)
{
if( (hardware_timer_register & flag) > 0 )
{
port = port ^ pin_mask;
}
}
main()
{
init_toggle_led(1000);
for(;;)
{
do_stuff();
toggle_led();
}
}
This was an example with polling. Alternatively, you can use hardware interrupts from the timers and toggle the port from there.
As David mentioned, you should run your LED code in a separate thread. http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html#BASICS
Once you have threads, if you want your code to be able to stop your LED from blinking, then add a flag that's checked inside the while loop at each iteration, and if it's set then break out.
#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
void * toggle_led(void *ptr);
int stop=0;
int main (int argc, const char * argv[])
{
printf("Hello, World!\n");
// set up thread
pthread_t LED_thread;
char * message = "blink!";
pthread_create( &LED_thread, NULL, toggle_led, (void*) message);
// do some other work
sleep(5);
// ok you want to quit now
stop=1;
pthread_join(LED_thread, NULL);
printf("Goodbye!\n");
return 0;
}
void *toggle_led(void *ptr)
{
while (!stop)
{
printf("%s \n", (char *)ptr);
sleep(1);
}
}
I think you need to implement as a watchdog functionality. Because if you use threads then even if other threads has some issues(like deadlock), your LEDs will toggle as long as toggle_led thread works. You need to implement an toggle_led() function and call from each of other threads /functions before returning to make sure all other threads/functions are getting executed successfully without waiting continuously for some resources

Resources