Hello,

I would like to know if you can consider the inclusion of the attached
element to the main click source repository ? It's a very simple element
that allow to enforce a static thread to cpu pinning when running Click
multithread. We are using that in a project designing multicore software routers
experiments involving a cache hierarchy scheduler.

There was already some cpu affinity setting in the click source code in
the linuxmodule/sched.cc file, function click_sched but it was using
a single parameter from the linux kernel module to allocate all threads
to the same CPU. 

With this element, you can specify on which CPU each threads should go
without having to play with userland tools like taskset and retrieve the
pid of the actual thread as you specify the thread id from the click 
script. 

Thanks,

Hoerdt Mickael
Index: click-git-20080715-dom0/elements/linuxmodule/cpupin.cc
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ click-git-20080715-dom0/elements/linuxmodule/cpupin.cc	2009-03-12 18:24:20.000000000 +0000
@@ -0,0 +1,90 @@
+/*
+ * CpuPin.{cc,hh} -- Pin Threads to CPUs
+ * Hoerdt Mickael
+ *
+ * Copyright (c) 2009 Lancaster University
+ *
+ * This software is being provided by the copyright holders under the GNU
+ * General Public License, either version 2 or, at your discretion, any later
+ * version. For more information, see the `COPYRIGHT' file in the source
+ * distribution.
+ */
+
+#include <click/config.h>
+#include "cpupin.hh"
+#include <click/glue.hh>
+#include <click/confparse.hh>
+#include <click/nameinfo.hh>
+#include <click/error.hh>
+#include <click/task.hh>
+#include <click/routerthread.hh>
+#include <click/router.hh>
+#include <click/master.hh>
+
+
+#include <click/cxxprotect.h>
+CLICK_CXX_PROTECT
+#include <linux/sched.h>
+#include <linux/cpumask.h>
+#include <linux/cpuset.h>
+CLICK_CXX_UNPROTECT
+#include <click/cxxunprotect.h>
+
+
+CLICK_DECLS
+
+CpuPin::CpuPin()
+{
+}
+
+CpuPin::~CpuPin()
+{
+}
+
+int
+CpuPin::configure(Vector<String> &conf, ErrorHandler *errh)
+{
+    int thread_id;
+    int cpu;
+    
+    int before = errh->nerrors();
+    for (int i = 0; i < conf.size(); i++) {
+        if (cp_va_space_kparse(conf[i], this, errh,
+			       "THREAD", cpkP+cpkM, cpInteger, &thread_id,
+			       "CPU", cpkP, cpInteger, &cpu,
+			       cpEnd) < 0)
+            return -1;
+             
+            
+            if (thread_id >= _thread_affinities.size())
+	            _thread_affinities.resize(thread_id + 1, 0);
+	        if (thread_id < -1 || thread_id >= master()->nthreads()) {
+	            errh->warning("thread preference %d out of range", thread_id);
+	            thread_id = (thread_id < 0 ? -1 : 0);
+            if (cpu < num_possible_cpus() && cpu_online(cpu))
+	            errh->warning("warning: cpu %d for thread %d offline\n", cpu,thread_id);
+	        }
+            _thread_affinities[thread_id] = cpu;
+      
+    
+    }
+    return (errh->nerrors() == before ? 0 : -1);
+}
+
+int
+CpuPin::initialize(ErrorHandler *)
+{
+    for(int i=0;i<_thread_affinities.size();i++) {
+        int thread_id=i;
+        int cpu = _thread_affinities[thread_id];
+        click_chatter("thread %d cpu %d\n", thread_id,cpu);
+        Master *m = router()->master();
+        RouterThread *thread = m->thread(thread_id);
+        set_cpus_allowed(thread->linux_task(), cpumask_of_cpu(cpu));
+    }
+
+    return 0;
+}
+
+CLICK_ENDDECLS
+EXPORT_ELEMENT(CpuPin)
Index: click-git-20080715-dom0/elements/linuxmodule/cpupin.hh
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ click-git-20080715-dom0/elements/linuxmodule/cpupin.hh	2009-03-12 18:26:42.000000000 +0000
@@ -0,0 +1,33 @@
+#ifndef CLICK_CpuPin_HH
+#define CLICK_CpuPin_HH
+#include <click/element.hh>
+#include <click/vector.hh>
+#include <click/hashtable.hh>
+#include <click/sync.hh>
+CLICK_DECLS
+
+/*
+ * =c
+ * CpuPin(THREAD_ID CPU_ID,...,THREAD_ID CPU_ID)
+ * =s threads
+ * Pin Threads to CPUs to enforce a specific thread
+ * to CPU allocation on multicore machines
+ * =d
+ */
+
+class CpuPin : public Element {
+
+public:
+  
+  CpuPin();
+  ~CpuPin();
+  Vector<int> _thread_affinities;
+  const char *class_name() const	{ return "CpuPin"; }
+  int configure_phase() const           { return  CONFIGURE_PHASE_LAST; } 
+  int configure(Vector<String> &, ErrorHandler *);
+  int initialize(ErrorHandler *);
+  
+};
+
+CLICK_ENDDECLS
+#endif
Index: click-git-20080715-dom0/include/click/routerthread.hh
===================================================================
--- click-git-20080715-dom0.orig/include/click/routerthread.hh	2009-03-12 14:53:14.018822306 +0000
+++ click-git-20080715-dom0/include/click/routerthread.hh	2009-03-12 14:53:52.000000000 +0000
@@ -82,6 +82,9 @@
     struct task_struct *sleeper() const	{ return _linux_task; }
 # endif
 #endif
+# if CLICK_LINUXMODULE
+    struct task_struct *linux_task() const	{ return _linux_task; }
+# endif
 
     unsigned _tasks_per_iter;
     unsigned _iters_per_os;
_______________________________________________
click mailing list
[email protected]
https://amsterdam.lcs.mit.edu/mailman/listinfo/click

Reply via email to