GithubHelp home page GithubHelp logo

openhft / java-thread-affinity Goto Github PK

View Code? Open in Web Editor NEW
1.8K 133.0 358.0 936 KB

Bind a java thread to a given core

Home Page: http://chronicle.software/products/thread-affinity/

License: Apache License 2.0

Java 95.45% Makefile 0.60% C 1.10% C++ 2.86%
affintiy core java bind low-latency

java-thread-affinity's Introduction

Thread Affinity

Thread Affinity line

Version

badge

javadoc

Overview

Lets you bind a thread to a given core, this can improve performance (this library works best on linux).

OpenHFT Java Thread Affinity library

See affinity/src/test/java for working examples of how to use this library.

Changes

  • V3.2.0 - Add support for text configuration

  • V3.1.1 - Upgraded JNA dependency to 4.4.0

  • V2.0.1 - Added getThreadId for the process if of the thread.

Dependencies

Java-Thread-Affinity will try to use JNA to provide access to native thread-handling functions. JNA should be installed on your system to get the most from this library.

JNA version

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.

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.

Installing JNA on Ubuntu

sudo apt-get install libjna-java

Installing JNA on CentOS

sudo yum install jna

How does CPU allocation work?

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.

The library looks for isolated CPUs determined by looking at the CPUs you are not running on by default. 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.

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. To control which CPUs a process can use, add -Daffinity.reserved={cpu-mask-in-hex} to the command line of the process.

Note: the CPU 0 is reserved for the Operating System, it has to run somewhere.

isolcpus

Java-Thread-Affinity requires that you first isolate some CPU’s.

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.

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:

isolcpus=1,3

Using AffinityLock

Acquiring a CPU lock for a thread

You can acquire a lock for a CPU in the following way:

In Java 6

AffinityLock al = AffinityLock.acquireLock();
try {
     // do some work locked to a CPU.
} finally {
     al.release();
}

In Java 7 or 8

try (AffinityLock al = AffinityLock.acquireLock()) {
    // do some work while locked to a CPU.
}

You have further options such as

Acquiring a CORE lock for a thread

You can reserve a whole core. If you have hyper-threading enabled, this will use one CPU and leave it’s twin CPU unused.

try (AffinityLock al = AffinityLock.acquireCore()) {
    // do some work while locked to a CPU.
}

Controlling layout

You can chose a layout relative to an existing lock.

try (final AffinityLock al = AffinityLock.acquireLock()) {
    System.out.println("Main locked");
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            try (AffinityLock al2 = al.acquireLock(AffinityStrategies.SAME_SOCKET,
                                                   AffinityStrategies.ANY)) {
                 System.out.println("Thread-0 locked");
            }
        }
    });
    t.start();
}

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.

Getting the thread id

You can get the current thread id using

int threadId = AffinitySupport.getThreadId();

Determining which CPU you are running on

You can get the current CPU being used by

int cpuId = AffinitySupport.getCpu();

Controlling the affinity more directly

The affinity of the process on start up is

long baseAffinity = AffinityLock.BASE_AFFINITY;

The available CPU for reservation is

long reservedAffinity = AffinityLock.RESERVED_AFFINITY;

If you want to get/set the affinity directly you can do

long currentAffinity = AffinitySupport.getAffinity();
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.

Debugging affinity state

For a detailed of view of the current affinity state (as seen by the library), execute the following script on Linux systems:

# change to the affinity lock-file directory (defaults to system property java.io.tmpdir)
$ cd /tmp

# dump affinity state
$ for i in "$(ls cpu-*)";
      do PID="$(cat $i | head -n1)"; TIMESTAMP="$(cat $i | tail -n1)";
      echo "pid $PID locked at $TIMESTAMP in $i"; taskset -cp $PID;
      cat "/proc/$PID/cmdline"; echo; echo
  done

  pid 14584 locked at 2017.10.30 at 10:33:24 GMT in cpu-3.lock
  pid 14584's current affinity list: 3
  /opt/jdk1.8.0_141/bin/java ...

Support Material

Questions and Answers

Question: How to lock a specific cpuId

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 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.

Answer

// lock a cpuId
try (AffinityLock lock = AffinityLock.acquireLock(n)) {

}

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

OR

// lock one of the last CPUs
try (AffinityLock lock = AffinityLock.acquireLockLastMinus(n)) {

}

Question: how to use a configuration file to set the cpuId

I have the cpuId in a configuration file, how can I set it using a string?

Answer: use one of the following

try (AffinityLock lock = AffinityLock.acquireLock("last")) {
    assertEquals(PROCESSORS - 1, Affinity.getCpu());
}
try (AffinityLock lock = AffinityLock.acquireLock("last-1")) {
    assertEquals(PROCESSORS - 2, Affinity.getCpu());
}
try (AffinityLock lock = AffinityLock.acquireLock("1")) {
    assertEquals(1, Affinity.getCpu());
}
try (AffinityLock lock = AffinityLock.acquireLock("any")) {
    assertTrue(lock.bound);
}
try (AffinityLock lock = AffinityLock.acquireLock("none")) {
    assertFalse(lock.bound);
}
try (AffinityLock lock = AffinityLock.acquireLock((String) null)) {
    assertFalse(lock.bound);
}
try (AffinityLock lock = AffinityLock.acquireLock("0")) { // prints a warning
    assertFalse(lock.bound);
}

java-thread-affinity's People

Contributors

danielshaya avatar dpisklov avatar emmachronicle avatar epickrram avatar geogriff-signal avatar hedehai avatar hft-team-city avatar hyperxpro avatar jansturenielsen avatar jerryshea avatar jorgemag96 avatar jozsefbartokhft avatar lburgazzoli avatar m-anthony avatar mprusakov avatar msalvagna avatar nicktindall avatar peter-lawrey avatar peter-lawrey-admin avatar robaustin avatar rogersimmons avatar shinanca avatar tgd avatar tomshercliff avatar vemv avatar yevgenp avatar zelenij avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

java-thread-affinity's Issues

Finalizer warnings

