/* * main.cpp * * Created on: 31.10.2010 * Author: sven */ #include #include #include #include #include #include #include #include // debug printing #ifdef DEBUG_MODE #include #define DEBUG_PRINT(format, args...)\ {\ static char message[512];\ snprintf(message,512,format, ##args);\ fprintf(stdout, "[%s: %d] : %s\n", __PRETTY_FUNCTION__,__LINE__, message);\ fflush(stdout);\ } #else #define DEBUG_PRINT(format, args...) #endif // DEBUG_MODE /* * global variables */ sem_t main_block,timer_block; pthread_t timer_thread; bool stop_timer_thread = false; pthread_mutex_t stop_mutex = PTHREAD_MUTEX_INITIALIZER; // 0 sec const long TIMER_INTERVAL_SECS = 0; // 10 msec const long TIMER_INTERVAL_USECS = 10000; struct sigaction timer_action, quit_action; /* * function prototypes */ void readSensors(); void initializeClock(); void initializeMain(); void WaitForNextCycle(); void ActuateProcess(); bool CalculateNewSetValues(); void Error(); void* TimerThreadProc(void*); void timer_handler(int); void* TimerThreadProc(void*) { /** * Timer code originally from * http://www.informit.com/articles/article.aspx?p=23618&seqNum=14 */ DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); bool stop_me = false; struct itimerval timer; /* Install timer_handler as the signal handler for SIGALRM. */ timer_action.sa_handler = timer_handler; sigemptyset(&timer_action.sa_mask); timer_action.sa_flags = 0; sigaction(SIGALRM,&timer_action,NULL); /* Configure the timer to expire after * TIMER_INTERVAL_SECS + TIMER_INTERVAL_USECS... */ timer.it_value.tv_sec = TIMER_INTERVAL_SECS; timer.it_value.tv_usec = TIMER_INTERVAL_USECS; /* ... and every TIMER_INTERVAL_SECS+TIMER_INTERVAL_USECS after that. */ timer.it_interval.tv_sec = TIMER_INTERVAL_SECS; timer.it_interval.tv_usec = TIMER_INTERVAL_USECS; /* If the timer code is ITIMER_REAL, * the process is sent a SIGALRM signal after the * specified wall-clock time has elapsed*/ setitimer (ITIMER_REAL, &timer, NULL); while(1) { pthread_mutex_lock(&stop_mutex); stop_me = stop_timer_thread; pthread_mutex_unlock(&stop_mutex); if(stop_me) { DEBUG_PRINT("exiting thread Process: %d Thread: %lu",(int)getpid(),pthread_self()); pthread_exit(NULL); } DEBUG_PRINT("waiting for timer_handler Process: %d Thread: %lu",(int)getpid(),pthread_self()); sem_wait(&timer_block); DEBUG_PRINT("waking up main Process: %d Thread: %lu",(int)getpid(),pthread_self()); sem_post(&main_block); } DEBUG_PRINT("should never happen Process: %d Thread: %lu",(int)getpid(),pthread_self()); return NULL; } void timer_handler(int signum) { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); static int count = 0; DEBUG_PRINT("timer expired %d times", ++count); sem_post(&timer_block); DEBUG_PRINT("exit"); } void quit_handler(int signum) { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); int semval; pthread_mutex_lock(&stop_mutex); stop_timer_thread = true; pthread_mutex_unlock(&stop_mutex); sem_getvalue(&timer_block,&semval); if(semval > 0) { DEBUG_PRINT("waking up timer thread"); sem_post(&timer_block); } pthread_join(timer_thread,NULL); DEBUG_PRINT("Joined timer thread"); //clean up sem_destroy(&timer_block); sem_destroy(&main_block); pthread_mutex_destroy(&stop_mutex); DEBUG_PRINT("exit"); exit(EXIT_SUCCESS); } void WaitForNextCycle() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); sem_wait(&main_block); DEBUG_PRINT("exit"); } void readSensors() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); struct timeval tv; struct timezone tz; struct tm *tm; gettimeofday(&tv, &tz); tm=localtime(&tv.tv_sec); printf(" %d:%02d:%02d %lu \n", tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec); DEBUG_PRINT("exit"); } void Error() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); DEBUG_PRINT("exit"); } bool CalculateNewSetValues() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); DEBUG_PRINT("exit"); return true; } void ActuateProcess() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); DEBUG_PRINT("exit"); } void initializeClock() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); pthread_create(&timer_thread,NULL,TimerThreadProc,NULL); DEBUG_PRINT("exit"); } void initializeMain() { DEBUG_PRINT("entry Process: %d Thread: %lu",(int)getpid(),pthread_self()); /* init semaphore as closed */ sem_init(&main_block,0,0); sem_init(&timer_block,0,0); /* catch all interesting signals */ quit_action.sa_handler = quit_handler; sigemptyset(&quit_action.sa_mask); quit_action.sa_flags = 0; sigaction(SIGTERM,&quit_action,NULL); sigaction(SIGQUIT,&quit_action,NULL); sigaction(SIGINT,&quit_action,NULL); sigaction(SIGHUP,&quit_action,NULL); DEBUG_PRINT("exit"); } int main(int argc, char* argv[]) { initializeMain(); initializeClock(); while(1) { readSensors(); if(CalculateNewSetValues()) ActuateProcess(); else Error(); WaitForNextCycle(); } return EXIT_SUCCESS; }