Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CODETOOLS-7902947: jcstress: Skip affinity initialization when non-local affinity mode is requested #55

Merged
merged 2 commits into from
Jun 1, 2021
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions jcstress-core/src/main/java/org/openjdk/jcstress/ForkedMain.java
Original file line number Diff line number Diff line change
@@ -47,14 +47,18 @@ public static void main(String[] args) throws Exception {
throw new IllegalStateException("Expected three arguments");
}

// Pre-initialize the affinity support and threads, so that workers
// do not have to do this on critical paths during the execution.
// This also runs when the rest of the infrastructure starts up.
new WarmupAffinityTask().start();

String host = args[0];
int port = Integer.parseInt(args[1]);
int token = Integer.parseInt(args[2]);
boolean initLocalAffinity = Boolean.parseBoolean(args[0]);

if (initLocalAffinity) {
// Pre-initialize the affinity support and threads, so that workers
// do not have to do this on critical paths during the execution.
// This also runs when the rest of the infrastructure starts up.
new WarmupAffinityTask().start();
}

String host = args[1];
int port = Integer.parseInt(args[2]);
int token = Integer.parseInt(args[3]);

BinaryLinkClient link = new BinaryLinkClient(host, port);

Original file line number Diff line number Diff line change
@@ -342,6 +342,9 @@ void start() {

command.add(ForkedMain.class.getName());

// notify the forked VM whether we want the local affinity initialized
command.add(Boolean.toString(task.shClass.mode() == AffinityMode.LOCAL));

command.add(host);
command.add(String.valueOf(port));

Original file line number Diff line number Diff line change
@@ -457,6 +457,18 @@ private void generateContinuous(TestInfo info) {
pw.println();
pw.println(" control.isStopped = false;");
pw.println();

// Initialize affinity before starting the timing measurement, so that init time
// does not eat up into the test run time.
pw.println(" if (config.localAffinity) {");
pw.println(" try {");
pw.println(" AffinitySupport.tryBind();");
pw.println(" } catch (Exception e) {");
pw.println(" // Do not care");
pw.println(" }");
pw.println(" }");
pw.println();

pw.println(" ArrayList<CounterThread<" + r + ">> threads = new ArrayList<>(" + actorsCount + ");");
for (ExecutableElement a : info.getActors()) {
pw.println(" threads.add(new CounterThread<" + r + ">() { public Counter<" + r + "> internalRun() {");
@@ -557,7 +569,7 @@ private void generateContinuous(TestInfo info) {
pw.println();
pw.println(" private Counter<" + r + "> " + TASK_LOOP_PREFIX + a.getSimpleName() + "() {");
pw.println(" Counter<" + r + "> counter = new Counter<>();");
pw.println(" AffinitySupport.bind(config.actorMap[" + n + "]);");
pw.println(" if (config.localAffinity) AffinitySupport.bind(config.localAffinityMap[" + n + "]);");
pw.println(" while (true) {");
pw.println(" WorkerSync sync = workerSync;");
pw.println(" if (sync.stopped) {");
Original file line number Diff line number Diff line change
@@ -24,6 +24,8 @@
*/
package org.openjdk.jcstress.infra.runners;

import org.openjdk.jcstress.os.AffinityMode;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@@ -37,7 +39,8 @@ public class ForkedTestConfig {
public final int maxFootprintMB;
public int minStride;
public int maxStride;
public int[] actorMap;
public boolean localAffinity;
public int[] localAffinityMap;

public ForkedTestConfig(TestConfig cfg) {
spinLoopStyle = cfg.spinLoopStyle;
@@ -47,7 +50,10 @@ public ForkedTestConfig(TestConfig cfg) {
maxFootprintMB = cfg.maxFootprintMB;
minStride = cfg.minStride;
maxStride = cfg.maxStride;
actorMap = cfg.cpuMap.actorMap();
localAffinity = cfg.shClass.mode() == AffinityMode.LOCAL;
if (localAffinity) {
localAffinityMap = cfg.cpuMap.actorMap();
}
}

public ForkedTestConfig(DataInputStream dis) throws IOException {
@@ -58,10 +64,13 @@ public ForkedTestConfig(DataInputStream dis) throws IOException {
maxFootprintMB = dis.readInt();
minStride = dis.readInt();
maxStride = dis.readInt();
int len = dis.readInt();
actorMap = new int[len];
for (int c = 0; c < len; c++) {
actorMap[c] = dis.readInt();
localAffinity = dis.readBoolean();
if (localAffinity) {
int len = dis.readInt();
localAffinityMap = new int[len];
for (int c = 0; c < len; c++) {
localAffinityMap[c] = dis.readInt();
}
}
}

@@ -73,9 +82,12 @@ public void write(DataOutputStream dos) throws IOException {
dos.writeInt(maxFootprintMB);
dos.writeInt(minStride);
dos.writeInt(maxStride);
dos.writeInt(actorMap.length);
for (int am : actorMap) {
dos.writeInt(am);
dos.writeBoolean(localAffinity);
if (localAffinity) {
dos.writeInt(localAffinityMap.length);
for (int am : localAffinityMap) {
dos.writeInt(am);
}
}
}

Original file line number Diff line number Diff line change
@@ -33,11 +33,6 @@
public class AffinitySupport {

public static void bind(int cpu) {
if (cpu == -1) {
// Special case: no need to affine.
return;
}

if (VMSupport.isLinux()) {
Linux.bind(cpu);
} else {
@@ -55,6 +50,7 @@ public static void tryBind() {

static class Linux {
private static volatile CLibrary INSTANCE;
private static boolean BIND_TRIED;

public static void tryInit() {
if (INSTANCE == null) {
@@ -76,15 +72,23 @@ public static void bind(int cpu) {
}

public static void tryBind() {
tryInit();
if (BIND_TRIED) return;

synchronized (Linux.class) {
if (BIND_TRIED) return;

final cpu_set_t new_cpuset = new cpu_set_t();
new_cpuset.set(0);
final cpu_set_t old_cpuset = new cpu_set_t();
tryInit();

get(old_cpuset);
set(new_cpuset);
set(old_cpuset);
final cpu_set_t new_cpuset = new cpu_set_t();
new_cpuset.set(0);
final cpu_set_t old_cpuset = new cpu_set_t();

get(old_cpuset);
set(new_cpuset);
set(old_cpuset);

BIND_TRIED = true;
}
}

private static void get(cpu_set_t cpuset) {