pthread_pause pthread_unpause
authorTomas Mudrunka <tomas@mudrunka.cz>
Fri, 25 Jun 2021 10:56:00 +0000 (12:56 +0200)
committerTomas Mudrunka <tomas@mudrunka.cz>
Fri, 25 Jun 2021 10:56:00 +0000 (12:56 +0200)
c/pthread_extra/Makefile
c/pthread_extra/pthread_extra.h
c/pthread_extra/pthread_pause.c [new file with mode: 0644]
c/pthread_extra/test.c
c/pthread_extra/test_pause.c [new file with mode: 0644]

index 954e2f6c0018bbfa0e036b3764cd966948ed7025..cf4e67474bf7817aa8da742dffa357bc6fe6d522 100644 (file)
@@ -11,13 +11,15 @@ CXXFLAGS+=$(COPT) $(CERR) $(CDEF) -std=c++11 $(CLIB)
 LDFLAGS+=$(COPT) $(LIB)\r
 \r
 BIN=test\r
-OBJ=pthread_multi.o pthread_msgqueue.o test.o\r
+OBJ=pthread_pause.o pthread_multi.o pthread_msgqueue.o test.o\r
 \r
 all: $(BIN)\r
 $(BIN): $(OBJ)\r
        $(CXX) -o $(BIN) $(OBJ) $(LDFLAGS)\r
        strip --strip-unneeded $(BIN)\r
 \r
+       gcc -lpthread -I . test_pause.c pthread_pause.o -o test_pause\r
+\r
 clean:\r
        rm -f $(BIN) $(OBJ) $(DEPS)\r
 \r
index e1fe782cec638133d401592152c7c582644e7a59..bd1baad3b8e1270495b616ccd1b458fe568fd761 100644 (file)
@@ -5,10 +5,24 @@
 #include <time.h>
 #include <stdbool.h>
 #include <stdint.h>
+#include <signal.h>
 
 #define PTHREAD_XTIME_NOBLOCK (&(struct timespec){ .tv_sec = 0, .tv_nsec = 0 })
 #define PTHREAD_XTIME_FOREVER NULL
 
+//Pausing
+
+#define PTHREAD_XSIG_STOP (SIGRTMIN+0)
+#define PTHREAD_XSIG_CONT (SIGRTMIN+1)
+#define PTHREAD_XSIGRTMIN (SIGRTMIN+2) //First unused RT signal
+
+#define pthread_pause(t)   (pthread_kill((t), PTHREAD_XSIG_STOP));
+#define pthread_unpause(t) (pthread_kill((t), PTHREAD_XSIG_CONT));
+
+void pthread_unpause_handler();
+void pthread_pause_handler();
+void pthread_pause_enable();
+
 // Message queues
 
 #define PTHREAD_XMQ_FRONT true
diff --git a/c/pthread_extra/pthread_pause.c b/c/pthread_extra/pthread_pause.c
new file mode 100644 (file)
index 0000000..309016c
--- /dev/null
@@ -0,0 +1,19 @@
+#include <pthread.h>
+#include <pthread_extra.h>
+#include <signal.h>
+
+void pthread_unpause_handler() {
+       //NOP
+}
+
+void pthread_pause_handler() {
+       sigset_t sigset;
+       sigfillset(&sigset);
+       sigdelset(&sigset, PTHREAD_XSIG_CONT);
+       sigsuspend(&sigset);
+}
+
+void pthread_pause_enable() {
+       signal(PTHREAD_XSIG_STOP, pthread_pause_handler);
+       signal(PTHREAD_XSIG_CONT, pthread_unpause_handler);
+}
index 891cd504c2632171618254e0f32db5e85bc813d6..f39a979cb7ade2f6acc46ce9e1e79f4042967103 100644 (file)
@@ -40,12 +40,21 @@ void *thread_recv() {
 
        char str[128];
        while(1) {
-               pthread_mq_receive_generic(&myq, &str, false, PTHREAD_XTIME_FOREVER);
-               printf("RECVD: %.6s\t\t(waiting %d)\n", str, (int)pthread_mq_waiting(&myq));
-               sleep(1);
+               if(pthread_mq_receive_generic(&myq, &str, false, PTHREAD_XTIME_FOREVER))
+                       printf("-RECVD: %.6s\t\t(waiting %d)\n", str, (int)pthread_mq_waiting(&myq));
+               if(pthread_mq_receive_generic(&myq, &str, false, PTHREAD_XTIME_NOBLOCK))
+                       printf("+RECVD: %.6s\t\t(waiting %d)\n", str, (int)pthread_mq_waiting(&myq));
        }
 }
 
+void *thread_send() {
+       while(1) {
+               pthread_mq_send_generic(&myq, " X   ", true, PTHREAD_XTIME_NOBLOCK);
+               pthread_mq_send_generic(&myq, " Y   ", false, PTHREAD_XTIME_FOREVER);
+       }
+}
+
+
 int main() {
        //main_mumu();
 
@@ -55,6 +64,8 @@ int main() {
 
        pthread_t t;
        pthread_create(&t, NULL, thread_recv, NULL);
+       pthread_t s;
+       pthread_create(&s, NULL, thread_send, NULL);
 
        pthread_mq_send_generic(&myq, "AHOJ1", false, NULL);
        pthread_mq_send_generic(&myq, "AHOJ2", false, NULL);
@@ -64,11 +75,10 @@ int main() {
        pthread_mq_send_generic(&myq, "AHOJ6", true, NULL);
 
        while(1) {
-               pthread_mq_send_generic(&myq, "B", false, NULL);
-               pthread_mq_send_generic(&myq, "A", true, NULL);
-               pthread_mq_send_generic(&myq, " A", false, NULL);
-               pthread_mq_send_generic(&myq, " B", false, NULL);
-               sleep(1);
+               pthread_mq_send_generic(&myq, "B    ", false, NULL);
+               pthread_mq_send_generic(&myq, "A    ", true, NULL);
+               pthread_mq_send_generic(&myq, " B   ", false, PTHREAD_XTIME_FOREVER);
+               pthread_mq_send_generic(&myq, " A   ", false, PTHREAD_XTIME_NOBLOCK);
        }
 
        pthread_join(t, NULL);
diff --git a/c/pthread_extra/test_pause.c b/c/pthread_extra/test_pause.c
new file mode 100644 (file)
index 0000000..47f2db0
--- /dev/null
@@ -0,0 +1,46 @@
+#include <signal.h>
+#include <pthread.h>
+#include <pthread_extra.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+
+void *thread_test(void *arg) {
+       //Whole process dies if you kill thread immediately before it is pausable
+       //pthread_pause_enable();
+       while(1) {
+               usleep(1000*300);
+               printf("Running%s!\n", (char *)arg);
+       }
+}
+
+int main() {
+
+       pthread_t a, b;
+       pthread_pause_enable(); //Will get inherited by all threads from now on
+       //That way you can be sure it is pausable immediately
+       pthread_create(&a, NULL, thread_test, " A");
+       pthread_create(&b, NULL, thread_test, " B");
+
+       while(1) {
+               pthread_pause(b);
+               pthread_unpause(a);
+               printf("SWITCH A:\n");
+               sleep(2);
+
+               printf("SWITCH B:\n");
+               pthread_pause(a);
+               pthread_unpause(b);
+               sleep(2);
+
+               printf("SWITCH A+B:\n");
+               pthread_unpause(a);
+               pthread_unpause(b);
+               sleep(1);
+       }
+
+       pthread_join(a, NULL);
+       pthread_join(b, NULL);
+       printf("DIEDED!\n");
+}
This page took 0.216806 seconds and 4 git commands to generate.