C timers and threads again - c

Can someone help me to complete my code with a function that can check the result of a timer "check_timer" and another one that reset this timer if it had expired "reset_timer"?
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <sys/time.h>
#define GLOBAL_TIMER 8 * 60 * 60
typedef struct protocol_type {
int protocol_number;
char *protocol_name;
pthread_t thread_timer_id;
} protocol_type_t;
pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
/* call back function - inform the user the time has expired */
void timeout_call_back(pthread_t thread_id)
{
printf("Welcome thread %ld, your time is up ===\n", pthread_self());
// doing some other stuff
}
/* Go to sleep for a period of seconds */
static void* start_timer(void *args)
{
/* function pointer */
void (*finish_function)(pthread_t);
int seconds = *((int*) args);
finish_function = timeout_call_back;
struct timeval now;
struct timespec timeout;
pthread_mutex_lock(&mut);
printf("thread ID : %ld, are waiting for %d seconds to to expire\n", pthread_self(), seconds);
gettimeofday(&now, NULL);
timeout.tv_sec = now.tv_sec + seconds;
timeout.tv_nsec = now.tv_usec * 1000;
pthread_cond_timedwait(&cond, &mut, &timeout);
(*finish_function)(pthread_self());
pthread_mutex_unlock(&mut);
pthread_exit(NULL);
}
// This function is in MT environnement and is running inside a daemon
int received_buffer_parser(char *received_buffer) {
pthread_mutex_t mut_main = PTHREAD_MUTEX_INITIALIZER;
protocol_type_t *my_protocol;
// Identify protocol type
my_protocol = protocol_identifier(received_buffer);
// Check if i received it in the last 8 hours in safe
pthread_mutex_lock(&mut_main);
if (check_timer(my_protocol->thread_id) has expired) { // I want to write this function
// I want to reset thread timer
launch_new_timer(my_protocol->thread_id)
}
else {
// doing some stuff
// dump data to the disk
}
pthread_mutex_unlock(&mut_main);
return 0;
}
int launch_new_timer(pthread_t thread_id)
{
int rc;
int seconds = GLOBAL_TIMER;
rc = pthread_create(&thread_id, NULL, start_timer, (void *) &seconds);
if(rc)
printf("Failed to create thread1\n");
pthread_join(thread_id, NULL);
return 0;
}
Clarification
I clarify here the real context of my code:
I receive from the network some types of different protocols packets(ICMP, SSH, RIP, OSPF, BGP...), and i want to:
identify every type of packets, let say with : identify_protocol(char *received_buffer), I got this function, it's ok.
Check if i receive this type of protocols in the last 8 hours (THE TIMER OF EACH PROTOCOL TYPE EXPIRE AFTER 8 HOURS), two choices:
a. if so, I dump the result data into a specific file on the disk.
b. no, I didn't receive this type in the last 8 HOURS i create a new thread (in my code i simplify, with thread1, thread2 and thread3, this threads are 3 threads used to be a timers for three protocols types) - i start a new timer with : start_timer(void *args) function do this job.
My main question is how to be able to check the result of my timers in a safe manner and then decide i reset the timer or not.
I design the finish_function at the beginning to help me to check when the timer has expired.
Feel free to give me a better design for best performances for my program.
My system is Linux.

To check for timers that merely expire, you don't need to use threads and synchronization at all. Simply keep global variables indicating the start time of the timer. So
when the timer starts, set a global variable (one per protocol) to gettimeofday()
when you want to check whether the timer has expired for a protocol, see whether gettimeofday()-starttime(protocol) is <8h
If you want to be notified on timer expiry, I recommend to use alarm(2). It only has second resolution, but that should be good enough for 8h timeouts. Whenever a timer is set, cancelled, or reset, compute the minimum timeout of any of the timers, then call alarm with that timeout. In the signal handler, perform the processing that you want to do on reception of timeout. Alternatively, do nothing in the signal handler, and just trust that any pending system call will be interrupted, and check all timers for expiry on EINTR.
Edit: alarm works like this
#include <unistd.h>
#include <signal.h>
void timeout(int ignored)
{
printf("timed out\n");
}
void main()
{
signal(SIGALRM, timeout);
alarm(10);
pause();
}

