[netperf-dev] netperf4 commit notice r120 - branches/glib_migration/src

raj at netperf.org raj at netperf.org
Thu Mar 30 22:44:21 PST 2006


Author: raj
Date: 2006-03-30 22:44:20 -0800 (Thu, 30 Mar 2006)
New Revision: 120

Modified:
   branches/glib_migration/src/netlib.c
   branches/glib_migration/src/netlib.h
   branches/glib_migration/src/netmsg.c
   branches/glib_migration/src/netperf.h
Log:
Code the "launch_pad" routine we will use to assign a "native" thread
id into the test_t of a test_thread launched from the netserver. We
still need to code a routine to allow the main netserver thread to save
its CPU affinity, so when we change to the affinity we want for the 
test thread prior to its launch (so things like thread stacks will be
allocated where we want them) we can come back to where we were.  once
the test thread is in the init state, we'll hit it with a processor
affinity call just to be sure that the affinity it inherited from the
main thread "sticks"  We do all this to get the thread stacks where we
want them, and because there is no architected way to extract the 
native thread_id from a GThread, and GThreads have no affinity calls :(


Modified: branches/glib_migration/src/netlib.c
===================================================================
--- branches/glib_migration/src/netlib.c	2006-03-31 01:07:15 UTC (rev 119)
+++ branches/glib_migration/src/netlib.c	2006-03-31 06:44:20 UTC (rev 120)
@@ -1580,7 +1580,38 @@
   return(rc);
 }
 
+/* this routine exists because there is no architected way to get a
+   "native" thread id out of a GThread.  we need a native thread ID to
+   allow the main netserver thread to bind a test thread to a
+   specified CPU/processor set/locality domain. so, we use the
+   launch_pad routine to allow the newly created thread to store a
+   "pthread_self" into the test structure. the netserver thread, when
+   it see's the test thread is in the idle state can then assign the
+   affinity to the thread. raj 2006-03-30 */
 
+void *
+launch_pad(void *data) {
+  thread_launch_state_t *launch_state;
+  test_t *test;
+
+  launch_state = data;
+  test = launch_state->data_arg;
+
+#ifdef G_THREADS_IMPL_POSIX
+  /* hmm, I wonder if I have to worry about alignment */
+  test->native_thread_id = malloc(sizeof(pthread_t));
+  if (test->native_thread_id) {
+    *(pthread_t *)(test->native_thread_id) = pthread_self();
+  }
+#else
+  test->native_thread_id = NULL;
+#endif
+  /* and now, call the routine we really want to run. at some point we
+     should bring those values onto the stack so we can free the
+     thread_launch_state_t I suppose. */
+  return (launch_state->start_routine)(launch_state->data_arg);
+}
+
 /* I would have used the NETPERF_THREAD_T abstraction, but that would
    make netlib.h dependent on netperf.h and I'm not sure I want to do
    that. raj 2006-03-02 */
@@ -1589,6 +1620,7 @@
 
 {
   int rc;
+  thread_launch_state_t *launch_state;
 
   NETPERF_THREAD_T temp_tid;
 

Modified: branches/glib_migration/src/netlib.h
===================================================================
--- branches/glib_migration/src/netlib.h	2006-03-31 01:07:15 UTC (rev 119)
+++ branches/glib_migration/src/netlib.h	2006-03-31 06:44:20 UTC (rev 120)
@@ -53,7 +53,7 @@
 #include <sys/socket.h>
 #endif
 
-#ifndef WIN32
+#ifndef G_OS_WIN32
 #define SOCKET int
 #endif
 
@@ -140,6 +140,11 @@
   gboolean        first_message;  /* do we await the first message? */
 } global_state_t;
 
+typedef struct thread_launch_state {
+  void *data_arg;                 /* the actual data to be passed */
+  void *(*start_routine)(void *); /* the actual routine to execute */
+} thread_launch_state_t;
+
 extern void netlib_init();
 
 void display_test_hash();

Modified: branches/glib_migration/src/netmsg.c
===================================================================
--- branches/glib_migration/src/netmsg.c	2006-03-31 01:07:15 UTC (rev 119)
+++ branches/glib_migration/src/netmsg.c	2006-03-31 06:44:20 UTC (rev 120)
@@ -874,8 +874,8 @@
   xmlChar   *testid;
   xmlChar   *loc_type;
   xmlChar   *loc_value;
+  thread_launch_state_t *launch_state;
 
-
   NETPERF_DEBUG_ENTRY(debug,where);
 
   if (server->state != server->state_req) {
@@ -930,23 +930,26 @@
                 new_test->test_func);
         fflush(where);
       }
-      rc = launch_thread(&new_test->thread_id,new_test->test_func,new_test);
-      if (debug) {
-        fprintf(where,
-                "test_message: launched thread %d for test\n",
-                new_test->thread_id);
-        fflush(where);
+      launch_state =
+	(thread_launch_state_t *)malloc(sizeof(thread_launch_state_t));
+      if (launch_state) {
+	launch_state->data_arg = new_test;
+	launch_state->start_routine = new_test->test_func;
+	rc = launch_thread(&new_test->thread_id,new_test->test_func,new_test);
+	if (debug) {
+	  fprintf(where,
+		  "test_message: launched thread %d for test\n",
+		  new_test->thread_id);
+	  fflush(where);
+	}
       }
-    }
-    /* Set test thread locality */
-    if (rc == NPE_SUCCESS) {
-      loc_type  = xmlGetProp(test_node,(const xmlChar *)"locality_type");
-      loc_value = xmlGetProp(test_node,(const xmlChar *)"locality_value");
-      if ((loc_type != NULL) && (loc_value != NULL)) {
-        rc = set_thread_locality(new_test, (char *)loc_type, (char *)loc_value);
+      else {
+	rc = NPE_MALLOC_FAILED2;
       }
     }
-    /* wait for test to initialize */
+
+    /* wait for test to initialize, then we will know that it's native
+       thread id has been set in the test_t */
     if (rc == NPE_SUCCESS) {
       while (new_test->new_state == TEST_PREINIT) {
         if (debug) {
@@ -964,6 +967,16 @@
         fflush(where);
       }
     }
+
+    /* now we can set test thread locality */
+    if (rc == NPE_SUCCESS) {
+      loc_type  = xmlGetProp(test_node,(const xmlChar *)"locality_type");
+      loc_value = xmlGetProp(test_node,(const xmlChar *)"locality_value");
+      if ((loc_type != NULL) && (loc_value != NULL)) {
+        rc = set_thread_locality(new_test, (char *)loc_type, (char *)loc_value);
+      }
+    }
+
     if (rc != NPE_SUCCESS) {
       new_test->state  = TEST_ERROR;
       new_test->err_rc = rc;

Modified: branches/glib_migration/src/netperf.h
===================================================================
--- branches/glib_migration/src/netperf.h	2006-03-31 01:07:15 UTC (rev 119)
+++ branches/glib_migration/src/netperf.h	2006-03-31 06:44:20 UTC (rev 120)
@@ -319,6 +319,11 @@
 				   opaque thread id should be we will
 				   have to do some interesting
 				   backflips to deal with them */
+  void      *native_thread_id; /* a pointer to the "native" thread id
+				  of the test thread, used for things
+				  like processor affinity since
+				  GThread doesn't do that sort of
+				  thing :( */
 
   xmlChar   *test_name;        /* the ASCII name of the test being
                                   performed by this test instance. */



More information about the netperf-dev mailing list