[openrtm-commit:02675] r964 - in trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src: RTMExamples_scripts jp/go/aist/rtm/RTC jp/go/aist/rtm/RTC/executionContext jp/go/aist/rtm/RTC/util
openrtm @ openrtm.org
openrtm @ openrtm.org
2017年 7月 13日 (木) 10:57:06 JST
Author: t-katami
Date: 2017-07-13 10:57:06 +0900 (Thu, 13 Jul 2017)
New Revision: 964
Added:
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityLinux.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityWindows.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ICPUAffinity.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Kernel32.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Libc.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/cpu_set_t.java
Modified:
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/RTMExamples_scripts/search_classpath.func
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/Manager.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/RTObject_impl.java
trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/executionContext/PeriodicExecutionContext.java
Log:
[incompat,->RELENG_1_2] CPU affinity setting has been added. refs #3713
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/RTMExamples_scripts/search_classpath.func
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/RTMExamples_scripts/search_classpath.func 2017-07-11 08:31:38 UTC (rev 963)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/RTMExamples_scripts/search_classpath.func 2017-07-13 01:57:06 UTC (rev 964)
@@ -1,7 +1,9 @@
get_classpath()
{
FILE1=`ls ${RTM_JAVA_ROOT}/jar/OpenRTM*`
- FILE2=`ls ${RTM_JAVA_ROOT}/jar/commons-cli*`
- CLASSPATH=.:$FILE1:$FILE2
+ FILE2=`ls ${RTM_JAVA_ROOT}/lib/commons-cli*`
+ FILE3=`ls ${RTM_JAVA_ROOT}/lib/jna-?.?.?.jar`
+ FILE4=`ls ${RTM_JAVA_ROOT}/lib/jna-platform-*.jar`
+ CLASSPATH=.:$FILE1:$FILE2:$FILE3:$FILE4:${RTM_JAVA_ROOT}/bin
echo ${CLASSPATH}
}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityLinux.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityLinux.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityLinux.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,127 @@
+package jp.go.aist.rtm.RTC;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+
+import com.sun.jna.Platform;
+
+import jp.go.aist.rtm.RTC.util.cpu_set_t;
+import jp.go.aist.rtm.RTC.util.Libc;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+
+
+ /**
+ * {@.ja CPU affinity Class For Linux }
+ * {@.en CPU affinity Class For Linux }
+ *
+ */
+public class CPUAffinityLinux implements ICPUAffinity {
+
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ *
+ *
+ */
+ public CPUAffinityLinux(){
+ rtcout = new Logbuf("CPUAffinityLinux");
+ }
+
+ /**
+ * {@.ja プロセスのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト(ビット表現)}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ @Override
+ public boolean setProcessAffinity(BitSet cpu_set){
+ rtcout.println(Logbuf.DEBUG, "setProcessAffinity");
+ rtcout.println(Logbuf.DEBUG, "cpu_set:" + cpu_set.isEmpty());
+ final Libc lib = Libc.INSTANCE;
+ final int pid = lib.getpid();
+ rtcout.println(Logbuf.DEBUG, "pid:" + pid);
+ final cpu_set_t cpuset = new cpu_set_t();
+ final int size = cpu_set_t.SIZE_OF_CPU_SET_T;
+ rtcout.println(Logbuf.DEBUG, "size:" + size);
+ final long[] bits = cpu_set.toLongArray();
+ for (int i = 0; i < bits.length; i++) {
+ rtcout.println(Logbuf.DEBUG, "bit[" + i + "]:"+bits[i]);
+ rtcout.println(Logbuf.DEBUG, "Platform64:"+Platform.is64Bit());
+ if (Platform.is64Bit()) {
+ cpuset.__bits[i].setValue(bits[i]);
+ } else {
+ cpuset.__bits[i * 2].setValue(bits[i] & 0xFFFFFFFFL);
+ cpuset.__bits[i * 2 + 1].setValue((bits[i] >>> 32) & 0xFFFFFFFFL);
+ }
+ }
+
+ if (lib.sched_setaffinity(pid, size, cpuset) != 0) {
+ rtcout.println(Logbuf.DEBUG, "false");
+ return false;
+ }
+ else{
+ rtcout.println(Logbuf.DEBUG, "true");
+ return true;
+ }
+ }
+ /**
+ * {@.ja スレッドのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ @Override
+ public boolean setThreadAffinity(ArrayList<Integer> cpu_num_list){
+ final int SYS_gettid = Platform.is64Bit() ? 186 : 224;
+
+ BitSet cpu_set = new BitSet();
+ cpu_set.clear();
+
+ for(int ic=0;ic<cpu_num_list.size();++ic){
+ int num = cpu_num_list.get(ic).intValue();
+ cpu_set.set(num);
+ }
+ final Libc lib = Libc.INSTANCE;
+ int tid = lib.syscall(SYS_gettid);
+ rtcout.println(Logbuf.DEBUG, "tid:" + tid);
+
+ final cpu_set_t cpuset = new cpu_set_t();
+ final int size = cpu_set_t.SIZE_OF_CPU_SET_T;
+ final long[] bits = cpu_set.toLongArray();
+ for (int ic = 0; ic < bits.length; ic++) {
+ if (Platform.is64Bit()) {
+ cpuset.__bits[ic].setValue(bits[ic]);
+ } else {
+ cpuset.__bits[ic * 2].setValue(bits[ic] & 0xFFFFFFFFL);
+ cpuset.__bits[ic * 2 + 1].setValue((bits[ic] >>> 32) & 0xFFFFFFFFL);
+ }
+ }
+
+
+ if (lib.sched_setaffinity(tid, size, cpuset) != 0) {
+ return false;
+ }
+ else{
+ return true;
+ }
+ }
+ /**
+ * {@.ja Logging用フォーマットオブジェクト}
+ * {@.en Format object for Logging}
+ */
+ protected Logbuf rtcout;
+}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityWindows.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityWindows.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/CPUAffinityWindows.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,148 @@
+package jp.go.aist.rtm.RTC;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+
+import com.sun.jna.Platform;
+import com.sun.jna.platform.win32.WinDef;
+import com.sun.jna.ptr.LongByReference;
+
+import jp.go.aist.rtm.RTC.util.cpu_set_t;
+import jp.go.aist.rtm.RTC.util.Kernel32;
+import jp.go.aist.rtm.RTC.log.Logbuf;
+
+ /**
+ * {@.ja CPU affinity Class For Windows }
+ * {@.en CPU affinity Class For Windows }
+ *
+ */
+public class CPUAffinityWindows implements ICPUAffinity {
+
+ /**
+ * {@.ja コンストラクタ}
+ * {@.en Constructor}
+ *
+ *
+ */
+ public CPUAffinityWindows(){
+ rtcout = new Logbuf("CPUAffinityWindows");
+ }
+
+ /**
+ * {@.ja プロセスのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト(ビット表現)}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ @Override
+ public boolean setProcessAffinity(BitSet cpu_set){
+ rtcout.println(Logbuf.DEBUG, "setProcessAffinity");
+ rtcout.println(Logbuf.DEBUG, "cpu_set:" + cpu_set.isEmpty());
+ final int pid = Kernel32.INSTANCE.GetCurrentProcess();
+ rtcout.println(Logbuf.DEBUG, "pid:" + pid);
+ //System.out.println("pid:" + Kernel32.INSTANCE.GetCurrentProcessId());
+
+ //PROCESS_QUERY_INFORMATION(0x400)
+ //PROCESS_SET_INFORMATION(0x200)
+ Kernel32.INSTANCE.OpenProcess(0x0600, false, pid);
+
+ WinDef.DWORD aff;
+ long[] longs = cpu_set.toLongArray();
+ switch (longs.length) {
+ case 0:
+ aff = new WinDef.DWORD(0);
+ break;
+ case 1:
+ aff = new WinDef.DWORD(longs[0]);
+ break;
+ default:
+ aff = new WinDef.DWORD(longs[0]);
+ rtcout.println(Logbuf.DEBUG, "Windows API does not support "
+ + "more than 64 CPUs for thread affinity");
+ }
+
+ Kernel32.INSTANCE.SetProcessAffinityMask(pid, aff);
+ final LongByReference cpuset1 = new LongByReference(0);
+ final LongByReference cpuset2 = new LongByReference(0);
+ int result = Kernel32.INSTANCE.GetProcessAffinityMask(pid,
+ cpuset1,
+ cpuset2);
+ long[] longs_temp = new long[1];
+ longs_temp[0] = cpuset1.getValue();
+ if (BitSet.valueOf(longs_temp) != cpu_set) {
+ rtcout.println(Logbuf.DEBUG, "false");
+ return false;
+ }
+ else{
+ rtcout.println(Logbuf.DEBUG, "true");
+ return true;
+ }
+ }
+ /**
+ * {@.ja スレッドのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ @Override
+ public boolean setThreadAffinity(ArrayList<Integer> cpu_num_list){
+ rtcout.println(Logbuf.DEBUG, "setThreadAffinity");
+
+ BitSet cpu_set = new BitSet();
+ cpu_set.clear();
+
+ for(int ic=0;ic<cpu_num_list.size();++ic){
+ int num = cpu_num_list.get(ic).intValue();
+ cpu_set.set(num);
+ }
+ rtcout.println(Logbuf.DEBUG, "cpu_set:" + cpu_set.isEmpty());
+
+ final int pid = Kernel32.INSTANCE.GetCurrentThread();
+ rtcout.println(Logbuf.DEBUG, "pid:" + pid);
+ //System.out.println("pid:" + Kernel32.INSTANCE.GetCurrentThreadId());
+
+ WinDef.DWORD aff;
+ long[] longs = cpu_set.toLongArray();
+ switch (longs.length) {
+ case 0:
+ aff = new WinDef.DWORD(0);
+ break;
+ case 1:
+ aff = new WinDef.DWORD(longs[0]);
+ break;
+ default:
+ aff = new WinDef.DWORD(longs[0]);
+ rtcout.println(Logbuf.DEBUG, "Windows API does not support "
+ + "more than 64 CPUs for thread affinity");
+ }
+
+ WinDef.DWORD result = Kernel32.INSTANCE.SetThreadAffinityMask(pid, aff);
+ if (result != aff) {
+ rtcout.println(Logbuf.DEBUG, "false");
+ return false;
+ }
+ else{
+ rtcout.println(Logbuf.DEBUG, "true");
+ return true;
+ }
+ }
+ /**
+ * {@.ja Logging用フォーマットオブジェクト}
+ * {@.en Format object for Logging}
+ */
+ protected Logbuf rtcout;
+}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ICPUAffinity.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ICPUAffinity.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/ICPUAffinity.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,43 @@
+package jp.go.aist.rtm.RTC;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.lang.Integer;
+
+ /**
+ * {@.ja CPU affinity用インターフェイス}
+ * {@.en Interface for CPU affinity}
+ *
+ *
+ */
+public interface ICPUAffinity {
+ /**
+ * {@.ja プロセスのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト(ビット表現)}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ public boolean setProcessAffinity(BitSet cpu_set);
+
+ /**
+ * {@.ja スレッドのCPUアフィニティを設定}
+ * {@.en Setting the CPU affinity of a process}
+ *
+ * <p>
+ * @param cpu_set
+ * {@.ja CPU番号のリスト}
+ * {@.en The list in which the number of the CPU is stocked}
+ *
+ * @return
+ * {@.ja 結果(成功:true,失敗:false)}
+ * {@.en Setup result (Successful:true, Failed:false)}
+ */
+ public boolean setThreadAffinity(ArrayList<Integer> cpu_num_list);
+}
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/Manager.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/Manager.java 2017-07-11 08:31:38 UTC (rev 963)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/Manager.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -11,6 +11,7 @@
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.BitSet;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.FileHandler;
@@ -1873,6 +1874,7 @@
"exec_cxt.activation_timeout",
"exec_cxt.deactivation_timeout",
"exec_cxt.reset_timeout",
+ "exec_cxt.cpu_affinity",
"logger.enable",
"logger.log_level",
"naming.enable",
@@ -3774,9 +3776,47 @@
PeriodicExecutionContext.PeriodicExecutionContextInit(this);
ExtTrigExecutionContext.ExtTrigExecutionContextInit(this);
OpenHRPExecutionContext.OpenHRPExecutionContextInit(this);
-
+ initCpuAffinity();
return true;
}
+ /**
+ * {@.ja スレッドの CPU affinity マスクを設定・取得する}
+ * {@.en et and get a thread's CPU affinity mask}
+ *
+ */
+ protected void initCpuAffinity() {
+ rtcout.println(Logbuf.TRACE, "initCpuAffinity()");
+ Properties node = m_config.findNode("manager.cpu_affinity");
+ if (node == null) {
+ return;
+ }
+ String affinity_str = m_config.getProperty("manager.cpu_affinity");
+
+ rtcout.println(Logbuf.DEBUG, "CPU affinity property: "+ affinity_str);
+
+ String[] tmp = affinity_str.split(",");
+ String osname = System.getProperty("os.name").toLowerCase();
+ rtcout.println(Logbuf.DEBUG, "os.name: "+ osname);
+ ICPUAffinity CPUAffinity;
+ if(osname.startsWith("windows")){
+ CPUAffinity = new CPUAffinityWindows();
+ }
+ else{
+ CPUAffinity = new CPUAffinityLinux();
+ }
+
+ ArrayList<Integer> cpu_num = new ArrayList<Integer>();
+ BitSet cpu_set = new BitSet();
+ cpu_set.clear();
+
+ rtcout.println(Logbuf.DEBUG, "cpu_num: ");
+ for(int ic=0;ic<tmp.length;++ic){
+ int num = Integer.parseInt(tmp[ic]);
+ rtcout.println(Logbuf.DEBUG, " " + num);
+ cpu_set.set(num);
+ }
+ CPUAffinity.setProcessAffinity(cpu_set);
+ }
/**
* {@.ja PeriodicECSharedComposite の初期化。}
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/RTObject_impl.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/RTObject_impl.java 2017-07-11 08:31:38 UTC (rev 963)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/RTObject_impl.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -6452,6 +6452,7 @@
"activation_timeout",
"deactivation_timeout",
"reset_timeout",
+ "cpu_affinity",
""
};
Properties node = m_properties.findNode("exec_cxt");
@@ -6627,65 +6628,134 @@
* {@.en creating, initializing and binding context}
*/
protected ReturnCode_t createContexts(ArrayList<Properties> ec_args){
- ReturnCode_t ret = ReturnCode_t.RTC_OK;
- Set<String> avail_ec
- = ExecutionContextFactory.instance().getIdentifiers();
- for (int ic=0; ic < ec_args.size(); ++ic) {
- String ec_type = ec_args.get(ic).getProperty("type");
- String ec_name = ec_args.get(ic).getProperty("name");
- ExecutionContextBase ec = null;
- // if EC's name exists, find existing EC in the factory.
- if (!(ec_name.length()<1) &&
- findExistingEC(ec_args.get(ic), ec) == ReturnCode_t.RTC_OK) {
- rtcout.println(Logbuf.DEBUG, "EC: type="
- + ec_type
- + ", name="
- + ec_name
- + " already exists.");
- }
- // If EC's name is empty or no existing EC, create new EC.
- else { // If EC's name is empty or no existing EC, create new EC.
- boolean find_flag = false;
- Iterator it = avail_ec.iterator();
- while (it.hasNext()) {
- if(it.next().equals(ec_type)){
- find_flag= true;
- break;
- }
- }
- if (!find_flag) {
- rtcout.println(Logbuf.WARN, "EC: "
- + ec_type
- + " is not available.");
- rtcout.println(Logbuf.DEBUG, "Available ECs: "
- + avail_ec.toString());
- continue;
- }
- ExecutionContextFactory<ExecutionContextBase,String> factory
- = ExecutionContextFactory.instance();
- ec = factory.createObject(ec_type);
+ ReturnCode_t ret = ReturnCode_t.RTC_OK;
+ Set<String> avail_ec
+ = ExecutionContextFactory.instance().getIdentifiers();
+ for (int ic=0; ic < ec_args.size(); ++ic) {
+ String ec_type = ec_args.get(ic).getProperty("type");
+ String ec_name = ec_args.get(ic).getProperty("name");
+ ExecutionContextBase ec = null;
+ // if EC's name exists, find existing EC in the factory.
+ if (!(ec_name.length()<1) &&
+ findExistingEC(ec_args.get(ic), ec) == ReturnCode_t.RTC_OK) {
+ rtcout.println(Logbuf.DEBUG, "EC: type="
+ + ec_type
+ + ", name="
+ + ec_name
+ + " already exists.");
+ }
+ // If EC's name is empty or no existing EC, create new EC.
+ else { // If EC's name is empty or no existing EC, create new EC.
+ boolean find_flag = false;
+ Iterator it = avail_ec.iterator();
+ while (it.hasNext()) {
+ if(it.next().equals(ec_type)){
+ find_flag= true;
+ break;
+ }
+ }
+ if (!find_flag) {
+ rtcout.println(Logbuf.WARN, "EC: "
+ + ec_type
+ + " is not available.");
+ rtcout.println(Logbuf.DEBUG, "Available ECs: "
+ + avail_ec.toString());
+ continue;
+ }
+ ExecutionContextFactory<ExecutionContextBase,String> factory
+ = ExecutionContextFactory.instance();
+ ec = factory.createObject(ec_type);
- }
+ }
- // EC factory available but creation failed. Resource full?
- if (ec == null) {
- rtcout.println(Logbuf.ERROR, "EC ("
- + ec_type
- + ") creation failed.");
- rtcout.println(Logbuf.DEBUG, "Available EC list: "
+ // EC factory available but creation failed. Resource full?
+ if (ec == null) {
+ rtcout.println(Logbuf.ERROR, "EC ("
+ + ec_type
+ + ") creation failed.");
+ rtcout.println(Logbuf.DEBUG, "Available EC list: "
+ avail_ec.toString());
- ret = ReturnCode_t.RTC_ERROR;
- continue;
- }
- rtcout.println(Logbuf.DEBUG, "EC ("
- + ec_type
- + ") created.");
+ ret = ReturnCode_t.RTC_ERROR;
+ continue;
+ }
+ rtcout.println(Logbuf.DEBUG, "EC ("
+ + ec_type
+ + ") created.");
- ec.init(ec_args.get(ic));
- m_eclist.add(ec);
- ec.bindComponent(this);
- }
- return ret;
+ ec.init(ec_args.get(ic));
+ m_eclist.add(ec);
+ ec.bindComponent(this);
+ }
+ if (m_eclist.size() == 0) {
+ Properties default_prop = new Properties();
+ default_prop.setDefaults(DefaultConfiguration.default_config);
+ ExecutionContextBase ec = null;
+
+ String ec_type =
+ default_prop.getProperty("exec_cxt.periodic.type");
+ Iterator it = avail_ec.iterator();
+ while (it.hasNext()) {
+ if(it.next().equals(ec_type)){
+ rtcout.println(Logbuf.WARN, "EC: "
+ + ec_type
+ + " is not available.");
+ rtcout.println(Logbuf.DEBUG, "Available ECs: "
+ + it.toString());
+ return ReturnCode_t.RTC_ERROR;
+ }
+ }
+ ExecutionContextFactory<ExecutionContextBase,String> factory
+ = ExecutionContextFactory.instance();
+ ec = factory.createObject(ec_type);
+ if (ec == null) {
+ rtcout.println(Logbuf.ERROR, "EC ("
+ + ec_type
+ + ") creation failed.");
+ rtcout.println(Logbuf.DEBUG, "Available EC list: "
+ + avail_ec.toString());
+ return ReturnCode_t.RTC_ERROR;
+ }
+ Properties default_opts = new Properties();
+ Properties prop = default_prop.findNode("exec_cxt.exec_cxt");
+ if (prop == null) {
+ rtcout.println(Logbuf.WARN, "No default EC options found.");
+ return ReturnCode_t.RTC_ERROR;
+ }
+ default_opts.merge(prop);
+ final String inherited_opts[] =
+ {
+ "sync_transition",
+ "sync_activation",
+ "sync_deactivation",
+ "sync_reset",
+ "transition_timeout",
+ "activation_timeout",
+ "deactivation_timeout",
+ "reset_timeout",
+ "cpu_affinity",
+ ""
+ };
+ Properties node = m_properties.findNode("exec_cxt");
+ if (node == null) {
+ rtcout.println(Logbuf.WARN, "No exec_cxt option found.");
+ return ReturnCode_t.RTC_ERROR;
+ }
+ rtcout.println(Logbuf.DEBUG, "Copying inherited EC options.");
+ for (int ic=0; inherited_opts[ic].length()<1; ++ic) {
+ if (node.findNode(inherited_opts[ic]) != null) {
+ rtcout.println(Logbuf.PARANOID, "Option "
+ + inherited_opts[ic]
+ + " exists.");
+ default_opts.setProperty(inherited_opts[ic],
+ node.getProperty(inherited_opts[ic]));
+ }
+ }
+ ec.init(default_opts);
+ m_eclist.add(ec);
+ ec.bindComponent(this);
+ }
+
+ return ret;
}
/**
* {@.ja マネージャオブジェクト}
Modified: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/executionContext/PeriodicExecutionContext.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/executionContext/PeriodicExecutionContext.java 2017-07-11 08:31:38 UTC (rev 963)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/executionContext/PeriodicExecutionContext.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -1,8 +1,12 @@
package jp.go.aist.rtm.RTC.executionContext;
+import java.util.ArrayList;
import java.util.Vector;
import jp.go.aist.rtm.RTC.Manager;
+import jp.go.aist.rtm.RTC.ICPUAffinity;
+import jp.go.aist.rtm.RTC.CPUAffinityLinux;
+import jp.go.aist.rtm.RTC.CPUAffinityWindows;
import jp.go.aist.rtm.RTC.ObjectCreator;
import jp.go.aist.rtm.RTC.ObjectDestructor;
import jp.go.aist.rtm.RTC.RTObjectStateMachine;
@@ -136,6 +140,19 @@
int count = 0 ;
rtcout.println(Logbuf.TRACE, "PeriodicExecutionContext.svc()");
+ if(m_cpu.size()>0) {
+ ICPUAffinity CPUAffinity;
+ String osname = System.getProperty("os.name").toLowerCase();
+ rtcout.println(Logbuf.DEBUG, "os.name: "+ osname);
+ if(osname.startsWith("windows")){
+ CPUAffinity = new CPUAffinityWindows();
+ }
+ else{
+ CPUAffinity = new CPUAffinityLinux();
+ }
+ CPUAffinity.setThreadAffinity(m_cpu);
+ }
+
do {
invokeWorkerPreDo();
synchronized (m_workerthread.mutex_) {
@@ -155,9 +172,12 @@
if(count > 1000){
TimeValue t1_w = t1;
TimeValue period_w = period;
- rtcout.println(Logbuf.PARANOID, "Period: " + period.getSec() + " [s]");
- rtcout.println(Logbuf.PARANOID, "Execution: " + t1_w.minus(t0).getSec() + " [s]");
- rtcout.println(Logbuf.PARANOID, "Sleep: " + period_w.minus(t1_w).getSec() + " [s]");
+ rtcout.println(Logbuf.PARANOID, "Period: "
+ + period.getSec() + " [s]");
+ rtcout.println(Logbuf.PARANOID, "Execution: "
+ + t1_w.minus(t0).getSec() + " [s]");
+ rtcout.println(Logbuf.PARANOID, "Sleep: "
+ + period_w.minus(t1_w).getSec() + " [s]");
}
TimeValue delta = t1.minus(t0);
if( !m_nowait && period.toDouble() > delta.toDouble())
@@ -1540,6 +1560,7 @@
protected boolean m_nowait;
protected Thread m_thread = null;
protected boolean ticked_;
+ protected ArrayList<Integer> m_cpu = new ArrayList<Integer>();
/**
* <p>このExecutionContextを生成するFactoryクラスを
@@ -1661,6 +1682,10 @@
+ ", Timeout = "+m_resetTimeout.toDouble());
// Setting given Properties to EC's profile::properties
setProperties(props);
+
+ setCpuAffinity(props);
+ rtcout.println(Logbuf.DEBUG, "init() done");
+
}
@@ -1955,4 +1980,31 @@
public void invokeWorkerPreDo() { m_worker.invokeWorkerPreDo(); }
public void invokeWorkerDo() { m_worker.invokeWorkerDo(); }
public void invokeWorkerPostDo() { m_worker.invokeWorkerPostDo(); }
+
+ /**
+ * {@.ja 終了処理用コールバック関数。}
+ * {@.en Callback function to finalize}
+ *
+ */
+ public void setCpuAffinity(Properties props){
+ rtcout.println(Logbuf.TRACE, "setCpuAffinity()");
+ String affinity_str = props.getProperty("cpu_affinity");
+
+ if(!affinity_str.isEmpty()) {
+ rtcout.println(Logbuf.DEBUG, "CPU affinity property: "
+ + affinity_str);
+ String[] tmp = affinity_str.split(",");
+ m_cpu.clear();
+ for (int ic=0; ic < tmp.length; ++ic) {
+ try {
+ m_cpu.add(Integer.parseInt(tmp[ic]));
+ rtcout.println(Logbuf.DEBUG, "CPU affinity int value: "
+ + tmp[ic]
+ + " add.");
+ }
+ catch(Exception ex){
+ }
+ }
+ }
+ }
}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Kernel32.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Kernel32.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Kernel32.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,59 @@
+package jp.go.aist.rtm.RTC.util;
+import com.sun.jna.Library;
+import com.sun.jna.platform.win32.WinNT;
+import com.sun.jna.platform.win32.WinDef;
+
+
+import com.sun.jna.Native;
+import com.sun.jna.Pointer;
+import com.sun.jna.PointerType;
+import com.sun.jna.win32.StdCallLibrary;
+import com.sun.jna.win32.W32APIOptions;
+
+
+/**
+ * {@.ja Kernel32 クラス}
+ * {@.en Kernel32 class}
+ * <p>
+ * {@.ja WindowsAPIラッパクラス
+ * JNAを使用してWindowsAPIを呼び出す}
+ * {@.en WindowsAPI wrappers class
+ * Calls windowsAPI via JNA.}
+ *
+ */
+public interface Kernel32 extends Library,StdCallLibrary, WinNT {
+ Kernel32 INSTANCE = (Kernel32)Native.loadLibrary("kernel32" ,
+ Kernel32.class);
+
+ int GetProcessAffinityMask(
+ final int pid,
+ final PointerType lpProcessAffinityMask,
+ final PointerType lpSystemAffinityMask
+ );
+ WinDef.DWORD SetThreadAffinityMask(
+ final int pid,
+ final WinDef.DWORD lpProcessAffinityMask
+ );
+
+ boolean SetProcessAffinityMask(
+ final int pid,
+ final WinDef.DWORD dwProcessAffinityMask
+ );
+
+ int GetCurrentThread();
+
+ int GetCurrentProcess();
+
+ int GetCurrentThreadId();
+
+ int GetCurrentProcessId();
+
+ HANDLE OpenProcess(
+ int dwDesiredAccess, // アクセスフラグ
+ boolean bInheritHandle, // ハンドルの継承オプション
+ int dwProcessId // プロセス識別子
+ );
+ boolean CloseHandle(
+ HANDLE hObject // オブジェクトのハンドル
+ );
+}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Libc.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Libc.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/Libc.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,21 @@
+package jp.go.aist.rtm.RTC.util;
+import com.sun.jna.Library;
+import com.sun.jna.Native;
+
+
+ /**
+ * {@.ja LinuxのCライブラリ用インターフェイス}
+ * {@.en Interface for C library}
+ *
+ *
+ */
+public interface Libc extends Library {
+ Libc INSTANCE = (Libc) Native.loadLibrary("libc", Libc.class);
+
+ int getpid();
+ int sched_setaffinity(final int pid,
+ final int cpusetsize,
+ final cpu_set_t cpuset);
+ int syscall(int number, Object... args);
+
+}
Added: trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/cpu_set_t.java
===================================================================
--- trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/cpu_set_t.java (rev 0)
+++ trunk/OpenRTM-aist-Java/jp.go.aist.rtm.RTC/src/jp/go/aist/rtm/RTC/util/cpu_set_t.java 2017-07-13 01:57:06 UTC (rev 964)
@@ -0,0 +1,65 @@
+package jp.go.aist.rtm.RTC.util;
+import com.sun.jna.Library;
+import com.sun.jna.Structure;
+import com.sun.jna.NativeLong;
+
+import java.util.Arrays;
+import java.util.List;
+
+ /**
+ * {@.ja cpu_set_t構造体}
+ * {@.en cpu_set_t structure}
+ *
+ *
+ */
+public class cpu_set_t extends Structure {
+ static final int __CPU_SETSIZE = 1024;
+ static final int __NCPUBITS = 8 * NativeLong.SIZE;
+ public static final int SIZE_OF_CPU_SET_T = (__CPU_SETSIZE / __NCPUBITS) * NativeLong.SIZE;
+ static List<String> FIELD_ORDER = Arrays.asList("__bits");
+ public NativeLong[] __bits = new NativeLong[__CPU_SETSIZE / __NCPUBITS];
+
+ public cpu_set_t() {
+ for (int i = 0; i < __bits.length; i++) {
+ __bits[i] = new NativeLong(0);
+ }
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static void __CPU_ZERO(cpu_set_t cpuset) {
+ for (NativeLong bits : cpuset.__bits) {
+ bits.setValue(0l);
+ }
+ }
+
+ public static int __CPUELT(int cpu) {
+ return cpu / __NCPUBITS;
+ }
+
+ public static long __CPUMASK(int cpu) {
+ return 1l << (cpu % __NCPUBITS);
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static void __CPU_SET(int cpu, cpu_set_t cpuset) {
+ cpuset.__bits[__CPUELT(cpu)].setValue(
+ cpuset.__bits[__CPUELT(cpu)].longValue() | __CPUMASK(cpu));
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static void __CPU_CLR(int cpu, cpu_set_t cpuset) {
+ cpuset.__bits[__CPUELT(cpu)].setValue(
+ cpuset.__bits[__CPUELT(cpu)].longValue() & ~__CPUMASK(cpu));
+ }
+
+ @SuppressWarnings({"UnusedDeclaration"})
+ public static boolean __CPU_ISSET(int cpu, cpu_set_t cpuset) {
+ return (cpuset.__bits[__CPUELT(cpu)].longValue() & __CPUMASK(cpu)) != 0;
+ }
+
+ @Override
+ protected List getFieldOrder() {
+ return FIELD_ORDER;
+ }
+}
+
More information about the openrtm-commit
mailing list