Related

Linux C timer - signal disrupts current process

I'm working on a application that has specific timing restraints such that an event should occur (ideally exactly) every 200us. I'm trying to do this with a timer and signal.
#include <stdio.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <pthread.h>
timer_t timer_id;
void start_timer(void)
{
struct itimerspec value;
value.it_value.tv_sec = 0;
value.it_value.tv_nsec = 20000;
value.it_interval.tv_sec = 0;
value.it_interval.tv_nsec = 200000;
timer_create(CLOCK_REALTIME, NULL, &timer_id);
timer_settime(timer_id, 0, &value, NULL);
}
void handler(int sig) {
printf("in handler\n");
}
void *my_thread(void *ignore)
{
(void)ignore;
start_timer();
// Sleep forever
while(1) sleep(1000);
}
int main()
{
pthread_t thread_id;
(void) signal(SIGALRM, handler);
pthread_create(&thread_id, NULL, my_thread, NULL);
// sleep is a placeholder for this SO question. I want to do
// other processing here
sleep(5000);
printf("sleep finished\n");
}
After 200us the signal handler is called. It appears to be called when the sleep(5000) line is running because the "sleep finished" message is displayed early. I want the timer to disrupt the thread that started the timer, not the main process. This is why I created a thread to start it. Is there a way to have the signal only abort the current instruction on the thread instead of on the main process? I know that the other threads/processes will be blocked when the handler runs, but I wanted them to continue afterwards as if nothing happened. For example, in this case I want to sleep at least 5000 seconds.
Yes, you can block the signal (pthread_sigmask) in the main thread before starting any other threads, and only unblock it in the thread intended to handle it. This will ensure that it arrives in the thread you want it in.
However, if you already have threads, are you sure you actually need a timer generating a signal for this? clock_nanosleep should allow sleep with wakeup at a precise time, and avoids all the awfulness of signals.

Linux driver code with wait queues hanging system

I have written a sample linux device driver code which will create two kernel threads and each will increment a single global variable. I have used wait-queues to perform the task of incrementing the variable, and each thread will wait on the wait queue until a timer expires and each thread is woken up at random.
But problem is when I inserted this module, the whole system is just freezing up, and I have to restart the machine. This is happening every time I inserted the module. I tried debugging the kthread code to see if I am entering dead-lock situation by mistake but I am unable to figure out anything wrong with the code.
Can anyone please tell me what I am doing wrong in the code to get the hang-up situation?
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/semaphore.h>
#include <linux/wait.h>
#include <linux/timer.h>
#include <linux/sched.h>
#include <linux/kthread.h>
spinlock_t my_si_lock;
pid_t kthread_pid1;
pid_t kthread_pid2 ;
static DECLARE_WAIT_QUEUE_HEAD(wqueue);
static struct timer_list my_timer;
int kthread_num;
/* the timer callback */
void my_timer_callback( unsigned long data ){
printk(KERN_INFO "my_timer_callback called (%ld).\n", jiffies );
if (waitqueue_active(&wqueue)) {
wake_up_interruptible(&wqueue);
}
}
/*Routine for the first thread */
static int kthread_routine_1(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int *num=(int *)kthread_num;
char kthread_name[15];
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
printk(KERN_INFO "Inside daemon_routine() %ld\n",current->pid);
allow_signal(SIGKILL);
allow_signal(SIGTERM);
do{
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wqueue, &wait);
spin_lock_irqsave(&my_si_lock, flags);
printk(KERN_INFO "kernel_daemon [%d] incrementing the shared data=%d\n",current->pid,(*num)++);
spin_unlock_irqrestore(&my_si_lock, flags);
remove_wait_queue(&wqueue, &wait);
if (kthread_should_stop()) {
break;
}
}while(!signal_pending(current));
set_current_state(TASK_RUNNING);
return 0;
}
/*Routine for the second thread */
static int kthread_routine_2(void *kthread_num)
{
//int num=(int)(*(int*)kthread_num);
int *num=(int *)kthread_num;
char kthread_name[15];
unsigned long flags;
DECLARE_WAITQUEUE(wait, current);
printk(KERN_INFO "Inside daemon_routine() %ld\n",current->pid);
allow_signal(SIGKILL);
allow_signal(SIGTERM);
do{
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wqueue, &wait);
spin_lock_irqsave(&my_si_lock, flags);
printk(KERN_INFO "kernel_daemon [%d] incrementing the shared data=%d\n",current->pid,(*num)++);
spin_unlock_irqrestore(&my_si_lock, flags);
remove_wait_queue(&wqueue, &wait);
if (kthread_should_stop()) {
break;
}
}while(!signal_pending(current));
set_current_state(TASK_RUNNING);
return 0;
}
static int __init signalexample_module_init(void)
{
int ret;
spin_lock_init(&my_si_lock);
init_waitqueue_head(&wqueue);
kthread_num=1;
printk(KERN_INFO "starting the first kernel thread with id ");
kthread_pid1 = kthread_run(kthread_routine_1,&kthread_num,"first_kthread");
printk(KERN_INFO "%ld \n",(long)kthread_pid1);
if(kthread_pid1< 0 ){
printk(KERN_ALERT "Kernel thread [1] creation failed\n");
return -1;
}
printk(KERN_INFO "starting the second kernel thread with id");
kthread_pid2 = kthread_run(kthread_routine_2,&kthread_num,"second_kthread");
printk(KERN_INFO "%ld \n",(long)kthread_pid2);
if(kthread_pid2 < 0 ){
printk(KERN_ALERT "Kernel thread [2] creation failed\n");
return -1;
}
setup_timer( &my_timer, my_timer_callback, 0 );
ret = mod_timer( &my_timer, jiffies + msecs_to_jiffies(2000) );
if (ret) {
printk("Error in mod_timer\n");
return -EINVAL;
}
return 0;
}
static void __exit signalexample_module_exit(void)
{
del_timer(&my_timer);
}
module_init(signalexample_module_init);
module_exit(signalexample_module_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Demonstrates use of kthread");
You need a call to schedule() in both of your thread functions:
/* In kernel thread function... */
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&wqueue, &wait);
schedule(); /* Add this call here */
spin_lock_irqsave(&my_si_lock, flags);
/* etc... */
Calling set_current_state(TASK_INTERRUPTIBLE) sets the state in the current process' task structure, which allows the scheduler to move the process off of the run queue once it sleeps. But then you have to tell the scheduler, "Okay, I've set a new state. Reschedule me now." You're missing this second step, so the changed flag won't take effect until the next time the scheduler decides to suspend your thread, and there's no way to know how soon that will happen, or which line of your code it's executing when it happens (except in the locked code - that shouldn't be interrupted).
I'm not really sure why it's causing your whole system to lock up, because your system's state is pretty unpredictable. Since the kernel threads weren't waiting for the timer to expire before grabbing locks and looping, I have no idea when you could expect the scheduler to actually take action on the new task struct states, and a lot of things could be happening in the meantime. Your threads are repeatedly calling add_wait_queue(&wqueue, &wait); and remove_wait_queue(&wqueue, &wait);, so who knows what state the wait queue is in by the time your timer callback fires. In fact, since the kernel threads are spinning, this code has a race condition:
if (waitqueue_active(&wqueue)) {
wake_up_interruptible(&wqueue);
}
It's possible that you have active tasks on the waitqueue when the if statement is executed, only to have them emptied out by the time wake_up_interruptible(&wqueue); is called.
By the way, I'm assuming your current goal of incrementing a global variable is just an exercise to learn waitqueues and sleep states. If you ever want to actually implement a shared counter, look at atomic operations instead, and you'll be able to dump the spinlock.
If you decide to keep the spinlock, you should switch to using the DEFINE_SPINLOCK() macro instead.
Also, as I mentioned in my comment, you should change your two kthread_pid variables to be of task_struct * type. You also need a call to kthread_stop(kthread_pid); in your __exit routine for each of the threads you start. kthread_should_stop() will never return true if you don't ever tell them to stop.

