]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Implement pthread_yield.
authorJulian Seward <jseward@acm.org>
Wed, 22 May 2002 13:17:31 +0000 (13:17 +0000)
committerJulian Seward <jseward@acm.org>
Wed, 22 May 2002 13:17:31 +0000 (13:17 +0000)
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@308

12 files changed:
coregrind/arch/x86-linux/vg_libpthread.c
coregrind/arch/x86-linux/vg_libpthread_unimp.c
coregrind/vg_include.h
coregrind/vg_libpthread.c
coregrind/vg_libpthread_unimp.c
coregrind/vg_scheduler.c
tests/Makefile.am
tests/pth_yield.c [new file with mode: 0644]
vg_include.h
vg_libpthread.c
vg_libpthread_unimp.c
vg_scheduler.c

index 572f33aea0489b08acc3268deed023d58ab0ba0c..46d1c65a7949188e2c0faef47c58ff44d4b22212 100644 (file)
@@ -259,6 +259,17 @@ int pthread_attr_destroy(pthread_attr_t *attr)
    THREADs
    ------------------------------------------------ */
 
+__attribute__((weak))
+int pthread_yield ( void )
+{
+   int res;
+   ensure_valgrind("pthread_yield");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_YIELD, 0, 0, 0, 0);
+   return 0;
+}
+
+
 int pthread_equal(pthread_t thread1, pthread_t thread2)
 {
    return thread1 == thread2 ? 1 : 0;
index 01c299e2a9844ea4429219df7bef30e5f8f8d024..1458dc2fa4b3e513917bf7f2a015929cc4bf64bd 100644 (file)
@@ -252,8 +252,6 @@ __attribute__((weak)) void pthread_spin_trylock ( void )
                       { vgPlain_unimp("pthread_spin_trylock"); }
 __attribute__((weak)) void pthread_spin_unlock ( void )
                       { vgPlain_unimp("pthread_spin_unlock"); }
-__attribute__((weak)) void pthread_yield ( void )
-                      { vgPlain_unimp("pthread_yield"); }
 
 
 /*--------------------------------------------------------------------*/
index cdcd1caa3b15d60cccf2184bcfff979a62eb5ca7..692a48c528f0e91ecf9f1c0f03355b8f415fef73 100644 (file)
@@ -436,6 +436,7 @@ extern Bool  VG_(is_empty_arena) ( ArenaId aid );
 #define VG_USERREQ__PTHREAD_SIGMASK         0x3012
 #define VG_USERREQ__SIGWAIT                 0x3013
 #define VG_USERREQ__PTHREAD_KILL            0x3014
+#define VG_USERREQ__PTHREAD_YIELD           0x3015
 
 /* Cosmetic ... */
 #define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
index 572f33aea0489b08acc3268deed023d58ab0ba0c..46d1c65a7949188e2c0faef47c58ff44d4b22212 100644 (file)
@@ -259,6 +259,17 @@ int pthread_attr_destroy(pthread_attr_t *attr)
    THREADs
    ------------------------------------------------ */
 
+__attribute__((weak))
+int pthread_yield ( void )
+{
+   int res;
+   ensure_valgrind("pthread_yield");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_YIELD, 0, 0, 0, 0);
+   return 0;
+}
+
+
 int pthread_equal(pthread_t thread1, pthread_t thread2)
 {
    return thread1 == thread2 ? 1 : 0;
index 01c299e2a9844ea4429219df7bef30e5f8f8d024..1458dc2fa4b3e513917bf7f2a015929cc4bf64bd 100644 (file)
@@ -252,8 +252,6 @@ __attribute__((weak)) void pthread_spin_trylock ( void )
                       { vgPlain_unimp("pthread_spin_trylock"); }
 __attribute__((weak)) void pthread_spin_unlock ( void )
                       { vgPlain_unimp("pthread_spin_unlock"); }
-__attribute__((weak)) void pthread_yield ( void )
-                      { vgPlain_unimp("pthread_yield"); }
 
 
 /*--------------------------------------------------------------------*/
index 57d687d5f806e228d794ecb5443d8b62dfb054f2..1c6dfede1dedb1b171a7d5f305b6f7fea411ad05 100644 (file)
@@ -1542,6 +1542,20 @@ void cleanup_after_thread_exited ( ThreadId tid )
 }
 
 
+static
+void do_pthread_yield ( ThreadId tid )
+{
+   Char msg_buf[100];
+   vg_assert(VG_(is_valid_tid)(tid));
+
+   if (VG_(clo_trace_sched)) {
+      VG_(sprintf)(msg_buf, "yield");
+      print_sched_event(tid, msg_buf);
+   }
+   SET_EDX(tid, 0);
+}
+
+
 static
 void do_pthread_cancel ( ThreadId  tid,
                          pthread_t tid_cancellee )
@@ -2672,6 +2686,12 @@ void do_nontrivial_clientreq ( ThreadId tid )
          do_pthread_kill ( tid, arg[1], arg[2] );
         break;
 
+      case VG_USERREQ__PTHREAD_YIELD:
+         do_pthread_yield ( tid );
+         /* because this is classified as a non-trivial client
+            request, the scheduler should now select a new thread to
+            run. */
+        break;
 
       case VG_USERREQ__MAKE_NOACCESS:
       case VG_USERREQ__MAKE_WRITABLE:
