Implementace vyhradniho rezimu
authorTomas Mudrunka <tomas@mudrunka.cz>
Thu, 1 Jul 2021 13:36:31 +0000 (15:36 +0200)
committerTomas Mudrunka <tomas@mudrunka.cz>
Thu, 1 Jul 2021 13:36:31 +0000 (15:36 +0200)
c/pthread_extra/pthread_extra.h
c/pthread_extra/pthread_pause.c
c/pthread_extra/pthread_user_data.c
c/pthread_extra/test_pause.c

index ca5de70c6ae121025b2935e74345c1fa107fbc78..4df45d97eb6b29d3fed4398035a31756e4cf5fc0 100644 (file)
@@ -32,6 +32,7 @@ void** pthread_user_data_ptr(pthread_t thread);
 void*  pthread_user_data_get(pthread_t thread);
 void   pthread_user_data_set(pthread_t thread, void *usr);
 void   pthread_user_data_cleanup(void * arg);
+int pthread_user_data_internal_iterate(int (*routine)(pthread_t), void *arg);
 
 // Pausing
 
@@ -50,6 +51,8 @@ void pthread_pause_enable();
 void pthread_pause_disable();
 int pthread_pause(pthread_t thread);
 int pthread_unpause(pthread_t thread);
+int pthread_pause_all();
+int pthread_unpause_all();
 int pthread_pause_reschedule(pthread_t thread);
 int pthread_extra_yield();
 
index 4107b38004fac9c2cb1686b91ff546d157ca7518..63ccc6a05cb299bae0c8a099fc520be1f55bb2c3 100644 (file)
@@ -14,7 +14,7 @@
 
 ///When this variable is nonzero, only referenced thread is allowed to run
 ///Access has to be protected by pthread_user_data_lock()
-pthread_t pthread_pause_holder = 0;
+pthread_t pthread_pause_holder = PTHREAD_XNULL;
 
 void pthread_pause_handler(const int signal, siginfo_t *info, void *ptr) {
        (void)signal; (void)info; (void)ptr;
@@ -98,7 +98,7 @@ int pthread_pause_reschedule(pthread_t thread) {
        //Check if thread has running flag
        int run = (pthread_user_data_internal(thread)->running);
        //Check if privileged (single thread) mode is active
-       if((pthread_pause_holder != 0) && !pthread_equal(pthread_pause_holder, thread)) {
+       if((pthread_pause_holder != PTHREAD_XNULL) && !pthread_equal(pthread_pause_holder, thread)) {
                run = 0;
        }
        pthread_user_data_unlock();
@@ -137,19 +137,19 @@ int pthread_unpause(pthread_t thread) {
 
 int pthread_pause_all() {
        pthread_user_data_lock();
-       if(pthread_pause_holder!=0) assert(pthread_equal(pthread_pause_holder, pthread_self()));
+       if(pthread_pause_holder!=PTHREAD_XNULL) assert(pthread_equal(pthread_pause_holder, pthread_self()));
        pthread_pause_holder = pthread_self();
        pthread_user_data_unlock();
-       //todo reschedule all
+       pthread_user_data_internal_iterate(&pthread_pause_reschedule, NULL);
        return 0;
 }
 
 int pthread_unpause_all() {
        pthread_user_data_lock();
-       if(pthread_pause_holder!=0) assert(pthread_equal(pthread_pause_holder, pthread_self()));
-       pthread_pause_holder = 0;
+       if(pthread_pause_holder!=PTHREAD_XNULL) assert(pthread_equal(pthread_pause_holder, pthread_self()));
+       pthread_pause_holder = PTHREAD_XNULL;
        pthread_user_data_unlock();
-       //todo reschedule
+       pthread_user_data_internal_iterate(&pthread_pause_reschedule, NULL);
        return 0;
 }
 
index a1e1ebd4d40fbf05a547a968c2131d31fb533c83..cf97a652f6d1c973aa06f9920c2e0643cb17ae63 100644 (file)
@@ -48,6 +48,19 @@ pthread_user_data_internal_t* pthread_user_data_internal(pthread_t thread) {
        return &pthread_user_data[i];
 }
 
+//Iterate specified callback over all registered threads
+int pthread_user_data_internal_iterate(int (*routine)(pthread_t), void *arg) {
+       (void) arg;
+       int i;
+       pthread_user_data_lock();
+       for(i = 0; i<PTHREAD_XTHREADS_MAX; i++) {
+               if(pthread_equal(pthread_user_data[i].tid, PTHREAD_XNULL)) break;
+               routine(pthread_user_data[i].tid);
+       }
+       pthread_user_data_unlock();
+       return i;
+}
+
 //Get pointer to user specified pointer of that thread
 void** pthread_user_data_ptr(pthread_t thread) {
        return &pthread_user_data_internal(thread)->usr;
index f17be8a3de72c378780be4903f8e7ea8be9eb2b1..ed60fcc6d187ae32501f00378033f512921ba8c8 100644 (file)
@@ -54,6 +54,13 @@ int main() {
                pthread_unpause(a);
                pthread_unpause(b);
                sleep(1);
+
+               printf("SWITCH MAIN ONLY:\n");
+               pthread_pause_all();
+               sleep(1);
+               printf("SWITCH MAIN A+B:\n");
+               pthread_unpause_all();
+               sleep(1);
        }
 
        pthread_join(a, NULL);
This page took 0.213551 seconds and 4 git commands to generate.