#include "thread/Watchdog.h" #include #include #include #include static const int COUNT = 3; static const int SLEEP_US = 500*1000; static const int WATCHDOG_INTERVAL_MS = 2000; static void run1(void* arg); static void run2(void* arg); static void run3(void* arg); static QueuedThread* t1 = NULL; static QueuedThread* t2 = NULL; static QueuedThread* t3 = NULL; __attribute__((__format__ (__printf__, 2, 0))) static void stdLog(const char* tag, const char* format, ...) { va_list args; printf("%s ", tag); va_start(args, format); vprintf(format, args); va_end(args); } _Noreturn static void onThreadUnresponsive(Thread* thread) { printf("Thread %p is unresponsive, exiting\n", (void*)(thread)); assert(thread == t3->thread); _exit(0); // this actually means passing the test } int main() { Watchdog* watchdog = createWatchdog(WATCHDOG_INTERVAL_MS, &onThreadUnresponsive, &stdLog); t1 = createWatchedThread(watchdog); t2 = createWatchedThread(watchdog); t3 = createWatchedThread(watchdog); printf("T1: %p\nT2: %p\nT3: %p\n", (void*)t1->thread, (void*)t2->thread, (void*)t3->thread); startWatchdog(watchdog); postQueuedTask(t1, &run1, NULL); postQueuedTask(t2, &run2, NULL); postQueuedTask(t3, &run3, NULL); for (int i = 0; i < COUNT+1; i++) { printf("Main: %d\n", i); usleep(SLEEP_US); } // give watchdog a chance to spot the hanged thread usleep((WATCHDOG_INTERVAL_MS+500) * 1000); stopWatchdog(watchdog); joinWatchedThreads(watchdog); freeWatchedThreads(watchdog); freeWatchdog(&watchdog); printf("Done.\n"); return 1; // this actually means failing the test } // --- void run1(void* arg) { (void)arg; for (int i = 0; i < COUNT; i++) { printf("Thread 1: %d\n", i); usleep(SLEEP_US); } } void run2(void* arg) { (void)arg; for (int i = 0; i < COUNT; i++) { printf("Thread 2: %d\n", i); usleep(SLEEP_US); } } _Noreturn void run3(void* arg) { (void)arg; for (int i = 0; i < COUNT; i++) { printf("Thread 3: %d\n", i); usleep(SLEEP_US); } while (1) {} // loop forever }