From a8e71e8fffa0159f06b2c469fb2d3dfd8222b306 Mon Sep 17 00:00:00 2001 From: Tomas Mudrunka Date: Fri, 25 Jun 2021 12:56:00 +0200 Subject: [PATCH] pthread_pause pthread_unpause --- c/pthread_extra/Makefile | 4 ++- c/pthread_extra/pthread_extra.h | 14 ++++++++++ c/pthread_extra/pthread_pause.c | 19 ++++++++++++++ c/pthread_extra/test.c | 26 +++++++++++++------ c/pthread_extra/test_pause.c | 46 +++++++++++++++++++++++++++++++++ 5 files changed, 100 insertions(+), 9 deletions(-) create mode 100644 c/pthread_extra/pthread_pause.c create mode 100644 c/pthread_extra/test_pause.c diff --git a/c/pthread_extra/Makefile b/c/pthread_extra/Makefile index 954e2f6..cf4e674 100644 --- a/c/pthread_extra/Makefile +++ b/c/pthread_extra/Makefile @@ -11,13 +11,15 @@ CXXFLAGS+=$(COPT) $(CERR) $(CDEF) -std=c++11 $(CLIB) LDFLAGS+=$(COPT) $(LIB) BIN=test -OBJ=pthread_multi.o pthread_msgqueue.o test.o +OBJ=pthread_pause.o pthread_multi.o pthread_msgqueue.o test.o all: $(BIN) $(BIN): $(OBJ) $(CXX) -o $(BIN) $(OBJ) $(LDFLAGS) strip --strip-unneeded $(BIN) + gcc -lpthread -I . test_pause.c pthread_pause.o -o test_pause + clean: rm -f $(BIN) $(OBJ) $(DEPS) diff --git a/c/pthread_extra/pthread_extra.h b/c/pthread_extra/pthread_extra.h index e1fe782..bd1baad 100644 --- a/c/pthread_extra/pthread_extra.h +++ b/c/pthread_extra/pthread_extra.h @@ -5,10 +5,24 @@ #include #include #include +#include #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 index 0000000..309016c --- /dev/null +++ b/c/pthread_extra/pthread_pause.c @@ -0,0 +1,19 @@ +#include +#include +#include + +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); +} diff --git a/c/pthread_extra/test.c b/c/pthread_extra/test.c index 891cd50..f39a979 100644 --- a/c/pthread_extra/test.c +++ b/c/pthread_extra/test.c @@ -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 index 0000000..47f2db0 --- /dev/null +++ b/c/pthread_extra/test_pause.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include + +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"); +} -- 2.30.2