0

I am using eclipse IDE on ubuntu to compile my c project. I have a timer. After starting the timer, sleep or usleep functions are not working. Here is the code;

EDIT

/*
 ============================================================================
 Name        : TimerTest.c
 Author      : FK
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>         /* , getenv() */
#include <getopt.h>
#include <unistd.h>         /* exec(), daemon() */
#include <stdint.h>
#include <string.h>         /* memset(), strerror() */
#include <errno.h>          /* errno */
#include <libgen.h>         /* basename() */
#include <signal.h>
#include <sys/timex.h>      /* ntp_gettime() */
#include <time.h>

#include "timer/timer.h"

#define CONFIG_TIMER_INTERVAL   100 /* in ms */
/* global vars decalarations */

static uint8_t _terminate = 0;
static int _signo = 0;

static int init_prg(int argc, char *argv[]);
static void timer_callback(void);

/* function implementations */
static void sig_handler(int signo)
{
    /* http://www.yolinux.com/TUTORIALS/C++Signals.html */
    _signo = signo;
    switch (signo)
    {
        case SIGINT: /* Program interrupt. (ctrl-c) */

            _terminate = 1;
            break;
        case SIGTERM:

            _terminate = 1;
            break;
            /* SIGKILL, SIGSTOP yakalanımıyor! */
        default:

            break;
    }

}

int main(int argc, char *argv[])
{
    init_prg(argc, argv);
    /* start super loop */
    while (1)
    {
        printf("test!\n");
        //usleep(1000000);
        sleep(1);

    }
}

static int init_prg(int argc, char *argv[])
{
    int res = -1;

    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        //exit(EXIT_FAILURE);
    }

    /* Termination, Generated by "kill" command. */
    if (signal(SIGTERM, sig_handler) == SIG_ERR)
    {
        //exit(EXIT_FAILURE);
    }



    start_timer(2000, &timer_callback);

    if (res != 0)
    {
        //exit(EXIT_FAILURE);
    }

    return res;
}

static void timer_callback(void)
{
    printf("timer works!\n");
}

after execute program, it echoes "test!" rapidly. Ignoring sleep or usleep commands. if I comment out start_timer line, it sleeps, after timer it is not.Any ideas?

Furkan KESKIN
  • 168
  • 3
  • 16
  • 3
    Please post complete code example. It is not clear now how this code is supposed to behave. – pbn Aug 14 '18 at 12:27
  • It is difficult to diagnose unless we see what `start_timer()` is doing. I suspect you are triggering a `SIGALRM` signal. Timers created with `setitimer(ITIMER_REAL, ...)` will generate such a signal on expiry. This would be sufficient to wake the thread / program from `sleep()`ing. – David Collins Aug 14 '18 at 13:00

2 Answers2

2

You're not showing what standardized intefaces you're using to start the timer.

Regardless, POSIX specifies that the interaction of usleep with

nanosleep()
setitimer()
timer_create()
timer_delete()
timer_getoverrun()
timer_gettime()
timer_settime()
ualarm()
sleep()

is unspecified.

nanosleep should not have that problem.

From nanosleep's manpage:

Compared to sleep(3) and usleep(3), nanosleep() has the following advantages: it provides a higher resolution for specifying the sleep interval; POSIX.1 explicitly specifies that it does not interact with signals; and it makes the task of resuming a sleep that has been interrupted by a signal handler easier.

The above suggests that replacing your usleep with:

#include <unistd.h>
int my_usleep(useconds_t Usec);

#include <time.h>
int my_usleep(useconds_t Usec)
{
    return nanosleep(&(const struct timespec){ 
      .tv_sec = Usec/100000, .tv_nsec=1000*Usec%1000000}, NULL);
}

should fix the problem.

Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • thank you for reply. I was trying some tests over my code and I realize something. If timer interval value is greater than the sleep value of superloop's, It is working. If the timer come in before, it supresses sleep or usleep comands. In other saying, it cancels sleep. I will update the code above. – Furkan KESKIN Aug 14 '18 at 13:15
2

It seems you are using a timer library similar to the one available at https://www.teuniz.net/Timer_code/ . If you open timer.c in that library, you will see that it uses setitimer(ITIMER_REAL, ...). A timer created in this way will generate a SIGALRM whenever the timer expires. This, in turn, will wake your program from sleep()ing.

Why? Because, if you read the POSIX specification for sleep() (available at http://pubs.opengroup.org/onlinepubs/009695399/ -> Alphabetical index -> sleep()), you will read.

The sleep() function shall cause the calling thread to be suspended from execution until either the number of realtime seconds specified by the argument seconds has elapsed or a signal is delivered to the calling thread and its action is to invoke a signal-catching function or to terminate the process.

If, on the other hand, you are not using the afore-mentioned library, then you need to show exactly what your start_timer() function is doing. Otherwise, anyone who tries to help you is shooting in the dark.

Solution: threads

I think your only option is to use separate threads - one thread for the task that sleeps and another for the task that handles the timer.

David Collins
  • 2,852
  • 9
  • 13