Using v2.2 on Linux. After a GC occurs, the following warning is logged for each of the reservable CPUs:

[Finalizer] WARN net.openhft.affinity.AffinityLock - Affinity lock for null was discarded rather than release()d in a controlled manner.

This is occurring because LOCK_INVENTORY is initialized inline with a NoCpuLayout, and then in the static initialization block the layout is overwritten with fromCpuInfo(). The first set of AffinityLock objects are subject to GC, hence the warning logged in finalize().

Should the layout be set only once, from the static block, after checking for /proc/cpuinfo?

Unintelligible Exception when initializing.

When trying to use the library (the code that does it works fine with the old 1.6 version of the API) I get the following exception:

Exception in thread "main" java.lang.ExceptionInInitializerError
        at net.openhft.affinity.AffinitySupport.<clinit>(AffinitySupport.java:43)
        at net.openhft.affinity.AffinityLock.<clinit>(AffinityLock.java:46)
        at com.tora.mdata.ssd.AbstractMain.buildLock(AbstractMain.java:98)
        at com.tora.mdata.ssd.AbstractMain.<init>(AbstractMain.java:22)
        at com.tora.mdata.ssd.flex.Main.<init>(Main.java:42)
        at com.tora.mdata.ssd.flex.MulticastMain.main(MulticastMain.java:33)
Caused by: java.lang.IllegalStateException: sched_getaffinity((8) , &(allocated@0x2aaab427a160 (8 bytes) (com.sun.jna.ptr.LongByReference@b427cc0a)) ) errorNo=22
        at net.openhft.affinity.impl.PosixJNAAffinity.getAffinity(PosixJNAAffinity.java:54)
        at net.openhft.affinity.impl.PosixJNAAffinity.<clinit>(PosixJNAAffinity.java:107)
        ... 6 more
Caused by: com.sun.jna.LastErrorException: [22] _
        at com.sun.jna.Native.invokeInt(Native Method)
        at com.sun.jna.Function.invoke(Function.java:383)
        at com.sun.jna.Function.invoke(Function.java:315)
        at com.sun.jna.Library$Handler.invoke(Library.java:212)
        at net.openhft.affinity.impl.$Proxy0.sched_getaffinity(Unknown Source)
        at net.openhft.affinity.impl.PosixJNAAffinity.getAffinity(PosixJNAAffinity.java:49)
        ... 7 more

What does it mean? How can I approach figuring out what's wrong?

cross process Affinity

Hi,

I tried to use the AffinityLock.acquireCore(). it looks good and seems that it does lock specific Core to a thread. however, when I run 2 (similar) processes on same machine it looks like the seconds process locks on same Core, as the first app. here are the dumps of 2 apps (I run on my desktop, only 4 cores):

dump of App 1:
0: General use CPU
1: Reserved for this application
2: Thread[name1,5,main] alive=true
3: General use CPU

dump of App 2:
0: General use CPU
1: Reserved for this application
2: Thread[name3,5,main] alive=true
3: General use CPU

is that on purpose?
I would assume that once core is locked, than other apps won't be able to lock the same core.

Thanks,
Arik

ExceptionInInitializerError occuring while try to run on Windows 7

Exception in thread "main" java.lang.ExceptionInInitializerError
at com.test.thread.Test.main(Test.java:11)
Caused by: java.lang.NullPointerException
at java.util.BitSet.and(Unknown Source)
at net.openhft.affinity.AffinityLock.getReservedAffinity0(AffinityLock.java:113)
at net.openhft.affinity.AffinityLock.(AffinityLock.java:46)
... 1 more

Cause: public static final BitSet BASE_AFFINITY = Affinity.getAffinity();
BASE_AFFINITY value is null and it is causing issue at reserverable.and(BASE_AFFINITY); line no:113

Affinity Version: 3.0
OS: Windows 7
Java Version: 1.7.0_51-b13

Changed Affinity lock files to make use of file locks which get released on kill -9

Affinity locks ( are used to ensure that threads are bound exclusively to a CPU core), we currently use files for this. The problem with using files is that the files are not removed if the process is kill -9'd.

A solution would be to add a lock to the file, locks on files are removed when the process is killed using 'kill -9'

We should ensure that when the file is created, it must be created with 'chmod 777' in order that any other process on the machine can later take hold of the lock.

When a lock is taken on the file, remove the contents of the file, and replace it with he PID of the current java process that has just acquired the lock, so in other words the contents of the file will always contain the last PID that has obtained the lock on the file. [ this is just for human trouble shooting ]

In the case where the lock file is kill -9'd it wont be possible to remove the contents of the file so it is not possible to alway say the contents of the file is the PID current process . As the process may have been killed.

Exception in thread "Processor-MT" java.lang.NoClassDefFoundError: net/openhft/affinity/AffinityLock Occurred in Docker Image

I am trying to run this library in docker image, but getting the following exception


**Exception in thread "Processor-MT" java.lang.NoClassDefFoundError: net/openhft/affinity/AffinityLock
        at SI.Processor.run(Processor.java:6650)
        at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.ClassNotFoundException: net.openhft.affinity.AffinityLock
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
        ... 2 more
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.sun.xml.bind.v2.runtime.reflect.opt.Injector (file:/app/lib/jaxb-impl-2.3.0.jar) to method java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int)
WARNING: Please consider reporting this to the maintainers of com.sun.xml.bind.v2.runtime.reflect.opt.Injector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.**

I am not sure why this error is occurring if I run my project in my host machine aka without creating images it gets to run smoothly. Problem is only arising in docker images.

question - single thread implementation.

Yes, I follow the tutorial in https://github.com/OpenHFT/Java-Thread-Affinity/README.md

The file path of the test Java program is in affinity/src/test/java/net/openhft/affinity/AffinityLockBindMain.java

The purpose of my modification is that I want to bind main thread to one specific CPU.

But I don't know how to do it right now. I am not sure how to implement it since I haven't fully understand funciton usage like affinityLock.bind(wholeCore);.

What I want to do is that, for example, I would like to do a very simple single thread implementation.

Could you tell me how to do that or could you please add one more simple implementation about how to set affinity of main thread of a program. Thanks!

import java.util.ArrayDeque;

public class Runner {
public static void main(String[] args) throws InterruptedException {
ArrayDeque<byte[]> deque = new ArrayDeque<byte[]>(); // define a deque
int objectSize = 1024;

    for(int i = 0; i < 5000; i++){
        for(int j = 0; j < 100; j++){
            deque.addLast(new byte[objectSize]);  // put something into it
        }

        for(int j = 0; j < 10; j++){
            deque.removeLast();  // get something out
        }
    }
}

}
So I try to comment writer and engine threads initialization except reader in AffinityLockBindMain.java, and set affinity by using following the tutorial

If you want to get/set the affinity directly you can do

long currentAffinity = AffinitySupport.getAffinity(); // (1)
AffinitySupport.setAffinity(1L << 5); // lock to CPU 5.// (2)
And I find that (1) and (2) are deprecated in AffinitySupport.java. They are actually in the Affinity.java in /affinity/src/main/java/net/openhft/affinity/Affinity.java

Appendix of Code :

package net.openhft.affinity;
import java.util.BitSet;

import static net.openhft.affinity.AffinityStrategies.;
//import static net.openhft.affinity.Affinity.
;
/**

  • @author peter.lawrey
    */
    public final class AffinityLockBindMainTest {
    private AffinityLockBindMainTest() {
    throw new InstantiationError( "Must not instantiate this class" );
    }

    public static void main(String... args) throws InterruptedException {
    AffinityLock al = AffinityLock.acquireLock();

     int threadId = AffinitySupport.getThreadId();
     System.out.println("threadId of main "+ threadId);
    
     int cpuId = Affinity.getCpu();
     System.out.println("cpuId of main: " + cpuId);
    
     // current cpu bitmap
     BitSet currentAffinity = Affinity.getAffinity();
     // print the bitmap
     StringBuilder s = new StringBuilder();
     for( int i = 0; i < currentAffinity.length();  i++ )
     {
         s.append( currentAffinity.get( i ) == true ? 1: 0 );
     }
     System.out.println( s );
    
     //Affinity.setAffinity( 1L << 5 ); // lock to CPU 5.
    
    
     try {
         // find a cpu on a different socket, otherwise a different core.
         AffinityLock readerLock = al.acquireLock(DIFFERENT_SOCKET, DIFFERENT_CORE);
         new Thread(new SleepRunnable(readerLock, false), "reader").start();
    
         // find a cpu on the same core, or the same socket, or any free cpu.
         //AffinityLock writerLock = readerLock.acquireLock(SAME_CORE, SAME_SOCKET, ANY);
         //new Thread(new SleepRunnable(writerLock, false), "writer").start();
    
         Thread.sleep(200);
     } finally {
         al.release();
     }
    
     // allocate a whole core to the engine so it doesn't have to compete for resources.
     //al = AffinityLock.acquireCore(false);
     //new Thread(new SleepRunnable(al, true), "engine").start();
    
     Thread.sleep(200);
     System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());
    

    }

    static class SleepRunnable implements Runnable {
    private final AffinityLock affinityLock;
    private final boolean wholeCore;

     SleepRunnable(AffinityLock affinityLock, boolean wholeCore) {
         this.affinityLock = affinityLock;
         this.wholeCore = wholeCore;
     }
    
     public void run() {
         affinityLock.bind(wholeCore);
    
         int threadId = AffinitySupport.getThreadId();
         System.out.println("threadId of one SleepRunnable "+
    

threadId);

        // current cpu bitmap
        BitSet currentAffinity = Affinity.getAffinity();
        // print the bitmap
        StringBuilder s = new StringBuilder();
        for( int i = 0; i < currentAffinity.length();  i++ )
        {
            s.append( currentAffinity.get( i ) == true ? 1: 0 );
        }
        System.out.println( s );

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            affinityLock.release();
        }
    }
}

}

Enhancement

Add support for tracking the CPUs bound in a directory such as OS.TMP+"/thread-affinity"

In this directory create a file for each CPU bound and which process has locked it (as well as when)

On Linux, When attempting to lock a CPU check this file doesn't exist first. If there is no free CPUs, check the processes which have locked the CPU are still running e.g. /proc/{pid} exists.

As a part of this bump the minor version of affinity.

PosixJNAAffinityTest#testGettid fails

On this CentOS machine (2x18 cores, SMT), I get thread IDs like 121295. This fails when testGettid asserts tid < 2^16. What is the reason for that assumption? Thread#tid is defined as long and set from Thread.threadSeqNumber, which is long, too.

Executing other threads in pinned thread

Hello.
First, thank you for your great product.
I've been using chronicle java thread affinity for low latency for years.
Recently I found something weird behavior. I guess this is not a problem of java-thread-affinity but a nature of jvm or OS.
I'm running a thread pinned to isolated core to process data . And I wanted other handlers handle those data on general cores. I used thread pool to execute other thread to handle them. What I found was threads of thread pool executed in pinned core are running on same pinned core not general core which results in severe performance downgrade.
I tried few scenarios and my conclusion is this.

  1. New thread(which can be from Thread or ThreadPool) executed in pinned core run in same pinned core.
  2. Where to create ThreadPool, Thread instance is not important.
  3. Executing a new thread in pinned core should be prohibited because it's running.
  4. AffinityLock.acquireLock("none") seems to be helpful but not enough info there.

Is my conclusion right? Am I doing something wrong? Are there any other solution?

Below is test code and result

package common.net;

import common.log.DefaultLogger;
import net.openhft.affinity.Affinity;
import net.openhft.affinity.AffinityLock;
import net.openhft.affinity.AffinityStrategies;
import sun.nio.ch.ThreadPool;

import java.util.concurrent.*;

/**
 * Created by 21511634 on 2016-07-21.
 */
public class Tester {
    static Executor e = Executors.newFixedThreadPool(2);

