Skip to content

Instantly share code, notes, and snippets.

@SubOptimal
Forked from thomasdarimont/ReportCpuCount.java
Last active March 29, 2019 19:39
Show Gist options
  • Save SubOptimal/75c7479376171e827e85419ee6f1aa2b to your computer and use it in GitHub Desktop.
Save SubOptimal/75c7479376171e827e85419ee6f1aa2b to your computer and use it in GitHub Desktop.
Using LD_PRELOAD to pass a fake CPU count to Java on Linux

Build shared library

gcc -shared -fPIC fake-cpu-count.c -o fake-cpu-count.so -ldl

Compile ReportCpuCount

javac ReportCpuCount.java

Run normally

java -cp . ReportCpuCount
#Found 8 CPUs
#...

Run with fake-cpu-count library

LD_PRELOAD=./fake-cpu-count.so java -cp . ReportCpuCount
#Found 2 CPUs
#...
#define _GNU_SOURCE
#include "stdlib.h"
#include <unistd.h>
#include <dlfcn.h>
typedef long int (*orig_sysconf_f_type)(int __name);
long sysconf(int name){
orig_sysconf_f_type orig_sysconf;
orig_sysconf = (orig_sysconf_f_type)dlsym(RTLD_NEXT,"sysconf");
if (name == _SC_NPROCESSORS_CONF){
return 3;
}
return orig_sysconf(name);
}
#define _GNU_SOURCE
#include "stdlib.h"
#include <unistd.h>
#include <dlfcn.h>
typedef long int (*orig_sysconf_f_type)(int __name);
long sysconf(int name){
orig_sysconf_f_type orig_sysconf;
orig_sysconf = (orig_sysconf_f_type)dlsym(RTLD_NEXT,"sysconf");
if (name == _SC_NPROCESSORS_CONF){
return 2;
}
return orig_sysconf(name);
}
#define _GNU_SOURCE
#include "stdlib.h"
#include <unistd.h>
#include <dlfcn.h>
typedef long int (*orig_sysconf_f_type)(int __name);
long sysconf(int name){
orig_sysconf_f_type orig_sysconf;
orig_sysconf = (orig_sysconf_f_type)dlsym(RTLD_NEXT,"sysconf");
if (name == _SC_NPROCESSORS_ONLN){
return 2;
}
return orig_sysconf(name);
}
public class ReportCpuCount {
public static void main(String[] args) throws Exception{
while(true){
System.out.printf("#Found %d CPUs%n", Runtime.getRuntime().availableProcessors());
Thread.sleep(1000);
}
}
}
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)
java only : #Found 4 CPUs
NPROCESSORS_CONF: #Found 4 CPUs
NPROCESSORS_ONLN: #Found 2 CPUs <-- runtime.availableProcessors() returns sysconf(_SC_NPROCESSORS_ONLN)
taskset -c 0 : #Found 4 CPUs
Java(TM) SE Runtime Environment (build 1.8.0_121-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode)
java only : #Found 4 CPUs
NPROCESSORS_CONF: #Found 4 CPUs
NPROCESSORS_ONLN: #Found 2 CPUs <-- runtime.availableProcessors() returns sysconf(_SC_NPROCESSORS_ONLN)
taskset -c 0 : #Found 4 CPUs
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
java only : #Found 4 CPUs
NPROCESSORS_CONF: #Found 3 CPUs <-- runtime.availableProcessors() returns sysconf(_SC_NPROCESSORS_CONF)
NPROCESSORS_ONLN: #Found 4 CPUs
taskset -c 0 : #Found 1 CPUs <-- runtime.availableProcessors() returns the specified CPU affinity
Java(TM) SE Runtime Environment (build 9-ea+165)
Java HotSpot(TM) 64-Bit Server VM (build 9-ea+165, mixed mode)
java only : #Found 4 CPUs
NPROCESSORS_CONF: #Found 4 CPUs <-- runtime.availableProcessors() ignores returns sysconf(_SC_NPROCESSORS_[CONF|ONLN])
NPROCESSORS_ONLN: #Found 4 CPUs <-/
taskset -c 0 : #Found 1 CPUs <-- runtime.availableProcessors() returns the specified CPU affinity
#!/bin/sh
# a bug report adressing the behaviour of the configured CPU affinity
#
# https://bugs.openjdk.java.net/browse/JDK-6515172
# the relevant code in Java 8 / 9
#
# http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/443a768ec827/src/os/linux/vm/os_linux.cpp
# http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/os/linux/vm/os_linux.cpp
JAVA_HOMES=/opt/jdks
PATH_ORIG=${PATH}
for jdk in jdk1.7.0_80 jdk1.8.0_121 jdk1.8.0_131 jdk1.9.0.ea.165
do
export PATH=${JAVA_HOMES}/${jdk}/bin:${PATH_ORIG}
javac ReportCpuCount.java
java -version 2>&1 | tail -2
printf "java only : "
java -cp . ReportCpuCount
printf "NPROCESSORS_CONF: "
gcc -shared -fPIC fake-cpu-conf.c -o fake-cpu-conf.so -ldl
LD_PRELOAD=./fake-cpu-conf.so java -cp . ReportCpuCount
printf "NPROCESSORS_ONLN: "
gcc -shared -fPIC fake-cpu-onln.c -o fake-cpu-onln.so -ldl
LD_PRELOAD=./fake-cpu-onln.so java -cp . ReportCpuCount
printf "taskset -c 0 : "
taskset -c 0 java -cp . ReportCpuCount
echo
done
@mikhailnov
Copy link

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment