summaryrefslogtreecommitdiffstats
path: root/Master/Real-Time Systems/Praktikum1/Aufgabe1/src
diff options
context:
space:
mode:
authorSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
committerSven Eisenhauer <sven@sven-eisenhauer.net>2023-11-10 15:11:48 +0100
commit33613a85afc4b1481367fbe92a17ee59c240250b (patch)
tree670b842326116b376b505ec2263878912fca97e2 /Master/Real-Time Systems/Praktikum1/Aufgabe1/src
downloadStudium-master.tar.gz
Studium-master.tar.bz2
add new repoHEADmaster
Diffstat (limited to 'Master/Real-Time Systems/Praktikum1/Aufgabe1/src')
-rw-r--r--Master/Real-Time Systems/Praktikum1/Aufgabe1/src/main.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/Master/Real-Time Systems/Praktikum1/Aufgabe1/src/main.cpp b/Master/Real-Time Systems/Praktikum1/Aufgabe1/src/main.cpp
new file mode 100644
index 0000000..65eef37
--- /dev/null
+++ b/Master/Real-Time Systems/Praktikum1/Aufgabe1/src/main.cpp
@@ -0,0 +1,195 @@
+/*
+ * main.cpp
+ *
+ * Created on: 31.10.2010
+ * Author: sven
+ */
+#include <pthread.h>
+#include <semaphore.h>
+#include <time.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// debug printing
+#ifdef DEBUG_MODE
+#include <stdio.h>
+ #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;
+}