    public static void main(String[] args) {
        try {
            if (args.length > 0) {
                TestForAffinity(Integer.parseInt(args[0])).join();
            } else {
                TestForGeneral().join();
            }
        } catch (InterruptedException ex) {
            ex.printStackTrace();
        }
        DefaultLogger.logger.info("Finished");
    }

    static void RunSubThread() {
        for (int i = 0; i < 4; ++i) {
            e.execute(() -> {
                try (AffinityLock al = AffinityLock.acquireLock("none")) {
                    DefaultLogger.logger.info("Sub thread started running on cpu " + Affinity.getCpu());
                    double result = 1;
                    for (long j = 1; j < 100000000; ++j) {
                        result += j;
                    }
                    DefaultLogger.logger.info("Sub thread finished running on cpu " + Affinity.getCpu() + " result=" + result);
                }
            });
        }
    }

    static Thread TestForAffinity(int cpuId) {
        Thread t = new Thread(() -> {
            try (AffinityLock al = AffinityLock.acquireLock(cpuId)) {
                DefaultLogger.logger.info("[TestForAffinity] Main thread running on cpu " + Affinity.getCpu());
                RunSubThread();
                DefaultLogger.logger.info("[TestForAffinity] Main thread finished running on cpu " + Affinity.getCpu());
            }
        });
        t.start();
        return t;
    }

    static Thread TestForGeneral() {
        Thread t = new Thread(() -> {
            DefaultLogger.logger.info("[TestForGeneral] Main thread running on cpu " + Affinity.getCpu());
            RunSubThread();
            DefaultLogger.logger.info("[TestForGeneral] Main thread finished running on cpu " + Affinity.getCpu());
        });
        t.start();
        return t;
    }
}

Result.
I have 36 cores and 0,1,18,19 are general cores.
General cpu test cmd : java -cp oraclearena.jar common.net.Tester
Affinity test cmd : java -cp oraclearena.jar common.net.Tester 2

[PROD][dma@pdmap01:/hw01/dma/ap]cat /proc/cpuinfo | grep processor
processor       : 0
processor       : 1
processor       : 2
processor       : 3
processor       : 4
processor       : 5
processor       : 6
processor       : 7
processor       : 8
processor       : 9
processor       : 10
processor       : 11
processor       : 12
processor       : 13
processor       : 14
processor       : 15
processor       : 16
processor       : 17
processor       : 18
processor       : 19
processor       : 20
processor       : 21
processor       : 22
processor       : 23
processor       : 24
processor       : 25
processor       : 26
processor       : 27
processor       : 28
processor       : 29
processor       : 30
processor       : 31
processor       : 32
processor       : 33
processor       : 34
processor       : 35




[PROD][dma@pdmap01:/hw01/dma/ap]taskset -cp 1
pid 1's current affinity list: 0,1,18,19




[PROD][dma@pdmap01:/hw01/dma/ap]java -cp oraclearena.jar common.net.Tester
11:23:39.984 [Thread-0] INFO  common.log.DefaultLogger - [TestForGeneral] Main thread running on cpu 0
11:23:39.986 [Thread-0] INFO  common.log.DefaultLogger - [TestForGeneral] Main thread finished running on cpu 0
11:23:39.988 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread started running on cpu 19
11:23:39.989 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread started running on cpu 0
11:23:40.267 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 0 result=4.999999950000001E15
11:23:40.267 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread started running on cpu 0
11:23:40.269 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 19 result=4.999999950000001E15
11:23:40.269 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread started running on cpu 19
11:23:40.402 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 0 result=4.999999950000001E15
11:23:40.405 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 19 result=4.999999950000001E15




[PROD][dma@pdmap01:/hw01/dma/ap]java -cp oraclearena.jar common.net.Tester 2
11:23:44.835 [Thread-0] INFO  net.openhft.affinity.AffinityLock - Assigning cpu 2 to Thread[Thread-0,5,main]
11:23:44.873 [Thread-0] DEBUG n.o.a.l.FileLockBasedLockChecker - Obtained lock on file /tmp/cpu-2.lock (394420)

11:23:44.883 [Thread-0] INFO  common.log.DefaultLogger - [TestForAffinity] Main thread running on cpu 2
11:23:44.886 [Thread-0] INFO  common.log.DefaultLogger - [TestForAffinity] Main thread finished running on cpu 2
11:23:44.886 [Thread-0] INFO  net.openhft.affinity.LockInventory - Releasing cpu 2 from Thread[Thread-0,5,main]
11:23:44.886 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread started running on cpu 2
11:23:44.904 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread started running on cpu 2
11:23:45.449 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 2 result=4.999999950000001E15
11:23:45.449 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread started running on cpu 2
11:23:45.463 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 2 result=4.999999950000001E15
11:23:45.464 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread started running on cpu 2
11:23:45.717 [pool-1-thread-2] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 2 result=4.999999950000001E15
11:23:45.723 [pool-1-thread-1] INFO  common.log.DefaultLogger - Sub thread finished running on cpu 2 result=4.999999950000001E15

Possible bind issue with AffinityThreadFactory

Hey,

I'm using AffinityThreadFactory and noticed something interesting:
Having created a bunch of threads using it, along with isolcpus - I found that only the first thread created by the factory had its Cpus_allowed_list updated in /proc.
If this is expected behaviour - no problems :)
Otherwise, the offender appears to be here in AffinityThreadFactory:
@Override public void run() { AffinityLock al = lastAffinityLock == null ? AffinityLock.acquireLock() : lastAffinityLock.acquireLock(strategies);

For the very first created thread, we use 'aquireLock' - which internally sets the 'bind' flag to true:

public static AffinityLock acquireLock() { return acquireLock(true); }
For all subsequently created threads, we use lock.aquireLock(strategies) - which sets the 'bind' flag to false:

public AffinityLock acquireLock(AffinityStrategy... strategies) { return acquireLock(false, cpuId, strategies); }

The thread factory doesn't do any further binding related activities with the locks it gets returned.

The result is that the first thread created is bound to its lock's reserved cpu - but no other threads are.

I dropped in a replacement thread factory locally where I explicitly 'bind' the locks after they are returned - and can report that all created threads now report the expected values in Cpus_allowed_list.

My 95th percentiles and above just got way better too ;)

