gcc -shared -fPIC fake-cpu-count.c -o fake-cpu-count.so -ldl
javac ReportCpuCount.java
java -cp . ReportCpuCount
#Found 8 CPUs
#...
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 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); | |
} | |
} | |
} |
The example is almost 5 years old, so that was to expect :), but ood to know. In the current JDK there is still code that queries the sysconf property mentioned above:
https://github.com/openjdk/jdk/blob/master/src/hotspot/os/linux/os_linux.cpp#L432
However, there seems to be another abstraction wrapped around that, which is container/cgroups aware which then overrides the actual value in order to support dynamic cpu settings.
See:
With that said, the example is just to demonstrate the mechanism, for another example one could try to replace the native logic behing System.currentTimeMillis().
It seems to be not working on JDK21, the underling mechanism that
Runtime.getRuntime().availableProcessors()
uses seems to have changed in Linux