Skip to content

Commit 24b5366

Browse files
committed
Added support for setting thread affinity using a description, closes OpenHFT#54
1 parent 9571555 commit 24b5366

2 files changed

Lines changed: 91 additions & 43 deletions

File tree

README.adoc

Lines changed: 90 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,26 @@
22

33
image::/images/Thread-Affinity_line.png[width=20%]
44

5-
=== Version
5+
== Version
66

77
[#image-maven]
88
[caption="", link=https://maven-badges.herokuapp.com/maven-central/net.openhft/affinity]
99
image::https://maven-badges.herokuapp.com/maven-central/net.openhft/affinity/badge.svg[]
1010

11-
=== Overview
11+
== Overview
1212
Lets you bind a thread to a given core, this can improve performance (this library works best on linux).
1313

1414
OpenHFT Java Thread Affinity library
1515

1616
See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java]
1717
for working examples of how to use this library.
1818

19-
==== Wold Wide Usage
19+
=== Wold Wide Usage
2020
http://jrvis.com/red-dwarf/?user=openhft&repo=Java-Thread-Affinity[Thread Affinity usage Heatmap]
2121

22-
==== Changes
22+
=== Changes
2323

24+
* V3.2.0 - Add support for text configuration
2425
* V3.1.1 - Upgraded JNA dependency to 4.4.0
2526
* V2.0.1 - Added getThreadId for the process if of the thread.
2627

@@ -30,7 +31,7 @@ Java-Thread-Affinity will try to use https://github.com/java-native-access/jna[J
3031
to provide access to native thread-handling functions. JNA should be installed on
3132
your system to get the most from this library.
3233

33-
==== JNA version
34+
=== JNA version
3435

3536
Java-Thread-Affinity currently depends on JNA version 4.4.0, which in turn
3637
depends on a version of GLIBC >= 2.14. If your operating system is an old one,
@@ -40,11 +41,11 @@ invoke native functions.
4041
To work around this problem, fork the repository, and override the `<version>` tag
4142
for the artifacts `jna` and `jna-platform` in the project's `pom` file.
4243

43-
==== Installing JNA on Ubuntu
44+
=== Installing JNA on Ubuntu
4445

4546
sudo apt-get install libjna-java
4647

47-
==== Installing JNA on CentOS
48+
=== Installing JNA on CentOS
4849

4950
sudo yum install jna
5051

@@ -77,86 +78,92 @@ To isolate the 1st and 3rd CPU cores (CPU numbers start from 0) on your system,
7778

7879
isolcpus=1,3
7980

80-
==== Acquiring a CPU lock for a thread
81+
== Using AffinityLock
82+
83+
=== Acquiring a CPU lock for a thread
8184
You can acquire a lock for a CPU in the following way:
8285

8386
In Java 6
8487
[source, java]
8588
----
86-
AffinityLock al = AffinityLock.acquireLock();
87-
try {
88-
// do some work locked to a CPU.
89-
} finally {
90-
al.release();
91-
}
89+
AffinityLock al = AffinityLock.acquireLock();
90+
try {
91+
// do some work locked to a CPU.
92+
} finally {
93+
al.release();
94+
}
9295
----
9396

9497
In Java 7 or 8
9598
[source, java]
9699
----
97-
try (AffinityLock al = AffinityLock.acquireLock()) {
98-
// do some work while locked to a CPU.
99-
}
100+
try (AffinityLock al = AffinityLock.acquireLock()) {
101+
// do some work while locked to a CPU.
102+
}
100103
----
101104
You have further options such as
102105

103106
=== Acquiring a CORE lock for a thread
104107
You can reserve a whole core. If you have hyper-threading enabled, this will use one CPU and leave it's twin CPU unused.
105108
[source, java]
106109
----
107-
try (AffinityLock al = AffinityLock.acquireCore()) {
108-
// do some work while locked to a CPU.
109-
}
110+
try (AffinityLock al = AffinityLock.acquireCore()) {
111+
// do some work while locked to a CPU.
112+
}
110113
----
111114
=== Controlling layout
112115
You can chose a layout relative to an existing lock.
113116
[source, java]
114117
----
115-
try (final AffinityLock al = AffinityLock.acquireLock()) {
116-
System.out.println("Main locked");
117-
Thread t = new Thread(new Runnable() {
118-
@Override
119-
public void run() {
120-
try (AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET,
121-
AffinityStrategies.ANY)) {
122-
System.out.println("Thread-0 locked");
123-
}
118+
try (final AffinityLock al = AffinityLock.acquireLock()) {
119+
System.out.println("Main locked");
120+
Thread t = new Thread(new Runnable() {
121+
@Override
122+
public void run() {
123+
try (AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET,
124+
AffinityStrategies.ANY)) {
125+
System.out.println("Thread-0 locked");
124126
}
125-
});
126-
t.start();
127-
}
127+
}
128+
});
129+
t.start();
130+
}
128131
----
129132
In this example, the library will prefer a free CPU on the same Socket as the first thread, otherwise it will pick any free CPU.
130133