how to call a function automatically at regular intervals?

Hi I am writing a C program to interface a serial device which gives data at regular intervals, i need to look for the inputs at the serial port at regular intervals. this can be done by a ' read' function . but i dont know how to call it frequently at fixed time intervals ?
This sort of behavior short-circuits the lovely machinery built in to most OSes to do just this, failing that something like cron would seem to be a lovely option. Failing all of that (if you're just looking for a quick hacky option) busy wait is not super awesome, the system isn't bright enough to hyperthread around that so your program winds up eating up a core doing nothing for the duration of your program, so while it's largely a matter of taste, I'm a nanosleep man myself.
on nix/nux systems:
#include <time.h>
int main(void)
{
struct timespec sleepytime;
sleepytime.tv_sec = seconds_you_want_to_sleep
sleepytime.tv_nsec = nanoseconds_you_want_to_sleep
while( !done)
{
nanosleep(&sleepytime, NULL);
//do your stuff here
}
return 0;
}
if you're worried about getting interrupted, the second parameter should be another timespec struct, in which will be stored the amount of time remaining, check if == 0,
then keep on trucking.
in windows apparently it is a little easier.
#include <windows.h>
int main(void)
{
while( !done)
{
Sleep(milliseconds_you_want_to_sleep);
//do your stuff here
}
return 0;
}
Unfortunately I don't run windows so I haven't been able to test the second code sample.
If you really need to read at regular intervals ( and not just poll for data to be available ) , you can do something like this :
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
void timer_handler (int signum)
{
static int count = 0;
printf ("timer expired %d times\n", ++count);
}
int main ()
{
struct sigaction sa;
struct itimerval timer;
/* Install timer_handler as the signal handler for SIGVTALRM. */
memset (&sa, 0, sizeof (sa));
sa.sa_handler = &timer_handler;
sigaction (SIGVTALRM, &sa, NULL);
/* Configure the timer to expire after 250 msec... */
timer.it_value.tv_sec = 0;
timer.it_value.tv_usec = 250000;
/* ... and every 250 msec after that. */
timer.it_interval.tv_sec = 0;
timer.it_interval.tv_usec = 250000;
/* Start a virtual timer. It counts down whenever this process is
executing. */
setitimer (ITIMER_REAL, &timer, NULL);
/* Do busy work. */
while (1);
}
I copied this from http://www.informit.com/articles/article.aspx?p=23618&seqNum=14 and changed the timer type, effectively you are setting up an interval timer and handling the signal when the timer runs out.

Code works for some time then just stops

I have made an application that monitors an interface and returns a packets per second reading, how ever when executed it runs fine for about 30 seconds till I open a YouTube page to get the counter running a little high. A couple of seconds later the application freezes and does nothing. This happens in irregular intervals so Im guessing its something with the counting, theres the code, its written in C.
#include <stdio.h>
#include <pcap.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <pthread.h>
void callThreads(u_char *useless, const struct pcap_pkthdr* pkthdr, const u_char* packet);
void *packetcalc(void *threadid);
static struct timespec time1, time2;
static int t = 0, i = 0;
static long rc;
static pthread_t threads[1];
int main(int argc, char *argv[]){
pcap_t* descr;
char errbuf[PCAP_ERRBUF_SIZE];
descr = pcap_open_live("eth0", BUFSIZ, 1, -1, errbuf);
if(descr == NULL){
printf("Error: pcap_open_live()\n");
return 1;
}
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
pcap_loop(descr, 0, callThreads, NULL);
return 0;
}
void callThreads(u_char *useless, const struct pcap_pkthdr* pkthdr, const u_char* packet){
if(i >= 2147483647){
//In case i gets full from counting too many packets
i = 0;
time1.tv_sec = 0;
}
++i;
rc = pthread_create(&threads[t], NULL, packetcalc, (void *) t);
}
void *packetcalc(void *threadid){
static int j;
static int temp = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
if(temp != time1.tv_sec){
j = (i / time1.tv_sec);
printf("Packets: %d/sec\t(%d)\t(%d)\n", j, i, (int)time1.tv_sec);
temp = time1.tv_sec;
}
pthread_exit(NULL);
}
Edit: Could it also be that I'm running this code in a VM that only has 1 CPU allocated to it due to the multithreading?
You are creating a thread per packet, which is a horrible idea. It should be enough to just print whatever counter you need right out of the callback function you give to pcap_loop(3).
There are several problems with your code. First, you create the threads using the default thread attributes, which means that they are created as joinable threads, i.e. you must call pthread_join() later or the thread control structures would remain lingering around. Hence there is a memory leak in your code. May be you should check the return value from pthread_create in order to detect when an error occurs, e.g. the system was not able to create new threads and your packet counting routine has stopped being invoked. You can also create new threads in detached state using the following code:
pthread_attr_t attr;
pthread_attribute_init(&attr);
pthread_attribute_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&threadid, &attr, packetcalc, (void *) t);
pthread_attribute_destroy(&attr);
Detached threads do not need to be joined later. They release all resources upon thread exit.
Second, you threads use some global variables as if they are private when in reality they are shared. This includes the global time1, as well as the local j and temp, which are declared static and hence are shared among the threads.
Note that creating threads is an expensive operation. While your code waits for pthread_create to finish, new packets may arrive and fill up the circular buffer, used by libpcap, hence you might lose some packets. As a matter of fact, using one thread per packet is a very bad idea. Instead use only two threads - one that runs the pcap loop and one that periodically counts the number of packets and calculates and prints the packet rate.

