Skip to content

Commit fed564d

Browse files
committed
renamed JNAAffinity to PosixJNAAffinity
added comments
1 parent 1999cea commit fed564d

6 files changed

Lines changed: 109 additions & 94 deletions

File tree

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
* @author peter.lawrey
2121
*/
2222
public class AffinityLock {
23+
//fixme: It seems like on virtualized platforms .availableProcessors() value can change at
24+
//runtime. We should think about how to adopt to such change
25+
2326
public static final int PROCESSORS = Runtime.getRuntime().availableProcessors();
2427
public static final long BASE_AFFINITY = AffinitySupport.getAffinity();
2528
public static final long RESERVED_AFFINITY = getReservedAffinity0();

src/main/java/vanilla/java/affinity/AffinitySupport.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ public enum AffinitySupport {
3030
if ( NativeAffinity.LOADED ) {
3131
System.out.println( "Using JNI-based affinity control implementation" );
3232
affinityImpl = NativeAffinity.INSTANCE;
33-
} else if ( JNAAffinity.LOADED ) {
33+
} else if ( PosixJNAAffinity.LOADED ) {
3434
System.out.println( "Using JNA-based affinity control implementation" );
35-
affinityImpl = JNAAffinity.INSTANCE;
35+
affinityImpl = PosixJNAAffinity.INSTANCE;
3636
} else {
3737
System.out.println( "WARNING: Using dummy affinity control implementation!" );
3838
affinityImpl = NullAffinity.INSTANCE;

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

Lines changed: 0 additions & 83 deletions
This file was deleted.
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
/*
2+
* Copyright 2011 Peter Lawrey
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package vanilla.java.affinity.impl;
18+
19+
import com.sun.jna.*;
20+
import com.sun.jna.ptr.LongByReference;
21+
22+
/**
23+
* Implementation of {@link IAffinityImpl} based on JNA call of
24+
* sched_setaffinity(3)/sched_getaffinity(3) from 'c' library. Applicable for most
25+
* linux/unix platforms
26+
*
27+
* fixme: currently this class not support systme with more then 64 cores
28+
*
29+
* @author peter.lawrey
30+
* @author BegemoT
31+
*/
32+
public enum PosixJNAAffinity implements IAffinityImpl {
33+
INSTANCE;
34+
35+
public static final boolean LOADED;
36+
37+
private static final String LIBRARY_NAME = "c";
38+
39+
/** @author BegemoT */
40+
private interface CLibrary extends Library {
41+
public static final CLibrary INSTANCE = ( CLibrary )
42+
Native.loadLibrary( LIBRARY_NAME, CLibrary.class );
43+
44+
public int sched_setaffinity( final int pid,
45+
final int cpusetsize,
46+
final PointerType cpuset ) throws LastErrorException;
47+
48+
public int sched_getaffinity( final int pid,
49+
final int cpusetsize,
50+
final PointerType cpuset ) throws LastErrorException;
51+
52+
public int sched_getcpu() throws LastErrorException;
53+
}
54+
55+
static {
56+
boolean loaded = false;
57+
try {
58+
INSTANCE.getAffinity();
59+
loaded = true;
60+
} catch ( UnsatisfiedLinkError e ) {
61+
System.out.println( "Unable to load jna library " + e );
62+
}
63+
LOADED = loaded;
64+
}
65+
66+
@Override
67+
public long getAffinity() {
68+
final CLibrary lib = CLibrary.INSTANCE;
69+
//fixme: where are systems with more then 64 cores...
70+
final LongByReference cpuset = new LongByReference( 0L );
71+
try {
72+
final int ret = lib.sched_getaffinity( 0, Long.SIZE / 8, cpuset );
73+
if ( ret < 0 ) {
74+
throw new IllegalStateException( "sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + cpuset + ") ) return " + ret );
75+
}
76+
return cpuset.getValue();
77+
} catch ( LastErrorException e ) {
78+
throw new IllegalStateException( "sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + cpuset + ") ) errorNo=" + e.getErrorCode(), e );
79+
}
80+
}
81+
82+
@Override
83+
public void setAffinity( final long affinity ) {
84+
final CLibrary lib = CLibrary.INSTANCE;
85+
try {
86+
//fixme: where are systems with more then 64 cores...
87+
final int ret = lib.sched_setaffinity( 0, Long.SIZE / 8, new LongByReference( affinity ) );
88+
if ( ret < 0 ) {
89+
throw new IllegalStateException( "sched_setaffinity((" + Long.SIZE / 8 + ") , &(" + affinity + ") ) return " + ret );
90+
}
91+
} catch ( LastErrorException e ) {
92+
throw new IllegalStateException( "sched_getaffinity((" + Long.SIZE / 8 + ") , &(" + affinity + ") ) errorNo=" + e.getErrorCode(), e );
93+
}
94+
}
95+
}

src/test/java/vanilla/java/affinity/impl/AbstractAffinityImplTest.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
*/
1313
public abstract class AbstractAffinityImplTest {
1414

15+
protected static final int CORES = Runtime.getRuntime().availableProcessors();
16+
1517
public abstract IAffinityImpl getImpl();
1618

1719

@@ -27,10 +29,9 @@ public void getAffinityReturnsValidValue() throws Exception {
2729
"Affinity mask " + affinity + " must be >0",
2830
affinity > 0
2931
);
30-
final int cores = Runtime.getRuntime().availableProcessors();
31-
final int allCoresMask = ( 1 << cores ) - 1;
32+
final int allCoresMask = ( 1 << CORES ) - 1;
3233
assertTrue(
33-
"Affinity mask " + affinity + " must be <=(2^" + cores + "-1 = " + allCoresMask + ")",
34+
"Affinity mask " + affinity + " must be <=(2^" + CORES + "-1 = " + allCoresMask + ")",
3435
affinity <= allCoresMask
3536
);
3637
}
@@ -43,7 +44,7 @@ public void setAffinityCompletesGracefully() throws Exception {
4344
@Test
4445
public void getAffinityReturnsValuePreviouslySet() throws Exception {
4546
final IAffinityImpl impl = getImpl();
46-
final int cores = Runtime.getRuntime().availableProcessors();
47+
final int cores = CORES;
4748
for ( int core = 0; core < cores; core++ ) {
4849
final long mask = ( 1 << core );
4950
getAffinityReturnsValuePreviouslySet( impl, mask );
@@ -60,8 +61,7 @@ private void getAffinityReturnsValuePreviouslySet( final IAffinityImpl impl,
6061

6162
@After
6263
public void tearDown() throws Exception {
63-
final int cores = Runtime.getRuntime().availableProcessors();
64-
final int anyCore = ( 1 << cores ) - 1;
64+
final int anyCore = ( 1 << CORES ) - 1;
6565
getImpl().setAffinity( anyCore );
6666
}
6767
}

src/test/java/vanilla/java/affinity/impl/JNAAffinityTest.java renamed to src/test/java/vanilla/java/affinity/impl/PosixJNAAffinityTest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@
1919
import org.junit.*;
2020

2121
/** @author peter.lawrey */
22-
public class JNAAffinityTest extends AbstractAffinityImplTest {
22+
public class PosixJNAAffinityTest extends AbstractAffinityImplTest {
2323
@BeforeClass
2424
public static void checkJniLibraryPresent() {
25-
Assume.assumeTrue( JNAAffinity.LOADED );
25+
Assume.assumeTrue( PosixJNAAffinity.LOADED );
2626
}
2727

2828
@Override
2929
public IAffinityImpl getImpl() {
30-
return JNAAffinity.INSTANCE;
30+
return PosixJNAAffinity.INSTANCE;
3131
}
3232
}

0 commit comments

Comments
 (0)