Skip to content

Commit 680799e

Browse files
committed
peter-lawrey#25 Add builtin native support for Linux/amd64
1 parent b82c9e3 commit 680799e

5 files changed

Lines changed: 98 additions & 28 deletions

File tree

pom.xml

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

2323
<groupId>vanilla.java</groupId>
2424
<artifactId>affinity</artifactId>
25-
<version>1.5.4-SNAPSHOT</version>
25+
<version>1.5.5.1-SNAPSHOT</version>
2626
<packaging>jar</packaging>
2727

2828
<licenses>

src/main/java/vanilla/java/affinity/AffinityLock.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232
* @author peter.lawrey
3333
*/
3434
public class AffinityLock {
35+
private static final Logger LOGGER = Logger.getLogger(AffinityLock.class.getName());
36+
3537
// TODO It seems like on virtualized platforms .availableProcessors() value can change at
3638
// TODO runtime. We should think about how to adopt to such change
3739

@@ -42,8 +44,6 @@ public class AffinityLock {
4244
public static final long BASE_AFFINITY = AffinitySupport.getAffinity();
4345
public static final long RESERVED_AFFINITY = getReservedAffinity0();
4446

45-
private static final Logger LOGGER = Logger.getLogger(AffinityLock.class.getName());
46-
4747
private static AffinityLock[] LOCKS;
4848
private static NavigableMap<Integer, AffinityLock[]> CORES; // set by cpuLayout()
4949
private static final AffinityLock NONE = new AffinityLock(-1, false, false);
@@ -73,12 +73,17 @@ public class AffinityLock {
7373
*/
7474
public static void cpuLayout(CpuLayout cpuLayout) {
7575
synchronized (AffinityLock.class) {
76+
if (cpuLayout.equals(AffinityLock.cpuLayout))
77+
return;
7678
AffinityLock.cpuLayout = cpuLayout;
7779
LOCKS = new AffinityLock[cpuLayout.cpus()];
7880
int threads = cpuLayout.threadsPerCore();
7981
CORES = new TreeMap<Integer, AffinityLock[]>();
8082
for (int i = 0; i < cpuLayout.cpus(); i++) {
81-
AffinityLock al = LOCKS[i] = new AffinityLock(i, ((BASE_AFFINITY >> i) & 1) != 0, ((RESERVED_AFFINITY >> i) & 1) != 0);
83+
boolean base1 = ((BASE_AFFINITY >> i) & 1) != 0;
84+
boolean reservable1 = ((RESERVED_AFFINITY >> i) & 1) != 0;
85+
LOGGER.log(Level.INFO, "cpu " + i + " base= " + base1 + " reservable= " + reservable1);
86+
AffinityLock al = LOCKS[i] = new AffinityLock(i, base1, reservable1);
8287
final int layoutId = al.cpuId;
8388
int logicalCpuId = coreForId(layoutId);
8489
AffinityLock[] als = CORES.get(logicalCpuId);
@@ -111,8 +116,14 @@ public static CpuLayout cpuLayout() {
111116

112117
private static long getReservedAffinity0() {
113118
String reservedAffinity = System.getProperty(AFFINITY_RESERVED);
114-
if (reservedAffinity == null || reservedAffinity.trim().isEmpty())
115-
return ((1 << PROCESSORS) - 1) ^ BASE_AFFINITY;
119+
if (reservedAffinity == null || reservedAffinity.trim().isEmpty()) {
120+
long reserverable = ((1 << PROCESSORS) - 1) ^ BASE_AFFINITY;
121+
if (reserverable == 0 && PROCESSORS > 1) {
122+
LOGGER.log(Level.INFO, "No isolated CPUs found, so assuming CPUs 1 to " + (PROCESSORS - 1) + " available.");
123+
return ((1 << PROCESSORS) - 2);
124+
}
125+
return reserverable;
126+
}
116127
return Long.parseLong(reservedAffinity, 16);
117128
}
118129

@@ -128,7 +139,7 @@ public static AffinityLock acquireLock() {
128139
/**
129140
* Assign any free core to this thread.
130141
* <p/>
131-
* In reality, only one cpu is assigned, the rest of the threads for that core are reserved so they are not used.
142+
* In reality, only one cpu is assigned, the rest of the threads for that core are reservable so they are not used.
132143
*
133144
* @return A handle for the current AffinityLock.
134145
*/
@@ -214,7 +225,7 @@ static String dumpLocks0(AffinityLock[] locks) {
214225
sb.append(i).append(": ");
215226
if (al.assignedThread != null)
216227
sb.append(al.assignedThread).append(" alive=").append(al.assignedThread.isAlive());
217-
else if (al.reserved)
228+
else if (al.reservable)
218229
sb.append("Reserved for this application");
219230
else if (al.base)
220231
sb.append("General use CPU");
@@ -228,14 +239,14 @@ else if (al.base)
228239
//// Non static fields and methods.
229240
private final int cpuId;
230241
private final boolean base;
231-
private final boolean reserved;
242+
private final boolean reservable;
232243
boolean bound = false;
233244
Thread assignedThread;
234245

235-
AffinityLock(int cpuId, boolean base, boolean reserved) {
246+
AffinityLock(int cpuId, boolean base, boolean reservable) {
236247
this.cpuId = cpuId;
237248
this.base = base;
238-
this.reserved = reserved;
249+
this.reservable = reservable;
239250
}
240251

241252
/**
@@ -251,14 +262,14 @@ private void assignCurrentThread(boolean bind, boolean wholeCore) {
251262
}
252263

253264
/**
254-
* Bind the current thread to this reserved lock.
265+
* Bind the current thread to this reservable lock.
255266
*/
256267
public void bind() {
257268
bind(false);
258269
}
259270

260271
/**
261-
* Bind the current thread to this reserved lock.
272+
* Bind the current thread to this reservable lock.
262273
*
263274
* @param wholeCore if true, also reserve the whole core.
264275
*/
@@ -297,7 +308,7 @@ public void bind(boolean wholeCore) {
297308
}
298309

299310
private boolean canReserve() {
300-
if (reserved) return false;
311+
if (!reservable) return false;
301312
if (assignedThread != null) {
302313
if (assignedThread.isAlive()) return false;
303314
LOGGER.severe("Lock assigned to " + assignedThread + " but this thread is dead.");
@@ -343,7 +354,7 @@ public void release() {
343354

344355
@Override
345356
protected void finalize() throws Throwable {
346-
if (reserved) {
357+
if (reservable) {
347358
LOGGER.warning("Affinity lock for " + assignedThread + " was discarded rather than release()d in a controlled manner.");
348359
release();
349360
}

src/main/java/vanilla/java/affinity/impl/NativeAffinity.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package vanilla.java.affinity.impl;
1818

19+
import vanilla.java.affinity.IAffinity;
20+
1921
import java.io.BufferedInputStream;
2022
import java.io.ByteArrayOutputStream;
2123
import java.io.File;
@@ -30,8 +32,6 @@
3032
import java.util.logging.Level;
3133
import java.util.logging.Logger;
3234

33-
import vanilla.java.affinity.IAffinity;
34-
3535
/**
3636
* @author peter.lawrey
3737
*/
@@ -66,7 +66,7 @@ private static boolean initialize() {
6666

6767
/**
6868
* Computes the MD5 value of the input stream
69-
*
69+
*
7070
* @param input
7171
* @return
7272
* @throws IOException
@@ -80,7 +80,7 @@ private static String md5sum(InputStream input) throws IOException {
8080
.getInstance("MD5");
8181
DigestInputStream digestInputStream = new DigestInputStream(in,
8282
digest);
83-
for (; digestInputStream.read() >= 0;) {
83+
for (; digestInputStream.read() >= 0; ) {
8484

8585
}
8686
ByteArrayOutputStream md5out = new ByteArrayOutputStream();
@@ -96,7 +96,7 @@ private static String md5sum(InputStream input) throws IOException {
9696

9797
/**
9898
* Extract the specified library file to the target folder
99-
*
99+
*
100100
* @param libFolderForCurrentOS
101101
* @param libraryFileName
102102
* @param targetFolder
@@ -148,8 +148,8 @@ private static boolean extractAndLoadLibraryFile(
148148
if (!System.getProperty("os.name").contains("Windows")) {
149149
try {
150150
Runtime.getRuntime()
151-
.exec(new String[] { "chmod", "755",
152-
extractedLibFile.getAbsolutePath() })
151+
.exec(new String[]{"chmod", "755",
152+
extractedLibFile.getAbsolutePath()})
153153
.waitFor();
154154
} catch (Throwable e) {
155155
}
@@ -168,17 +168,18 @@ private static boolean extractAndLoadLibraryFile(
168168
}
169169

170170
private static synchronized boolean loadNativeLibrary(String path,
171-
String name) {
171+
String name) {
172172
File libPath = new File(path, name);
173-
if (libPath.exists()) {
174173

174+
if (libPath.exists()) {
175+
String absolutePath = libPath.getAbsolutePath();
175176
try {
176-
System.load(libPath.getAbsolutePath());
177+
System.load(absolutePath);
177178
return true;
178179
} catch (UnsatisfiedLinkError e) {
179180
// TODO something with e
180181
if (LOGGER.isLoggable(Level.INFO)) {
181-
LOGGER.info("Unable to find libaffinity in " + path);
182+
LOGGER.info("Unable to find " + absolutePath + " in " + path + " " + e.getMessage());
182183
}
183184
return false;
184185
}

src/main/java/vanilla/java/affinity/impl/VanillaCpuLayout.java

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,19 @@
1818

1919
import vanilla.java.affinity.CpuLayout;
2020

21-
import java.io.*;
22-
import java.util.*;
21+
import java.io.BufferedReader;
22+
import java.io.FileInputStream;
23+
import java.io.FileNotFoundException;
24+
import java.io.IOException;
25+
import java.io.InputStream;
26+
import java.io.InputStreamReader;
27+
import java.util.ArrayList;
28+
import java.util.LinkedHashMap;
29+
import java.util.List;
30+
import java.util.Map;
31+
import java.util.Properties;
32+
import java.util.SortedSet;
33+
import java.util.TreeSet;
2334

2435
import static java.lang.Integer.parseInt;
2536

@@ -28,6 +39,7 @@
2839
*/
2940
public class VanillaCpuLayout implements CpuLayout {
3041
public static final int MAX_CPUS_SUPPORTED = 64;
42+
3143
private final List<CpuInfo> cpuDetails;
3244
private final int sockets;
3345
private final int coresPerSocket;
@@ -175,6 +187,30 @@ public String toString() {
175187
return sb.toString();
176188
}
177189

190+
@Override
191+
public boolean equals(Object o) {
192+
if (this == o) return true;
193+
if (o == null || getClass() != o.getClass()) return false;
194+
195+
VanillaCpuLayout that = (VanillaCpuLayout) o;
196+
197+
if (coresPerSocket != that.coresPerSocket) return false;
198+
if (sockets != that.sockets) return false;
199+
if (threadsPerCore != that.threadsPerCore) return false;
200+
if (!cpuDetails.equals(that.cpuDetails)) return false;
201+
202+
return true;
203+
}
204+
205+
@Override
206+
public int hashCode() {
207+
int result = cpuDetails.hashCode();
208+
result = 31 * result + sockets;
209+
result = 31 * result + coresPerSocket;
210+
result = 31 * result + threadsPerCore;
211+
return result;
212+
}
213+
178214
static class CpuInfo {
179215
int socketId, coreId, threadId;
180216

@@ -195,5 +231,27 @@ public String toString() {
195231
", threadId=" + threadId +
196232
'}';
197233
}
234+
235+
@Override
236+
public boolean equals(Object o) {
237+
if (this == o) return true;
238+
if (o == null || getClass() != o.getClass()) return false;
239+
240+
CpuInfo cpuInfo = (CpuInfo) o;
241+
242+
if (coreId != cpuInfo.coreId) return false;
243+
if (socketId != cpuInfo.socketId) return false;
244+
if (threadId != cpuInfo.threadId) return false;
245+
246+
return true;
247+
}
248+
249+
@Override
250+
public int hashCode() {
251+
int result = socketId;
252+
result = 31 * result + coreId;
253+
result = 31 * result + threadId;
254+
return result;
255+
}
198256
}
199257
}
Binary file not shown.

0 commit comments

Comments
 (0)