How to use libevent and pthread together in C

The main function is based on libevent, but there is a long run task in the function. So start N treads to run the tasks. Is is this idea OK? And how to use libevent and pthread together in C?
Bumping an old question, may have already been solved. But posting the answer just in case someone else needs it.
Yes, it is okay to do threading in this case. I recently used libevent in pthreads, and it seems to be working just fine. Here's the code :
#include <stdint.h>
#include <pthread.h>
#include <event.h>
void * thread_func (void *);
int main(void)
{
int32_t tid = 0, ret = -1;
struct event_base *evbase;
struct event *timer;
int32_t *t_ret = &ret;
struct timeval tv;
// 1. initialize libevent for pthreads
evthread_use_pthreads();
ret = pthread_create(&tid, NULL, thread_func, NULL);
// check ret for error
// 2. allocate event base
evbase = event_base_new();
// 3. allocate event object
timer = event_new(evbase, -1, EV_PERSIST, callback_func, NULL);
// 4. add event
tv.tv_sec = 0;
tv.tv_usec = 1000;
evtimer_add(timer, &tv);
// 5. start the event loop
event_base_dispatch(evbase); // event loop
// join pthread...
// 6. free resources
event_free(timer);
event_base_free(evbase);
return 0;
}
void * thread_func(void *arg)
{
struct event *ev;
struct event_base *base;
base = event_base_new();
ev = event_new(base, -1, EV_PERSIST, thread_callback, NULL);
event_add(ev, NULL); // wait forever
event_base_dispatch(base); // start event loop
event_free(ev);
event_base_free(base);
pthread_exit(0);
}
As you can see, in my case, the event for the main thread is timer. The base logic followed is as below :
call evthread_use_pthreads() to initialize libevent for pthreads on Linux (my case). For windows evthread_use_window_threads(). Check out the documentation given in event.h itself.
Allocate an event_base structure on global heap as instructed in documentation. Make sure to check return value for errors.
Same as above, but allocate event structure itself. In my case, I am not waiting on any file descriptor, so -1 is passed as argument. Also, I want my event to persist, hence EV_PERSIST . The code for callback functions is omitted.
Schedule the event for execution
Start the event loop
free the resources when done.
Libevent version used in my case is libevent2 5.1.9 , and you will also need libevent_pthreads.so library for linking.
cheers.
That would work.
In the I/O callback function delegates time consuming job to another thread of a thread pool. The exact mechanics depend on the interface of the worker thread or the thread pool.
To communicate the result back from the worker thread to the I/O thread use a pipe. The worker thread writes the pointer to the result object to the pipe and the I/O thread
wakes up and read the pointer from the pipe.
There is a multithreaded libevent example in this blog post:
http://www.roncemer.com/multi-threaded-libevent-server-example
His solution is, to quote:
The solution is to create one libevent event queue (AKA event_base) per active connection, each with its own event pump thread. This project does exactly that, giving you everything you need to write high-performance, multi-threaded, libevent-based socket servers.
NOTE This is for libev not libevent but the idea may apply.
Here I present an example for the community. Please comment and let me know if there are any noticable bugs. This example could include a signal handler for thread termination and graceful exit in the future.
//This program is demo for using pthreads with libev.
//Try using Timeout values as large as 1.0 and as small as 0.000001
//and notice the difference in the output
//(c) 2009 debuguo
//(c) 2013 enthusiasticgeek for stack overflow
//Free to distribute and improve the code. Leave credits intact
//compile using: gcc -g test.c -o test -lpthread -lev
#include <ev.h>
#include <stdio.h> // for puts
#include <stdlib.h>
#include <pthread.h>
pthread_mutex_t lock;
double timeout = 0.00001;
ev_timer timeout_watcher;
int timeout_count = 0;
ev_async async_watcher;
int async_count = 0;
struct ev_loop* loop2;
void* loop2thread(void* args)
{
// now wait for events to arrive on the inner loop
ev_loop(loop2, 0);
return NULL;
}
static void async_cb (EV_P_ ev_async *w, int revents)
{
//puts ("async ready");
pthread_mutex_lock(&lock); //Don't forget locking
++async_count;
printf("async = %d, timeout = %d \n", async_count, timeout_count);
pthread_mutex_unlock(&lock); //Don't forget unlocking
}
static void timeout_cb (EV_P_ ev_timer *w, int revents) // Timer callback function
{
//puts ("timeout");
if(ev_async_pending(&async_watcher)==false){ //the event has not yet been processed (or even noted) by the event loop? (i.e. Is it serviced? If yes then proceed to)
ev_async_send(loop2, &async_watcher); //Sends/signals/activates the given ev_async watcher, that is, feeds an EV_ASYNC event on the watcher into the event loop.
}
pthread_mutex_lock(&lock); //Don't forget locking
++timeout_count;
pthread_mutex_unlock(&lock); //Don't forget unlocking
w->repeat = timeout;
ev_timer_again(loop, &timeout_watcher); //Start the timer again.
}
int main (int argc, char** argv)
{
if (argc < 2) {
puts("Timeout value missing.\n./demo <timeout>");
return -1;
}
timeout = atof(argv[1]);
struct ev_loop *loop = EV_DEFAULT; //or ev_default_loop (0);
//Initialize pthread
pthread_mutex_init(&lock, NULL);
pthread_t thread;
// This loop sits in the pthread
loop2 = ev_loop_new(0);
//This block is specifically used pre-empting thread (i.e. temporary interruption and suspension of a task, without asking for its cooperation, with the intention to resume that task later.)
//This takes into account thread safety
ev_async_init(&async_watcher, async_cb);
ev_async_start(loop2, &async_watcher);
pthread_create(&thread, NULL, loop2thread, NULL);
ev_timer_init (&timeout_watcher, timeout_cb, timeout, 0.); // Non repeating timer. The timer starts repeating in the timeout callback function
ev_timer_start (loop, &timeout_watcher);
// now wait for events to arrive on the main loop
ev_loop(loop, 0);
//Wait on threads for execution
pthread_join(thread, NULL);
pthread_mutex_destroy(&lock);
return 0;
}

Resources