Skip to content

Commit 13dcd5d

Browse files
committed
Add support for using the current thread id.
1 parent a04717e commit 13dcd5d

File tree

3 files changed

+92
-1
lines changed

3 files changed

+92
-1
lines changed

affinity/src/main/java/net/openhft/affinity/AffinitySupport.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import net.openhft.affinity.impl.WindowsJNAAffinity;
2222
import org.jetbrains.annotations.NotNull;
2323

24+
import java.lang.reflect.Field;
2425
import java.util.logging.Logger;
2526

2627
/**
@@ -61,6 +62,10 @@ public static int getCpu() {
6162
return AFFINITY_IMPL.getCpu();
6263
}
6364

65+
public static int getThreadId() {
66+
return AFFINITY_IMPL.getThreadId();
67+
}
68+
6469
public static boolean isJNAAvailable() {
6570
if (JNAAvailable == null)
6671
try {
@@ -71,4 +76,17 @@ public static boolean isJNAAvailable() {
7176
}
7277
return JNAAvailable;
7378
}
79+
80+
public static void setThreadId() {
81+
try {
82+
int threadId = getThreadId();
83+
final Field tid = Thread.class.getDeclaredField("tid");
84+
tid.setAccessible(true);
85+
final Thread thread = Thread.currentThread();
86+
tid.setLong(thread, threadId);
87+
Logger.getAnonymousLogger().info("Set " + thread.getName() + " to thread id " + threadId);
88+
} catch (Exception e) {
89+
throw new IllegalStateException(e);
90+
}
91+
}
7492
}

affinity/src/main/java/net/openhft/affinity/impl/PosixJNAAffinity.java

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,62 @@ public int getCpu() {
102102
}
103103
}
104104

105+
private static final int PROCESS_ID;
106+
105107
@Override
106108
public int getProcessId() {
107-
return CLibrary.INSTANCE.getpid();
109+
return PROCESS_ID;
110+
}
111+
112+
static {
113+
int processId;
114+
try {
115+
processId = CLibrary.INSTANCE.getpid();
116+
} catch (Exception ignored) {
117+
processId = -1;
118+
}
119+
PROCESS_ID = processId;
108120
}
109121

122+
private final ThreadLocal<Integer> THREAD_ID = new ThreadLocal<Integer>();
123+
110124
@Override
111125
public int getThreadId() {
126+
if (ISLINUX) {
127+
Integer tid = THREAD_ID.get();
128+
if (tid == null)
129+
THREAD_ID.set(tid = CLibrary.INSTANCE.syscall(SYS_gettid, NO_ARGS));
130+
return tid;
131+
}
112132
return -1;
113133
}
114134

135+
private static final boolean ISLINUX = "Linux".equals(System.getProperty("os.name"));
136+
137+
private static final boolean IS64BIT = is64Bit0();
138+
139+
private static final int SYS_gettid = is64Bit() ? 186 : 224;
140+
141+
private static final Object[] NO_ARGS = {};
142+
143+
public static boolean is64Bit() {
144+
return IS64BIT;
145+
}
146+
147+
private static boolean is64Bit0() {
148+
String systemProp;
149+
systemProp = System.getProperty("com.ibm.vm.bitmode");
150+
if (systemProp != null) {
151+
return "64".equals(systemProp);
152+
}
153+
systemProp = System.getProperty("sun.arch.data.model");
154+
if (systemProp != null) {
155+
return "64".equals(systemProp);
156+
}
157+
systemProp = System.getProperty("java.vm.version");
158+
return systemProp != null && systemProp.contains("_64");
159+
}
160+
115161

116162
/**
117163
* @author BegemoT
@@ -131,6 +177,8 @@ int sched_getaffinity(final int pid,
131177
int sched_getcpu() throws LastErrorException;
132178

133179
int getpid() throws LastErrorException;
180+
181+
int syscall(int number, Object... args) throws LastErrorException;
134182
}
135183

136184
static {

affinity/src/test/java/net/openhft/affinity/impl/PosixJNAAffinityTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,13 @@
1616

1717
package net.openhft.affinity.impl;
1818

19+
import net.openhft.affinity.AffinitySupport;
1920
import net.openhft.affinity.IAffinity;
2021
import org.junit.Assume;
2122
import org.junit.BeforeClass;
23+
import org.junit.Test;
24+
25+
import static org.junit.Assert.assertTrue;
2226

2327
/**
2428
* @author peter.lawrey
@@ -33,4 +37,25 @@ public static void checkJniLibraryPresent() {
3337
public IAffinity getImpl() {
3438
return PosixJNAAffinity.INSTANCE;
3539
}
40+
41+
@Test
42+
public void testGettid() {
43+
System.out.println("pid=" + PosixJNAAffinity.INSTANCE.getProcessId());
44+
System.out.println("tid=" + PosixJNAAffinity.INSTANCE.getThreadId());
45+
AffinitySupport.setThreadId();
46+
47+
for (int j = 0; j < 10; j++) {
48+
final int runs = 5000;
49+
long tid = 0;
50+
long time = 0;
51+
for (int i = 0; i < runs; i++) {
52+
long start = System.nanoTime();
53+
tid = Thread.currentThread().getId();
54+
time += System.nanoTime() - start;
55+
assertTrue(tid > 0);
56+
assertTrue(tid < 1 << 16);
57+
}
58+
System.out.printf("gettid took an average of %,d ns, tid=%d%n", time / runs, tid);
59+
}
60+
}
3661
}

0 commit comments

Comments
 (0)