131134
=== Getting the thread id.
132135
You can get the current thread id using
133136
[source, java]
134137
----
135-
int threadId = AffinitySupport.getThreadId();
138+
139+
int threadId = AffinitySupport.getThreadId();
136140
----
137141
=== Determining which CPU you are running on.
138142
You can get the current CPU being used by
139143
[source, java]
140144
----
141-
int cpuId = AffinitySupport.getCpu();
145+
146+
int cpuId = AffinitySupport.getCpu();
142147
----
143148
=== Controlling the affinity more directly.
144149
The affinity of the process on start up is
145150
[source, java]
146151
----
147-
long baseAffinity = AffinityLock.BASE_AFFINITY;
152+
153+
long baseAffinity = AffinityLock.BASE_AFFINITY;
148154
----
149155
The available CPU for reservation is
150156
[source, java]
151157
----
152-
long reservedAffinity = AffinityLock.RESERVED_AFFINITY;
158+
long reservedAffinity = AffinityLock.RESERVED_AFFINITY;
153159
----
154160
If you want to get/set the affinity directly you can do
155161
[source, java]
156162
----
157-
long currentAffinity = AffinitySupport.getAffinity();
158-
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.
163+
long currentAffinity = AffinitySupport.getAffinity();
164+
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.
159165
----
166+
160167
=== Debugging affinity state
161168

162169
For a detailed of view of the current affinity state (as seen by the library),
@@ -188,18 +195,59 @@ For an article on how much difference affinity can make and how to use it http:/
188195

189196
== Questions and Answers
190197

191-
=== Question
198+
=== Question: How to lock a specific cpuId
192199
I am currently working on a project related to deadlock detection in multithreaded programs in java. We are trying to run threads on different processors and thus came across your github posts regarding the same. https://github.com/peter-lawrey/Java-Thread-Affinity/wiki/Getting-started
193200
Being a beginner, I have little knowledge and thus need your assistance. We need to know how to run threads on specified cpu number and then switch threads when one is waiting.
194201

195202
=== Answer
196203

197-
Use :
198-
199204
[source, java]
200205
----
201-
AffinityLock.setAffinity (1L << n);
206+
// lock a cpuId
207+
try (AffinityLock lock = AffinityLock.acquireLock(n)) {
208+
209+
}
202210
----
203211

204212
where n is the cpu you want to run the thread on.
205213

214+
OR
215+
216+
[source,java]
217+
----
218+
// lock one of the last CPUs
219+
try (AffinityLock lock = AffinityLock.acquireLockLastMinus(n)) {
220+
221+
}
222+
----
223+
224+
=== Question: how to use a configuration file to set the cpuId
225+
226+
I have the cpuId in a configuration file, how can I set it using a string?
227+
228+
=== Answer: use one fo the following.
229+
230+
[source,java]
231+
----
232+
try (AffinityLock lock = AffinityLock.acquireLock("last")) {
233+
assertEquals(PROCESSORS - 1, Affinity.getCpu());
234+
}
235+
try (AffinityLock lock = AffinityLock.acquireLock("last-1")) {
236+
assertEquals(PROCESSORS - 2, Affinity.getCpu());
237+
}
238+
try (AffinityLock lock = AffinityLock.acquireLock("1")) {
239+
assertEquals(1, Affinity.getCpu());
240+
}
241+
try (AffinityLock lock = AffinityLock.acquireLock("any")) {
242+
assertTrue(lock.bound);
243+
}
244+
try (AffinityLock lock = AffinityLock.acquireLock("none")) {
245+
assertFalse(lock.bound);
246+
}
247+
try (AffinityLock lock = AffinityLock.acquireLock((String) null)) {
248+
assertFalse(lock.bound);
249+
}
250+
try (AffinityLock lock = AffinityLock.acquireLock("0")) { // prints a warning
251+
assertFalse(lock.bound);
252+
}
253+
----

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
<modelVersion>4.0.0</modelVersion>
2828
<artifactId>Java-Thread-Affinity</artifactId>
29-
<version>3.1.14-SNAPSHOT</version>
29+
<version>3.2.0-SNAPSHOT</version>
3030
<packaging>pom</packaging>
3131

3232
<name>OpenHFT/Java-Thread-Affinity Parent</name>

0 commit comments

Comments
 (0)