Thanks for the great library!

Run "mvn package" fail in shell

First, I can run mvn package in Ubuntu command line. A part of result as below:

[INFO] --- exec-maven-plugin:1.2.1:exec (build-native) @ affinity ---
    g++ -O3 -Wall -shared -fPIC -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/server -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/i386/server  -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/amd64/jrockit/ -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/i386/jrockit/ -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ppc64le/server -L/usr/lib/jvm/java-8-openjdk-amd64/jre/lib/ppc64le/jrockit/ -ljvm -lrt -I /usr/lib/jvm/java-8-openjdk-amd64/include -I /usr/lib/jvm/java-8-openjdk-amd64/include/linux -I ../../../target/classes/../jni software_chronicle_enterprise_internals_impl_NativeAffinity.cpp net_openhft_ticker_impl_JNIClock.cpp -o ../../../target/classes/libCEInternals.so
    [INFO]
    [INFO] --- maven-bundle-plugin:4.2.1:manifest (default) @ affinity ---

Then, I write a execute.sh as below:

cd work
mvn package

When I run execute.sh. I got:

[INFO] --- exec-maven-plugin:1.2.1:exec (build-native) @ affinity ---
mkdir -p ../../../target/classes/jni
javah -force -classpath ../../../target/classes -d ../../../target/classes/../jni software.chronicle.enterprise.internals.impl.NativeAffinity net.openhft.ticker.impl.JNIClock
g++ -O3 -Wall -shared -fPIC -L/usr/java/default/jre/lib/amd64/server -L/usr/java/default/jre/lib/i386/server  -L/usr/java/default/jre/lib/amd64/jrockit/ -L/usr/java/default/jre/lib/i386/jrockit/ -L/usr/java/default/jre/lib/ppc64le/server -L/usr/java/default/jre/lib/ppc64le/jrockit/ -ljvm -lrt -I /usr/java/default/include -I /usr/java/default/include/linux -I ../../../target/classes/../jni software_chronicle_enterprise_internals_impl_NativeAffinity.cpp net_openhft_ticker_impl_JNIClock.cpp -o ../../../target/classes/libCEInternals.so
software_chronicle_enterprise_internals_impl_NativeAffinity.cpp:21:10: fatal error: jni.h: No such file or directory
   21 | #include <jni.h>
      |          ^~~~~~~
compilation terminated.
net_openhft_ticker_impl_JNIClock.cpp:21:10: fatal error: jni.h: No such file or directory
   21 | #include <jni.h>
      |          ^~~~~~~
compilation terminated.
make: *** [/mnt/c/Users/yhryy/Desktop/TryRealProj/projects/Java-Thread-Affinity-ea/work/affinity/src/main/c/Makefile:41: ../../../target/classes/libCEInternals.so] Error 1
[INFO] ------------------------------------------------------------------------

compatiblity of OS /bin/taskset PID affinty w/ OpenHFT Thread affinity

I assume that if you use OpenHFT Java-Thread-Affinity to map a particular Java VM's thread set to a specific pinned cpu that it would completely over-ride any prior use of /bin/taskset to map that same JVM's PID to a different pinned cpu, correct?

Could there ever be a scenario where both /bin/taskset and OpenHFT Java-Thread-Affinity could work together w synergy?

Or is it generally true that because OpenHFT J-T-A offers a much higher resolution Thread-->CPU (instead of the coarse PID-->CPU) affinity capability that it effectively obsoletes the use of /bin/taskset?

Fails to build on Java 9: sun.misc.URLClassPath is gone

In Java 9, due out in ~two weeks, the sun.misc.URLClassPath no longer exists.
It has always been an implementation detail they were free to remove at any time. Please stop using it.

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.6.2:compile (default-compile) on project affinity: Compilation failure: Compilation failure: 
[ERROR] /home/faux/code/Java-Thread-Affinity/affinity/src/main/java/net/openhft/affinity/BootClassPath.java:[22,16] cannot find symbol
[ERROR]   symbol:   class URLClassPath
[ERROR]   location: package sun.misc
[ERROR] /home/faux/code/Java-Thread-Affinity/affinity/src/main/java/net/openhft/affinity/BootClassPath.java:[31,19] cannot find symbol
[ERROR]   symbol:   class URLClassPath
[ERROR]   location: class net.openhft.affinity.BootClassPath
[ERROR] /home/faux/code/Java-Thread-Affinity/affinity/src/main/java/net/openhft/affinity/BootClassPath.java:[31,52] cannot find symbol
[ERROR]   symbol:   class URLClassPath
[ERROR]   location: class net.openhft.affinity.BootClassPath

Java Thread Affinity exception for Mac OS X (ExceptionInInitializerError)

Hi, Peter. I am experiencing an exception when trying to use Java Thread Affinity in my Mac OS X (stack below):

Exception in thread "main" java.lang.ExceptionInInitializerError
at Main.recursion(Main.java:46)
at Main.main(Main.java:23)
Caused by: java.lang.NullPointerException
at java.util.BitSet.and(BitSet.java:916)
at net.openhft.affinity.AffinityLock.getReservedAffinity0(AffinityLock.java:113)
at net.openhft.affinity.AffinityLock.(AffinityLock.java:46)
... 2 more

Debugging your code I have noticed that the method getAffinity() in class OSXJNAAffinity always return null and that is what is causing that exception. Please, can you confirm that? If so, how can I use your library in Mac?

Thank you.

My environment:

  • Affinity version: 3.0;

  • SO: Mac OS X Yosemite;
  • 
Java version: 1.8.0_65;

Threads to isolated CPUs strategy

I try to use the library for Netty as seen in following code. As I see from the log the library assign to isolated CPUs first but if there are more threads these are assigned to unisolated CPUs as well. How can I force the Thread factory to use only isolated CPUs for these threads?

final int workerThreads = 4;
ThreadFactory threadFactory = new AffinityThreadFactory("atf_wrk", AffinityStrategies.DIFFERENT_CORE);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads, threadFactory);

NullPointerException in LockCheck.getProcessForCpu()

We recently got an NPE with multiple threads in multiple processes executing AffinityLock.aquireLock() on the same machine. We specify the CPUs each process can use so they don't conflict.

java.lang.NullPointerException
at net.openhft.affinity.LockCheck.getProcessForCpu(LockCheck.java:120)
at net.openhft.affinity.LockCheck.isCpuFree(LockCheck.java:67)
at net.openhft.affinity.AffinityLock.canReserve(AffinityLock.java:253)
at net.openhft.affinity.LockInventory.acquireLock(LockInventory.java:90)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:184)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:167)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:145)

Another process on the same machine had a different error at the same time but this one seems to be ok because the cpu was eventually assigned
java.io.FileNotFoundException: /tmp/cpu-16.lock (No such file or directory)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(FileInputStream.java:195)
at java.io.FileInputStream.(FileInputStream.java:138)
at net.openhft.affinity.LockCheck.getProcessForCpu(LockCheck.java:118)
at net.openhft.affinity.LockCheck.isCpuFree(LockCheck.java:67)
at net.openhft.affinity.AffinityLock.canReserve(AffinityLock.java:253)
at net.openhft.affinity.LockInventory.acquireLock(LockInventory.java:90)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:184)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:167)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:145)
...
net.openhft.affinity.AffinityLock INFO: Assigning cpu 16 to {<thread_name>}

We haven't seen this NPE before and we've been running this code for a while. We're using version 3.1.1. Any ideas?

OSGi export packages

Hi,

I have been deploying the affinity jar as a bundle into an OSGi container that already has SLF4J as a separate bundle. The SLF4J minor versions are different. The difference causes Link errors between the versions when loaded in an OSGi container.

Removing them from both the jar file and the MANIFEST fixes the issue and we get happy bundles. I'm happy to submit a pull request but just wanted to check there was not a specific reason for including them in the first place?

Cheers,

Ron

FileLockBasedLockChecker error attempting to release locks held by other processes

To control which CPUs a specific-process can be pinned to in a multi-process affinity-enabled environment, the setting affinity.reserved can be specified to reserve specific CPUs per application.

When running multiple-applications with different reserved CPUs - the following error message can occur

ERROR FileLockBasedLockChecker - Cannot release lock for id XX as don't have it!

This seems to be due to ThreadAffinity checking the state of ALL lockfiles before checking which lockfiles are actually associated with the application's reserved CPUs:

final boolean canReserve(boolean specified) {

        // (1) Processes lockfiles...
        if (!LockCheck.isCpuFree(cpuId))
            return false;

        // (2) ....only checks reserved status here
        if (!specified && !reservable) return false;

        ...

As lock files for ALL processes using the library are stored in java.io.tmpdir by default - applications incorrectly process lockfiles reserved for other applications during step (1) and the error message results.

Minor issue with high loglevel (ERROR)

Version: affinity-3.2.1

Exception in Affinity Package

package javaapplication1;
import vanilla.java.affinity.AffinityLock;
/*
import vanilla.java.clock.ClockSupport;
import vanilla.java.clock.IClock;
import java.io.IOException;
import java.util.Random;
*/

public class JavaApplication1
{
public static void main(String[] args)
{
AffinityLock al = AffinityLock.acquireLock();
try {
new Thread(new SleepRunnable(), "reader").start();
new Thread(new SleepRunnable(), "writer").start();
new Thread(new SleepRunnable(), "engine").start();
} finally {
al.release();
}
System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());
}
private static class SleepRunnable implements Runnable {
public void run() {
AffinityLock al = AffinityLock.acquireLock();
try {
System.out.println("Hello World...!!");
Thread.sleep(1000);
} catch (InterruptedException e) {
} finally {
al.release();
}
}
}
}

Hello,

I have Written the above Code.

And got stuck in this Exception :
Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/WinDef$DWORD
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2427)
at java.lang.Class.privateGetPublicMethods(Class.java:2547)
at java.lang.Class.getMethods(Class.java:1410)
at sun.misc.ProxyGenerator.generateClassFile(ProxyGenerator.java:409)
at sun.misc.ProxyGenerator.generateProxyClass(ProxyGenerator.java:306)
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:501)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
at com.sun.jna.Native.loadLibrary(Native.java:371)
at com.sun.jna.Native.loadLibrary(Native.java:353)
at vanilla.java.affinity.impl.WindowsJNAAffinity$CLibrary.(WindowsJNAAffinity.java:48)
at vanilla.java.affinity.impl.WindowsJNAAffinity.getAffinity(WindowsJNAAffinity.java:70)
at vanilla.java.affinity.impl.WindowsJNAAffinity.(WindowsJNAAffinity.java:60)
at vanilla.java.affinity.AffinitySupport.(AffinitySupport.java:42)
at vanilla.java.affinity.AffinityLock.(AffinityLock.java:44)
at javaapplication1.JavaApplication1.main(JavaApplication1.java:15)
Java Result: 1
BUILD SUCCESSFUL (total time: 0 seconds)

How can I bind a cpu to multithread?

I want to bind a cpu to any thread that is generated from a thread pool. But the AffinityThreadFactory can't bind a cpuid. And so I use acquireLock(cpuid) method in each thread, but it doesn't work. Only one thread can bind successfully, the second thread can't bind the same cpu because of first thread is already bound.

Hide Logging

Hi,

How would I go ahead with silencing all the debug messages? Any chance you can make this done via a toggle as it's for a public java resource.

Thanks.

build problem

hi
i get:

UnsatisfiedLinkError: software.chronicle.enterprise.internals.impl.NativeAffinity.getProcessId0()I
running these test
affinity/src/test/java/net/openhft/affinity/impl/NativeAffinityImpTest.java
affinity/src/test/java/net/openhft/ticker/impl/JNIClockTest.java
on
Apache Maven 3.3.9 (NON-CANONICAL_2016-04-07T23:15:34Z_mockbuild; 2016-04-08T01:15:34+02:00)
Maven home: /usr/share/maven
Java version: 1.8.0_101, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.101-1.b14.fc24.i386/jre
Default locale: it_IT, platform encoding: UTF-8
OS name: "linux", version: "4.6.6-300.fc24.i686", arch: "i386", family: "unix"

and i tried to build also on an our ARM arch builder, but i get:
net_openhft_ticker_impl_JNIClock.cpp:59:25: error: 'rdtsc' was not declared in this scope
any plan for support other arches?
thanks in advance
regards

java.lang.UnsatisfiedLinkError on M1 mac

to reproduce run all test of /Users/teamcity/projects/Chronicle-Queue-Enterprise on m1 mac

[main/queue-cluster-1-replication-event-loop] WARN net.openhft.chronicle.threads.VanillaEventLoop - MediumEventLoop has been terminated due to exception
java.lang.UnsatisfiedLinkError: /Users/teamcity/Library/Caches/JNA/temp/jna1914262682919037562.tmp: dlopen(/Users/teamcity/Library/Caches/JNA/temp/jna1914262682919037562.tmp, 1): no suitable image found.  Did find:
	/Users/teamcity/Library/Caches/JNA/temp/jna1914262682919037562.tmp: no matching architecture in universal wrapper
	/Users/teamcity/Library/Caches/JNA/temp/jna1914262682919037562.tmp: no matching architecture in universal wrapper
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1950)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1832)
	at java.lang.Runtime.load0(Runtime.java:811)
	at java.lang.System.load(System.java:1088)
	at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:1018)
	at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:988)
	at com.sun.jna.Native.<clinit>(Native.java:195)
	at net.openhft.affinity.impl.OSXJNAAffinity$CLibrary.<clinit>(OSXJNAAffinity.java:76)
	at net.openhft.affinity.impl.OSXJNAAffinity.getThreadId(OSXJNAAffinity.java:66)
	at net.openhft.affinity.Affinity.getThreadId(Affinity.java:173)
	at net.openhft.affinity.AffinityLock.bind(AffinityLock.java:383)
	at net.openhft.affinity.AffinityLock.assignCurrentThread(AffinityLock.java:356)
	at net.openhft.affinity.LockInventory.updateLockForCurrentThread(LockInventory.java:73)
	at net.openhft.affinity.LockInventory.acquireLock(LockInventory.java:110)
	at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:297)
	at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:182)
	at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:280)
	at net.openhft.chronicle.threads.MediumEventLoop.run(MediumEventLoop.java:242)
	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at java.lang.Thread.run(Thread.java:748)
	at net.openhft.chronicle.core.threads.CleaningThread.run(CleaningThread.java:96)
[main/queue-cluster-1-~monitor] WARN net.openhft.chronicle.threads.internal.EventLoopThreadHolder - Monitoring a task which has finished VanillaEventLoop{name='queue-cluster-1-replication-event-loop', parent=EventGroup@1, service=java.util.concurrent.Executors$FinalizableDelegatedExecutorService@753a7223, highHandler=NOOP, mediumHandlers=[software.chronicle.enterprise.queue.replication.ReplicatedQueue$Initialiser@7105f85c, software.chronicle.enterprise.queue.replication.ReplicatedQueue$Initialiser@34077818], timerHandlers=[], daemonHandlers=[], newHandler=null, pauser=net.openhft.chronicle.threads.LongPauser@2374e947}

Affinity should respects the cpuId if greater than 0

We had the following issue reported in an email - I think I’ve found a bug in the Affinity code:

When you acquire a lock you go through this code:

public static AffinityLock acquireLock(int cpuId) {
    return acquireLock(true, cpuId, AffinityStrategies.ANY);
}

which then ends up here (unfortunately I can only decompiled code but you should be able to see it in your environment)

public final synchronized AffinityLock acquireLock(boolean bind, int cpuId, AffinityStrategy... strategies) {
    AffinityStrategy[] var4 = strategies;
    int var5 = strategies.length;

    for(int var6 = 0; var6 < var5; ++var6) {
        AffinityStrategy strategy = var4[var6];

        for(int i = this.logicalCoreLocks.length - 1; i > 0; --i) {
            AffinityLock al = this.logicalCoreLocks[i];
            if (al.canReserve() && (cpuId < 0 || strategy.matches(cpuId, al.cpuId()))) {
                al.assignCurrentThread(bind, false);
                LockCheck.updateCpu(al.cpuId());
                return al;
            }
        }
    }

    LOGGER.warn("No reservable CPU for {}", Thread.currentThread());
    return this.newLock(-1, false, false);
}

Assume I have the cpuId set to 4 on an 8 cpu machine.

It will still return 7 (if cpu 7 can be reserved)

Because of this line:

if (al.canReserve() && (cpuId < 0 || strategy.matches(cpuId, al.cpuId())))

This whole logic needs to be changed so that it respects the cpuId if greater than 0.

Hopefully this is clear but please contact me if you need any more info.

On another note we’re finding replication very slow.
On a simple HelloWorld example replication (echo test) a single round trip is taking upwards of 400us (with loopback) – what are your tests reporting for this?

Split packages cause error with Java 9

The affinity library defines classes in the java.lang package. This is not allowed in Java 9, since the java.lang package is already exported by the java.base module

Here is the error:

error: module affinity reads package java.lang from both java.base and affinity

Library does not work in eclipse and sonar

Hi,

our company use Java-Thread-Affinity in our project. Unfortunately after upgrade from OpenJDK 8 to OpenJDK 11 Java-Thread-Affinity started cause problems with sonar analysis (https://www.sonarqube.org). The sonar analyzer uses Eclipse java compiler (ECJ) to create abstract syntax tree. I've setted up the minimalistic project for demonstration:

Project: https://github.com/martinroucek/sonar-ecj-problem
Code: https://github.com/martinroucek/sonar-ecj-problem/blob/master/src/main/java/example/Main.java

I understand that sonar analysis maybe is not critical issue for you. But because the problem is in ECJ the library causes compile errors in Eclipse IDE which is still quite popular. When you import demo project into Eclipse it fails with errors:

The project was not built since its build path is incomplete. Cannot find the class file for java.lang.String. Fix the build path then try building this project
The type java.lang.String cannot be resolved. It is indirectly referenced from required .class files

Do you have any idea what causes this issue?

Linux - Affinity does not work

CPU:
Intel(R) Core(TM)2 Duo CPU P8600 @ 2.40GHz

OS:
Ubuntu 12.04 64bit
Java-Thread-Affinity version : 1.7

com.higherfrequencytrading.affinity.AffinityLock getReservedAffinity0
INFO: No isolated CPUs found, so assuming CPUs 1 to 1 available.
com.higherfrequencytrading.affinity.AffinityLock bind
INFO: Assigning cpu 1 to Thread[main,5,main]
com.higherfrequencytrading.affinity.AffinityLock acquireLock
WARNING: No reservable CPU for Thread[main,5,main]
com.higherfrequencytrading.affinity.AffinityLock acquireLock
WARNING: No reservable CPU for Thread[main,5,main]

updates to lastAffinityLock are not synchronised which can cause issues.

From: "aconstnull" [email protected]
Date: 13 Aug 2016 16:52
Subject: Re: [OpenHFT/Java-Thread-Affinity] Possible bind issue with AffinityThreadFactory (#30)
To: "OpenHFT/Java-Thread-Affinity" [email protected]
Cc:

Related: updates to lastAffinityLock are not synchronised which can cause issues. (The create thread method is synchronised but there is no synchronisation around reading / updating the lastAffinityLock member when working out how to acquire our next lock)

Exception when acquire cpu lock

import net.openhft.affinity.AffinityLock;
/*
import vanilla.java.clock.ClockSupport;
import vanilla.java.clock.IClock;
import java.io.IOException;
import java.util.Random;
*/

public class test
{
public static void main(String[] args)
{
AffinityLock al = AffinityLock.acquireLock();
try {
new Thread(new SleepRunnable(), "reader").start();
new Thread(new SleepRunnable(), "writer").start();
new Thread(new SleepRunnable(), "engine").start();
} finally {
al.release();
}
System.out.println("\nThe assignment of CPUs is\n" + AffinityLock.dumpLocks());
}
private static class SleepRunnable implements Runnable {
public void run() {
AffinityLock al = AffinityLock.acquireLock();
try {
System.out.println("Hello World...!!");
Thread.sleep(1000);
} catch (InterruptedException e) {
} finally {
al.release();
}
}
}
}

hello, I test the above code, and I get the exception below

Exception in thread "main" java.lang.IllegalArgumentException: Argument value 0x40000000000 exceeds native capacity (4 bytes) mask=0xffffffff00000000
at com.sun.jna.IntegerType.setValue(IntegerType.java:92)
at com.sun.jna.IntegerType.(IntegerType.java:55)
at com.sun.jna.platform.win32.WinDef$DWORD.(WinDef.java:135)
at net.openhft.affinity.impl.WindowsJNAAffinity.setAffinity(WindowsJNAAffinity.java:93)
at net.openhft.affinity.Affinity.setAffinity(Affinity.java:163)
at net.openhft.affinity.AffinityLock.bind(AffinityLock.java:235)
at net.openhft.affinity.AffinityLock.assignCurrentThread(AffinityLock.java:203)
at net.openhft.affinity.LockInventory.acquireLock(LockInventory.java:88)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:173)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:157)
at net.openhft.affinity.AffinityLock.acquireLock(AffinityLock.java:134)
at com.phenix.farmer.test.main(test.java:15)

I can't find the reason, please help me solve this problem.

Chronicle test VanillaChronicleTest fails on Mac OS X

I am trying to build on Mac OSX and failing because NullAffinity throws this exception:

java.lang.UnsupportedOperationException
    at net.openhft.affinity.impl.NullAffinity.getThreadId(NullAffinity.java:58)
    at net.openhft.affinity.AffinitySupport.getThreadId(AffinitySupport.java:70)
    at net.openhft.chronicle.sandbox.VanillaChronicle$VanillaAppender.startExcerpt(VanillaChronicle.java:423)
    at net.openhft.chronicle.sandbox.VanillaChronicle$VanillaAppender.startExcerpt(VanillaChronicle.java:416)
    at net.openhft.chronicle.sandbox.VanillaChronicleTest$1.run(VanillaChronicleTest.java:77)
...

I don't really understand all the code, but stepped through it a bit. The problem seems to be that NullAffinity (which is chosen for my OS by the affinity package) throws an exception when asked for the thread id:

NullAffinity.java:
    @Override
    public int getThreadId() {
        throw new UnsupportedOperationException();
    }

I changed to just return 0 and that allows it to pass test cases:

NullAffinity.java:
    @Override
    public int getThreadId() {
        return 0;
    }

Would this make sense to incorporate this change in the repo?

Thanks, Greg.

More than 64 CPUs

Have a 4 socket system (12 cores on each socket) running Linux. Total 48 cores / 96 CPUs with hyper threading and hit:

java.nio.BufferOverflowException
    at java.nio.Buffer.nextPutIndex(Buffer.java:519)
    at java.nio.HeapByteBuffer.putLong(HeapByteBuffer.java:417)
    at net.openhft.affinity.impl.LinuxJNAAffinity.getAffinity(LinuxJNAAffinity.java:80)
    at net.openhft.affinity.impl.LinuxJNAAffinity.<clinit>(LinuxJNAAffinity.java:48)

Found the cause in the code in LinuxJNAAffinity.java:
// TODO: FIXME!!! CHANGE IAffinity TO SUPPORT PLATFORMS WITH 64+ CORES FIXME!!!
I guess that 64+ CPUs is not that far in the future to be the norm.
A fix would be highly appreciated.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.