index 93a79cfea5e4da24177429641293098cd439349a..796a0334dbd71d5257e69f8e08e32543c2b56caf 100644 (file)
@@ -28,4 +28,4 @@ EXTRA_DIST = \
        bt_everything.c bt_literal.c \
        pth_threadpool.c pth_specific.c pth_mutexspeed.c malloc3.c \
        pth_once.c weirdioctl.c pth_signal1.c pth_signal2.c \
-       discard.c pth_semaphore1.c new_override.cpp
+       discard.c pth_semaphore1.c new_override.cpp pth_yield.c
diff --git a/tests/pth_yield.c b/tests/pth_yield.c
new file mode 100644 (file)
index 0000000..0b708ba
--- /dev/null
@@ -0,0 +1,44 @@
+
+#include <stdio.h>
+#include <assert.h>
+
+#define __USE_GNU
+#include <pthread.h>
+
+void do_one_thing ( void* v )
+{
+  int i, j, res;
+  for (i = 0; i < 10; i++) {
+    for (j = 0; j < 10; j++) {
+       printf("a "); fflush(stdout);
+    }
+    printf("\naaaaaaa-yielding\n");
+    res = pthread_yield();
+    assert(res == 0);
+  }
+}
+
+void do_another_thing ( void* v )
+{
+  int i, j, res;
+  for (i = 0; i < 10; i++) {
+    for (j = 0; j < 10; j++) {
+       printf("b "); fflush(stdout);
+    }
+    printf("\nbbbbbbb-yielding\n");
+    res = pthread_yield();
+    assert(res == 0);
+  }
+}
+
+
+int main ( void )
+{
+  pthread_t t1, t2;
+  pthread_create( &t1, NULL, (void*)do_one_thing, NULL );
+  pthread_create( &t2, NULL, (void*)do_another_thing, NULL );
+  pthread_join(t1, NULL);
+  pthread_join(t2, NULL);
+  printf("bye!\n");
+  return 0;
+}
index cdcd1caa3b15d60cccf2184bcfff979a62eb5ca7..692a48c528f0e91ecf9f1c0f03355b8f415fef73 100644 (file)
@@ -436,6 +436,7 @@ extern Bool  VG_(is_empty_arena) ( ArenaId aid );
 #define VG_USERREQ__PTHREAD_SIGMASK         0x3012
 #define VG_USERREQ__SIGWAIT                 0x3013
 #define VG_USERREQ__PTHREAD_KILL            0x3014
+#define VG_USERREQ__PTHREAD_YIELD           0x3015
 
 /* Cosmetic ... */
 #define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
index 572f33aea0489b08acc3268deed023d58ab0ba0c..46d1c65a7949188e2c0faef47c58ff44d4b22212 100644 (file)
@@ -259,6 +259,17 @@ int pthread_attr_destroy(pthread_attr_t *attr)
    THREADs
    ------------------------------------------------ */
 
+__attribute__((weak))
+int pthread_yield ( void )
+{
+   int res;
+   ensure_valgrind("pthread_yield");
+   VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
+                           VG_USERREQ__PTHREAD_YIELD, 0, 0, 0, 0);
+   return 0;
+}
+
+
 int pthread_equal(pthread_t thread1, pthread_t thread2)
 {
    return thread1 == thread2 ? 1 : 0;
index 01c299e2a9844ea4429219df7bef30e5f8f8d024..1458dc2fa4b3e513917bf7f2a015929cc4bf64bd 100644 (file)
@@ -252,8 +252,6 @@ __attribute__((weak)) void pthread_spin_trylock ( void )
                       { vgPlain_unimp("pthread_spin_trylock"); }
 __attribute__((weak)) void pthread_spin_unlock ( void )
                       { vgPlain_unimp("pthread_spin_unlock"); }
-__attribute__((weak)) void pthread_yield ( void )
-                      { vgPlain_unimp("pthread_yield"); }
 
 
 /*--------------------------------------------------------------------*/
index 57d687d5f806e228d794ecb5443d8b62dfb054f2..1c6dfede1dedb1b171a7d5f305b6f7fea411ad05 100644 (file)
@@ -1542,6 +1542,20 @@ void cleanup_after_thread_exited ( ThreadId tid )
 }
 
 
+static
+void do_pthread_yield ( ThreadId tid )
+{
+   Char msg_buf[100];
+   vg_assert(VG_(is_valid_tid)(tid));
+
+   if (VG_(clo_trace_sched)) {
+      VG_(sprintf)(msg_buf, "yield");
+      print_sched_event(tid, msg_buf);
+   }
+   SET_EDX(tid, 0);
+}
+
+
 static
 void do_pthread_cancel ( ThreadId  tid,
                          pthread_t tid_cancellee )
@@ -2672,6 +2686,12 @@ void do_nontrivial_clientreq ( ThreadId tid )
          do_pthread_kill ( tid, arg[1], arg[2] );
         break;
 
+      case VG_USERREQ__PTHREAD_YIELD:
+         do_pthread_yield ( tid );
+         /* because this is classified as a non-trivial client
+            request, the scheduler should now select a new thread to
+            run. */
+        break;
 
       case VG_USERREQ__MAKE_NOACCESS:
       case VG_USERREQ__MAKE_WRITABLE: