You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Documentation polish (LICENSE/README/requirements) + test import cleanup (#189)
* Refactor requirements document for clarity and formatting improvements
* Remove unused imports in PosixJNAAffinityTest
* Format LICENSE.adoc for improved readability
* Fix formatting and punctuation in README.adoc for improved readability
Licensed under the *Apache License, Version 2.0* (the "License"); you may not use this file except in compliance with the License.
3
+
Licensed under the *Apache License, Version 2.0* (the "License");
4
+
you may not use this file except in compliance with the License.
4
5
You may obtain a copy of the License at
5
6
6
7
http://www.apache.org/licenses/LICENSE-2.0
7
8
8
-
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9
-
See the License for the specific language governing permissions and limitations under the License.
9
+
Unless required by applicable law or agreed to in writing, software
10
+
distributed under the License is distributed on an "AS IS" BASIS,
11
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+
See the License for the specific language governing permissions and
@@ -14,22 +14,20 @@ Lets you bind a thread to a given core, this can improve performance (this libra
14
14
15
15
OpenHFT Java Thread Affinity library
16
16
17
-
See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java]
17
+
See https://github.com/OpenHFT/Java-Thread-Affinity/tree/master/affinity/src/test/java[affinity/src/test/java]
18
18
for working examples of how to use this library.
19
19
20
20
=== Supported operating systems
21
21
22
-
The library detects the running platform in `Affinity.java` and selects an
23
-
implementation for that OS. Features differ between systems:
22
+
The library detects the running platform in `Affinity.java` and selects an implementation for that OS.
23
+
Features differ between systems:
24
24
25
-
* *Linux* - full affinity control via JNA. The implementation can get and set
26
-
thread affinity, query the current CPU, and obtain process and thread IDs.
27
-
* *Windows* - thread affinity is managed through the kernel API. Process and
28
-
thread IDs are available, while `getCpu()` returns `-1`.
29
-
* *macOS* - provides process and thread IDs but does not modify affinity and
30
-
reports the CPU id as `-1`.
31
-
* *Solaris* - mirrors the macOS implementation: only process and thread IDs are
32
-
returned with no affinity or CPU querying support.
25
+
* *Linux* - full affinity control via JNA.
26
+
The implementation can get and set thread affinity, query the current CPU, and obtain process and thread IDs.
27
+
* *Windows* - thread affinity is managed through the kernel API.
28
+
Process and thread IDs are available, while `getCpu()` returns `-1`.
29
+
* *macOS* - provides process and thread IDs but does not modify affinity and reports the CPU id as `-1`.
30
+
* *Solaris* - mirrors the macOS implementation: only process and thread IDs are returned with no affinity or CPU querying support.
33
31
34
32
=== Changes
35
33
@@ -39,19 +37,15 @@ implementation for that OS. Features differ between systems:
39
37
40
38
=== Dependencies
41
39
42
-
Java-Thread-Affinity will try to use https://github.com/java-native-access/jna[JNA]
43
-
to provide access to native thread-handling functions. JNA should be installed on
44
-
your system to get the most from this library.
40
+
Java-Thread-Affinity will try to use link:https://github.com/java-native-access/jna[JNA]
41
+
to provide access to native thread-handling functions.
42
+
JNA should be installed on your system to get the most from this library.
45
43
46
44
=== JNA version
47
45
48
-
Java-Thread-Affinity currently depends on JNA version 4.4.0, which in turn
49
-
depends on a version of GLIBC >= 2.14. If your operating system is an old one,
50
-
with a version of GLIBC released before 2011, this library will not be able to
51
-
invoke native functions.
46
+
Java-Thread-Affinity currently depends on JNA version 4.4.0, which in turn depends on a version of GLIBC >= 2.14. If your operating system is an old one, with a version of GLIBC released before 2011, this library will not be able to invoke native functions.
52
47
53
-
To work around this problem, fork the repository, and override the `<version>` tag
54
-
for the artifacts `jna` and `jna-platform` in the project's `pom` file.
48
+
To work around this problem, fork the repository, and override the `<version>` tag for the artifacts `jna` and `jna-platform` in the project's `pom` file.
55
49
56
50
=== Installing JNA on Ubuntu
57
51
@@ -68,26 +62,25 @@ for the artifacts `jna` and `jna-platform` in the project's `pom` file.
68
62
Or download jna.jar and jna-platform.jar from the JNA project and add them to your classpath.
69
63
70
64
=== How does CPU allocation work?
71
-
The library will read your `/proc/cpuinfo` if you have one or provide one and it will determine your CPU layout. If you don't have one it will assume every CPU is on one CPU socket.
65
+
The library will read your `/proc/cpuinfo` if you have one or provide one and it will determine your CPU layout.
66
+
If you don't have one it will assume every CPU is on one CPU socket.
72
67
73
-
The library looks for isolated CPUs determined by looking at the CPUs you are not running on by default.
68
+
The library looks for isolated CPUs determined by looking at the CPUs you are not running on by default.
74
69
i.e. if you have 16 CPUs but 8 of them are not available for general use (as determined by the affinity of the process on startup) it will start assigning to those CPUs.
75
70
76
71
Note: if you have more than one process using this library you need to specify which CPUs the process can use otherwise it will assign the same CPUs to both processes.
77
72
78
-
To control which CPUs a process can use, add `-Daffinity.reserved={cpu-mask-in-hex}`
79
-
to the command line of the process. The mask is a hexadecimal bit mask without
80
-
the `0x` prefix where bit `0` represents CPU `0`, bit `1` represents CPU `1` and
81
-
so on. Multiple CPUs can be specified by setting more than one bit.
73
+
To control which CPUs a process can use, add `-Daffinity.reserved={cpu-mask-in-hex}` to the command line of the process.
74
+
The mask is a hexadecimal bit mask without the `0x` prefix where bit `0` represents CPU `0`, bit `1` represents CPU `1` and so on.
75
+
Multiple CPUs can be specified by setting more than one bit.
82
76
83
77
For example:
84
78
85
79
* `-Daffinity.reserved=2` reserves only CPU `1`.
86
80
* `-Daffinity.reserved=6` reserves CPUs `1` and `2`.
87
81
* `-Daffinity.reserved=10` reserves CPUs `1` and `3` (hexadecimal `a`).
88
82
89
-
Use an appropriate mask when starting each process to avoid reserving the same
90
-
cores for multiple JVMs.
83
+
Use an appropriate mask when starting each process to avoid reserving the same cores for multiple JVMs.
91
84
92
85
Note: the CPU 0 is reserved for the Operating System, it has to run somewhere.
Java-Thread-Affinity requires that you first isolate some CPU's.
105
98
106
-
Once a CPU core is isolated, the Linux scheduler will not use the CPU core to run any user-space processes. The isolated CPUs will not participate in load balancing, and will not have tasks running on them unless explicitly assigned.
99
+
Once a CPU core is isolated, the Linux scheduler will not use the CPU core to run any user-space processes.
100
+
The isolated CPUs will not participate in load balancing, and will not have tasks running on them unless explicitly assigned.
107
101
108
102
To isolate the 1st and 3rd CPU cores (CPU numbers start from 0) on your system, add the following to the kernel command line during boot:
109
103
110
104
isolcpus=1,3
111
105
112
-
Using GRUB
106
+
.Using GRUB
113
107
[source]
114
108
----
115
109
sudo sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT="/GRUB_CMDLINE_LINUX_DEFAULT="isolcpus=1,3 /' /etc/default/grub
116
110
sudo update-grub
117
111
sudo reboot
118
112
----
119
113
120
-
Using systemd-boot
114
+
.Using systemd-boot
121
115
[source]
122
116
----
123
117
sudo sed -i 's/^options \(.*\)/options 1円 isolcpus=1,3/' /boot/loader/entries/*.conf
@@ -129,8 +123,8 @@ sudo reboot
129
123
=== Acquiring a CPU lock for a thread
130
124
You can acquire a lock for a CPU in the following way:
131
125
132
-
In Java 6
133
-
[source,java]
126
+
.In Java 6
127
+
[source,java]
134
128
----
135
129
AffinityLock al = AffinityLock.acquireLock();
136
130
try {
@@ -140,26 +134,32 @@ try {
140
134
}
141
135
----
142
136
143
-
In Java 7 or 8
144
-
[source,java]
137
+
.In Java 7 or 8
138
+
[source,java]
145
139
----
146
140
try (AffinityLock al = AffinityLock.acquireLock()) {
147
141
// do some work while locked to a CPU.
148
142
}
149
143
----
144
+
150
145
You have further options such as
151
146
152
147
=== Acquiring a CORE lock for a thread
153
-
You can reserve a whole core. If you have hyper-threading enabled, this will use one CPU and leave it's twin CPU unused.
154
-
[source, java]
148
+
You can reserve a whole core.
149
+
If you have hyper-threading enabled, this will use one CPU and leave it's twin CPU unused.
150
+
151
+
[source,java]
155
152
----
156
153
try (AffinityLock al = AffinityLock.acquireCore()) {
157
154
// do some work while locked to a CPU.
158
155
}
159
156
----
157
+
160
158
=== Controlling layout
159
+
161
160
You can chose a layout relative to an existing lock.
162
-
[source, java]
161
+
162
+
[source,java]
163
163
----
164
164
try (final AffinityLock al = AffinityLock.acquireLock()) {
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.
179
180
180
181
=== Affinity strategies
@@ -193,32 +194,39 @@ The `AffinityStrategies` enum defines hints for selecting a CPU relative to an e
193
194
194
195
=== Getting the thread id
195
196
You can get the current thread id using
196
-
[source, java]
197
-
----
198
197
198
+
[source,java]
199
+
----
199
200
int threadId = AffinitySupport.getThreadId();
200
201
----
202
+
201
203
=== Determining which CPU you are running on
202
204
You can get the current CPU being used by
203
-
[source, java]
204
-
----
205
205
206
+
[source,java]
207
+
----
206
208
int cpuId = AffinitySupport.getCpu();
207
209
----
210
+
208
211
=== Controlling the affinity more directly
212
+
209
213
The affinity of the process on start up is
210
-
[source, java]
211
-
----
212
214
215
+
[source,java]
216
+
----
213
217
long baseAffinity = AffinityLock.BASE_AFFINITY;
214
218
----
219
+
215
220
The available CPU for reservation is
216
-
[source, java]
221
+
222
+
[source,java]
217
223
----
218
224
long reservedAffinity = AffinityLock.RESERVED_AFFINITY;
219
225
----
226
+
220
227
If you want to get/set the affinity directly you can do
221
-
[source, java]
228
+
229
+
[source,java]
222
230
----
223
231
long currentAffinity = AffinitySupport.getAffinity();
224
232
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.
@@ -227,8 +235,8 @@ AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.
227
235
=== Understanding dumpLocks() output
228
236
229
237
Several examples print the current CPU assignments using `AffinityLock.dumpLocks()`.
230
-
Each line of the output begins with the zero based CPU id followed by the status
231
-
of that CPU. Example output might look like:
238
+
Each line of the output begins with the zero based CPU id followed by the status of that CPU.
239
+
Example output might look like:
232
240
233
241
[source]
234
242
----
@@ -239,35 +247,32 @@ of that CPU. Example output might look like:
239
247
----
240
248
241
249
The number on each line is the logical CPU index as recognised by the library.
242
-
The text after the colon describes whether that CPU is free, reserved or already
243
-
bound to a thread. Use these indices when calling `AffinityLock.acquireLock(n)`
250
+
The text after the colon describes whether that CPU is free, reserved or already bound to a thread.
251
+
Use these indices when calling `AffinityLock.acquireLock(n)`
244
252
or when constructing explicit affinity masks.
245
253
246
254
=== Lock file directory
247
255
248
-
AffinityLock stores a small lock file for each CPU. These files are placed in
249
-
the directory specified by the `java.io.tmpdir` system property, which by
250
-
default points to your system's temporary directory (usually `/tmp` on Linux).
256
+
AffinityLock stores a small lock file for each CPU.
257
+
These files are placed in the directory specified by the `java.io.tmpdir` system property, which by default points to your system's temporary directory (usually `/tmp` on Linux).
251
258
252
-
If you want to keep the lock files elsewhere, set this property before using any
253
-
affinity APIs:
259
+
If you want to keep the lock files elsewhere, set this property before using any affinity APIs:
For a detailed of view of the current affinity state (as seen by the library),
270
-
execute the following script on Linux systems:
275
+
For a detailed of view of the current affinity state (as seen by the library), execute the following script on Linux systems:
271
276
272
277
[source]
273
278
----
@@ -289,11 +294,10 @@ $ for i in "$(ls cpu-*)";
289
294
290
295
== Using AffinityThreadFactory
291
296
292
-
`AffinityThreadFactory` binds each thread it creates according to a set of
293
-
`AffinityStrategy` rules. This allows executors to automatically run tasks on
294
-
cores selected by the library.
297
+
`AffinityThreadFactory` binds each thread it creates according to a set of `AffinityStrategy` rules.
298
+
This allows executors to automatically run tasks on cores selected by the library.
295
299
296
-
[source,java]
300
+
[source,java]
297
301
----
298
302
ExecutorService es = Executors.newFixedThreadPool(4,
299
303
new AffinityThreadFactory("worker",
@@ -315,12 +319,14 @@ For an article on how much difference affinity can make and how to use it http:/
315
319
== Questions and Answers
316
320
317
321
=== Question: How to lock a specific cpuId
318
-
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
319
-
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.
322
+
I am currently working on a project related to deadlock detection in multithreaded programs in java.
323
+
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
324
+
Being a beginner, I have little knowledge and thus need your assistance.
325
+
We need to know how to run threads on specified cpu number and then switch threads when one is waiting.
0 commit comments