Commit 122d826d authored by darshan's avatar darshan Committed by Ben Gamari

rts: Add api to pin a thread to a numa node but without fixing a capability

`rts_setInCallCapability` sets the thread affinity as well as pins the
numa node. We should also have the ability to set the numa node without
setting the capability affinity. `rts_pinNumaNodeForCapability` function
is added and exported via `RtsAPI.h`.

Previous callers of `rts_setInCallCapability` should now also call
`rts_pinNumaNodeForCapability` to get the same effect as before.

Test Plan:
  ./validate

Reviewers: austin, simonmar, bgamari

Reviewed By: simonmar, bgamari

Subscribers: thomie, niteria

Differential Revision: https://phabricator.haskell.org/D2637

GHC Trac Issues: #12764
parent bef7e784
......@@ -172,6 +172,24 @@ void rts_unlock (Capability *token);
// when there is no current capability.
Capability *rts_unsafeGetMyCapability (void);
/* ----------------------------------------------------------------------------
Which cpu should the OS thread and Haskell thread run on?
1. Run the current thread on the given capability:
rts_setInCallCapability(cap, 0);
2. Run the current thread on the given capability and set the cpu affinity
for this thread:
rts_setInCallCapability(cap, 1);
3. Run the current thread on the given numa node:
rts_pinThreadToNumaNode(node);
4. Run the current thread on the given capability and on the given numa node:
rts_setInCallCapability(cap, 0);
rts_pinThreadToNumaNode(cap);
------------------------------------------------------------------------- */
// Specify the Capability that the current OS thread should run on when it calls
// into Haskell. The actual capability will be calculated as the supplied
// value modulo the number of enabled Capabilities.
......@@ -185,6 +203,12 @@ Capability *rts_unsafeGetMyCapability (void);
// specified capability, set by either +RTS -qa or +RTS --numa.
void rts_setInCallCapability (int preferred_capability, int affinity);
// Specify the CPU Node that the current OS thread should run on when it calls
// into Haskell. The argument can be either a node number or capability number.
// The actual node will be calculated as the supplied value modulo the number
// of numa nodes.
void rts_pinThreadToNumaNode (int node);
/* ----------------------------------------------------------------------------
Building Haskell objects from C datatypes.
------------------------------------------------------------------------- */
......
......@@ -506,11 +506,19 @@ void rts_setInCallCapability (
if (RtsFlags.ParFlags.setAffinity) {
setThreadAffinity(preferred_capability, n_capabilities);
}
if (RtsFlags.GcFlags.numa) {
task->node = capNoToNumaNode(preferred_capability);
if (!DEBUG_IS_ON || !RtsFlags.DebugFlags.numa) { // faking NUMA
setThreadNode(numa_map[task->node]);
}
}
#endif
}
void rts_pinThreadToNumaNode (
int node USED_IF_THREADS)
{
#ifdef THREADED_RTS
if (RtsFlags.GcFlags.numa) {
Task *task = getTask();
task->node = capNoToNumaNode(node);
if (!DEBUG_IS_ON || !RtsFlags.DebugFlags.numa) { // faking NUMA
setThreadNode(numa_map[task->node]);
}
}
#endif
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment