Why is C nanosleep() not sleeping here? - c

Im trying to write to the terminal one line at a time but it just prints the whole thing without sleeping. It works if I use sleep(1). Am I just not understanding how nanosleep is suppose to work?
void
display_all(int fdin, int fdout)
{
struct timespec tm1,tm2;
tm1.tv_sec = 0;
tm1.tv_nsec = 1000000000L;
while (display_line(fdin, fdout) == 80)
{
nanosleep(&tm1,&tm2);
}
}
display_line is using the function write to write to STDOUT.

From the nanosleep man page:
The value of the nanoseconds field must be in the range 0 to 999999999

#include <stdio.h>
#include <time.h>
#define MILISECONDS 300
#define NLOOPS 10
void nsleep(long miliseconds) {
struct timespec ts = {0, miliseconds * 1000000L};
nanosleep(&ts, NULL);
}
int main() {
short i;
for (i = 0; i < NLOOPS; i++)
fflush(stdout),
nsleep((long) MILISECONDS),
printf("%d miliseconds\n", MILISECONDS);
return 0;
}
Or:
void nsleep(long miliseconds) {
struct timespec ts;
ts.tv_sec = 0;
ts.tv_nsec = miliseconds * 1000000L;
nanosleep(&ts, NULL);
}

Related

How to implement 2 timers in linux

I m trying to set the flag variable on(working with raspbery pi. I need pin on) for 500 useconds(micro seconds) and flag off for 300 useconds continuously(infinitely until I stop it). I thought of implementing it using 2 timers.
Now In this program i have written for 5 seconds and 3 seconds.
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
struct sigaction sa;
struct itimerval timer1,timer2;
int count=1;
void timer_handler (int signum)
{
if(count++%2==1)
printf("High\n"); //flag=1
else
printf("Low\n"); //flag=0
}
int main ()
{
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sa.sa_flags = SA_RESTART;
sigaction (SIGALRM, &sa, NULL);
int i=0;
while(1){
scanf(" %d",&i);
if(i==1){ // I m starting 2 timers here
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 1;
timer1.it_interval.tv_sec = 8; //5+3
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 5;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 8;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL);
setitimer (ITIMER_REAL, &timer2, NULL);
}
else if(i==2) // I m stopping here
{
timer1.it_value.tv_sec = 0;
timer1.it_value.tv_usec = 0;
timer1.it_interval.tv_sec = 0;
timer1.it_interval.tv_usec = 0;
timer2.it_value.tv_sec = 0;
timer2.it_value.tv_usec = 0;
timer2.it_interval.tv_sec = 0;
timer2.it_interval.tv_usec = 0;
setitimer (ITIMER_REAL, &timer1, NULL); // 1st timer on
setitimer (ITIMER_REAL, &timer2, NULL); //2nd timer on
}
}
}
This is code I have written.
what actually happening is the second timer is running and first timer is not running. I think its overwritten.
Ps. I dont want to use sleep function as it takes more time. I m using timers as the resolution is microsecond.
1.How do I do this using two timers?
2.Is there any better method to do this task?
There is only one ITIMER_REAL, so you must create virtual timers yourself. A simple and reliable possibility if you don't need microsecond precision, is to use a periodic timer with a small interval and implement your virtual timers on top of that (so every "tick" from your periodic timer will decrement your virtual timers).
Following an example how you could implement it:
vtimer.h
#ifndef VTIMER_H
#define VTIMER_H
typedef void (vtimer_timeout)(void *arg);
typedef struct vtimer
{
int msec;
int periodic;
int current;
vtimer_timeout *timeout;
} vtimer;
#define vtimer_init(m, p, cb) { \
.msec=(m), .periodic=(p), .current=0, .timeout=cb}
void vtimer_start(vtimer *self, void *timeoutArg);
void vtimer_stop(vtimer *self);
// call this periodically, e.g. after each interrupted library call:
void vtimer_dispatch();
#endif
vtimer.c
#define _POSIX_C_SOURCE 200101L
#include "vtimer.h"
#include <stddef.h>
#include <signal.h>
#include <sys/time.h>
#define NUM_TIMERS 8
static vtimer *timers[NUM_TIMERS] = {0};
static void *timoutArgs[NUM_TIMERS] = {0};
static size_t ntimers = 0;
static volatile sig_atomic_t ticks = 0;
static void tickhandler(int signum)
{
(void)signum;
++ticks;
}
static struct sigaction timerAction = {.sa_handler = tickhandler};
static struct sigaction defaultAction;
static struct itimerval tickTimerval = {{0, 1000}, {0, 1000}};
static struct itimerval disableTimerval = {{0,0},{0,0}};
void vtimer_start(vtimer *self, void *timeoutArg)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
found = 1;
break;
}
}
if (!found)
{
if (ntimers == NUM_TIMERS) return; // or maybe return error
if (!ntimers++)
{
// only start the "ticking" timer when necessary
sigaction(SIGALRM, &timerAction, &defaultAction);
setitimer(ITIMER_REAL, &tickTimerval, 0);
}
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (!timers[idx])
{
timers[idx] = self;
timoutArgs[idx] = timeoutArg;
break;
}
}
}
self->current = self->msec;
}
void vtimer_stop(vtimer *self)
{
int found = 0;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx] == self)
{
timers[idx] = 0;
found = 1;
break;
}
}
if (found && !--ntimers)
{
// no virtual timers running -> stop ticking timer
setitimer(ITIMER_REAL, &disableTimerval, 0);
sigaction(SIGALRM, &defaultAction, 0);
}
}
void vtimer_dispatch(void)
{
while (ticks)
{
--ticks;
for (size_t idx = 0; idx < NUM_TIMERS; ++idx)
{
if (timers[idx])
{
if (!--(timers[idx]->current))
{
timers[idx]->timeout(timoutArgs[idx]);
if (timers[idx]->periodic)
{
timers[idx]->current = timers[idx]->msec;
}
else vtimer_stop(timers[idx]);
}
}
}
}
}
Example program using this:
#include "vtimer.h"
#include <stdio.h>
#include <errno.h>
static void timer1_timeout(void *arg)
{
(void) arg;
puts("timer 1");
}
static void timer2_timeout(void *arg)
{
(void) arg;
puts("timer 2");
}
int main(void)
{
vtimer timer1 = vtimer_init(5000, 1, timer1_timeout);
vtimer timer2 = vtimer_init(8000, 1, timer2_timeout);
vtimer_start(&timer1, 0);
vtimer_start(&timer2, 0);
for (;;)
{
errno = 0;
int c = getchar();
if (c == EOF && errno != EINTR) break;
if (c == 'q') break;
vtimer_dispatch();
}
vtimer_stop(&timer2);
vtimer_stop(&timer1);
return 0;
}
There are a lot of design decisions on the way (e.g. how frequent your ticks should be (here 1ms), having a fixed number of virtual timers vs a dynamic one, using pointers as "timer handles" or maybe integers, and so on), so think about what you need and try to write your own.

why does my debouncer not work?

I'm trying to write a debouncer that will only return a valid argument (>0) if it has been debounced (-1 four bouncing).
I've come up with this so far but it always returns -1, why is that I'm wondering:
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#define BOUNCETIME 500000000 //(500ms)
#define SetTime(x) clock_gettime(CLOCK_REALTIME, (x)); // set time
static struct timespec tset;
struct timespec tnow;
int DeBounce(unsigned int arg)
{
static int val = -1;
long long nsec = 0;
if (val < 0) {
val = arg;
SetTime(&tset);
return arg;
} else {
SetTime(&tnow);
if (tnow.tv_nsec < tset.tv_nsec)
nsec = tnow.tv_nsec + 1000000000;
else
nsec = tnow.tv_nsec;
if (tnow.tv_nsec - tset.tv_nsec > BOUNCETIME) {
printf("arg okay\n");
val = -1;
return arg;
}
else
printf("bounce, ignore!\n");
return -1;
}
}
int main (void)
{
printf("#1 %d\n",DeBounce(0));
usleep(1);
printf("#2 %d\n",DeBounce(1));
usleep(200);
printf("#3 %d\n",DeBounce(1));
sleep(1);
printf("#4 %d\n",DeBounce(1));
}
the ouput I get is:
$ ./debounce
#1 0
bounce, ignore!
#2 -1
bounce, ignore!
#3 -1
bounce, ignore!
#4 -1
$
usleep(600); is 600 microseconds. But your debounce period is 500 milliseconds.
Furthermore tnow.tv_nsec - tset.tv_nsec is not correct as tv_nsec is not the full time value but only the number of nanoseconds past the second. The correct way to calculate elapsed time in nanoseconds is something like this:
(tnow.tv_sec * 1.0e-9 + tnow.tv_nsec) - (tset.tv_sec * 1.0e-9 + tset.tv_nsec)

libevent: make timer persistent

I have the following code:
#include <stdio.h>
#include <sys/time.h>
#include <event.h>
void say_hello(int fd, short event, void *arg){
printf("Hello\n");
}
int main(int argc, const char* argv[])
{
struct event ev;
struct timeval tv;
tv.tv_sec = 3;
tv.tv_usec = 0;
event_init();
evtimer_set(&ev,say_hello,NULL);
evtimer_add(&ev, &tv);
event_dispatch();
return 0;
}
Problem is "hello" gets printed once and then the program exits...
I want it to output "hello" indefinitely.
How to do this? Many thanks in advance,
Just to clarify Basile's solution:
I was confused as well until I realized that "timer" in this context refers to a single shot timer. What we need is an interval timer; which requires the EV_PERSIST flag in libevent.
struct timeval time;
time.tv_sec = 1;
time.tv_usec = 0;
event_set(&my_event, 0, EV_PERSIST, my_function, NULL);
evtimer_add(&my_event, &time);
change the code in main to read
evtimer_set(&ev,say_hello,&ev);
and make your say_hello function
void say_hello(int fd, short event, void *arg){
struct event *ev = arg;
struct timeval tv;
printf("Hello\n");
tv.tv_sec = 3;
tv.tv_usec = 0;
evtimer_add(ev, &tv);
}
Here is the example for libevent2:
#include <event2/event.h>
static int n_calls = 0;
void cb_func(evutil_socket_t fd, short what, void *arg)
{
struct event *me = arg;
printf("cb_func called %d times so far.\n", ++n_calls);
if (n_calls > 100)
event_del(me);
}
void run(struct event_base *base)
{
struct timeval one_sec = { 1, 0 };
struct event *ev;
/* We're going to set up a repeating timer to get called called 100
times. */
ev = event_new(base, -1, EV_PERSIST, cb_func, event_self_cbarg());
event_add(ev, &one_sec);
event_base_dispatch(base);
}
Did you read evtimer_set(3) man page? Please read it again.
You probably want to use the flag EV_PERSIST or call evtimer_add from your say_hello callback.
#include <stdio.h>
#include "ev.h"
static void timer_cback_caller(EV_P_ ev_timer* w, int revents)
{
const int new_timeout_in_ms = 1200; // new delay between timer ticks
printf("timer tick\n");
w->repeat = new_timeout_in_ms / 1000.;
ev_timer_again(EV_A_ w);
}
int main()
{
struct ev_loop *loop = ev_default_loop(0);
ev_timer timer;
const int start_delay_in_ms = 1000; // delay before first timer tick
const int timeout_in_ms = 1500; // delay between every timer tick
ev_timer_init(&timer, timer_cback_caller, start_delay_in_ms/1000., timeout_in_ms/1000.);
ev_timer_start(loop, &timer);
ev_run(loop, 0); // will never return
return 0;
}
More examples in libev documentation

How to use nanosleep() in C? What are `tim.tv_sec` and `tim.tv_nsec`?

What is the use of tim.tv_sec and tim.tv_nsec in the following?
How can I sleep execution for 500000 microseconds?
#include <stdio.h>
#include <time.h>
int main()
{
struct timespec tim, tim2;
tim.tv_sec = 1;
tim.tv_nsec = 500;
if(nanosleep(&tim , &tim2) < 0 )
{
printf("Nano sleep system call failed \n");
return -1;
}
printf("Nano sleep successfull \n");
return 0;
}
Half a second is 500,000,000 nanoseconds, so your code should read:
tim.tv_sec = 0;
tim.tv_nsec = 500000000L;
As things stand, you code is sleeping for 1.0000005s (1s + 500ns).
tv_nsec is the sleep time in nanoseconds. 500000us = 500000000ns, so you want:
nanosleep((const struct timespec[]){{0, 500000000L}}, NULL);
500000 microseconds are 500000000 nanoseconds. You only wait for 500 ns = 0.5 µs.
This worked for me ....
#include <stdio.h>
#include <time.h> /* Needed for struct timespec */
int mssleep(long miliseconds)
{
struct timespec rem;
struct timespec req= {
(int)(miliseconds / 1000), /* secs (Must be Non-Negative) */
(miliseconds % 1000) * 1000000 /* nano (Must be in range of 0 to 999999999) */
};
return nanosleep(&req , &rem);
}
int main()
{
int ret = mssleep(2500);
printf("sleep result %d\n",ret);
return 0;
}
I usually use some #define and constants to make the calculation easy:
#define NANO_SECOND_MULTIPLIER 1000000 // 1 millisecond = 1,000,000 Nanoseconds
const long INTERVAL_MS = 500 * NANO_SECOND_MULTIPLIER;
Hence my code would look like this:
timespec sleepValue = {0};
sleepValue.tv_nsec = INTERVAL_MS;
nanosleep(&sleepValue, NULL);
More correct variant:
{
struct timespec delta = {5 /*secs*/, 135 /*nanosecs*/};
while (nanosleep(&delta, &delta));
}
POSIX 7
First find the function: http://pubs.opengroup.org/onlinepubs/9699919799/functions/nanosleep.html
That contains a link to a time.h, which as a header should be where structs are defined:
The header shall declare the timespec structure, which shall > include at least the following members:
time_t tv_sec Seconds.
long tv_nsec Nanoseconds.
man 2 nanosleep
Pseudo-official glibc docs which you should always check for syscalls:
struct timespec {
time_t tv_sec; /* seconds */
long tv_nsec; /* nanoseconds */
};

Need help applying timer in C in Linux

I want to create a timer in our C program so that it can print the variable after every 1 second.
Can anybody help me in doing this?
Don't use busy waiting, because you've got 100% CPU utilization.
You must use system function which turns process into sleeping mode for example select():
#include <stdio.h>
#include <sys/select.h>
void your_callback()
{
printf("%s\n", __FUNCTION__);
}
int main()
{
struct timeval t;
while (1) {
t.tv_sec = 1;
t.tv_usec = 0;
select(0, NULL, NULL, NULL, &t);
your_callback();
}
return 0;
}
If all you are interested in doing is printing the value of a variable at a one second interval, using time(2) or clock(3) as suggested in the other answers might suffice. In general, I would not recommend these busy-waiting techniques.
If your program is more complex, I suggest you investigate using the alarm(2) or settimer(2) function to asynchronously deliver a signal to your application at a one second interval.
The following example uses select(2) to block indefinitely in order to minimize CPU usage associated with busy-waiting techniques. The blocking select() call is interrupted and returns when a signal is caught. In the case of the SIGALRM signal, the print_variable flag is set and the value of variable is printed.
Example 1: using alarm()
#include <signal.h>
#include <stdio.h>
#include <sys/select.h>
#include <unistd.h>
volatile unsigned int variable = 0;
volatile unsigned int print_variable = 0;
void alarm_handler(int signum)
{
variable++;
print_variable = 1;
alarm(1);
}
int main()
{
signal(SIGALRM, alarm_handler);
alarm(1);
for (;;)
{
select(0, NULL, NULL, NULL, NULL);
if (print_variable)
{
printf("Variable = %u\n", variable);
}
}
}
Note: Error checking was omitted from the above code for simplicity.
A printf() function could have been called inside the SIGALRM handler, but calling non-reentrant functions in a signal handler is generally discouraged.
A timeout of one second can also be passed to select(), but if it were interrupted by any signal, additional logic is necessary to ensure that the remainder of the one second timeout is honored. Fortunately on Linux, select() modifies the timeout value to reflect the amount of time not slept. This allows interruption cases to be detected followed by subsequent call(s) select() to complete the timeout.
Example 2: using select()
#include <errno.h>
#include <stdio.h>
#include <sys/select.h>
volatile unsigned int variable = 0;
int main()
{
struct timeval tv;
int val;
for (;;)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
do
{
val = select(0, NULL, NULL, NULL, &tv);
} while (val != 0 && errno == EINTR);
printf("Variable = %u\n", ++variable);
}
}
If you want only second precision. Use time(0) which returns current time if time.h is included.
update:
Adding simple example which prints 10 in every second during 20 seconds:
#include <time.h>
#include <stdio.h>
int main()
{
int a = 10;
int num = 20;
int c = time(0);
while(n--)
{
printf("%d\n", a);
while(!(time(0) - c));
c = time(0);
}
return 0;
}
use time(0) see this example
/* timer.c */
#include <stdio.h>
#include <time.h>
void delay_sec( int seconds ){
clock_t endwait;
endwait = clock () + seconds * CLOCKS_PER_SEC;
while (clock() < endwait) {}
}
int main (void){
time_t rawtime, ini_time, now;
struct tm *ptm;
time ( &ini_time );
for(;;){
time ( &rawtime );
//ptm = gmtime ( &rawtime );
//printf ("%2d:%02d:%02d\n", ptm_2->tm_hour, ptm_2->tm_min, ptm_2->tm_sec);
now = rawtime - ini_time;
ptm = gmtime ( &now );
printf ("%2d:%02d:%02d\n", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
delay_sec(1);
}
return 0;
}
I believe you know 1000 Milliseconds equals to 1 Second.
#include <stdio.h>
#include <time.h>
#define mydelay 1000
void delay(int mseconds)
{
clock_t wait = mseconds + clock();
while (wait > clock());
}
int main()
{
int i=100;
while(1)
{
printf("%d\n",i);
delay(mydelay);
}
return 0;
}
A simple example which prints the value of the variable a for every 1 sec:
#include<stdio.h>
void main(void)
{
int a = 10;
while(a--)
{
printf("Value of a = %d\n", a);
sleep(1);
}
}
Output:
Value of a = 9
...
value of a = 0

Resources