void moreCapabilities (nat from USED_IF_THREADS, nat to USED_IF_THREADS) { #if defined(THREADED_RTS) nat i; Capability **old_capabilities = capabilities; capabilities = stgMallocBytes(to * sizeof(Capability*), "moreCapabilities"); if (to == 1) { // THREADED_RTS must work on builds that don't have a mutable // BaseReg (eg. unregisterised), so in this case // capabilities[0] must coincide with &MainCapability. capabilities[0] = &MainCapability; } for (i = 0; i < to; i++) { if (i < from) { capabilities[i] = old_capabilities[i]; } else { capabilities[i] = stgMallocBytes(sizeof(Capability), "moreCapabilities"); initCapability(capabilities[i], i); } } debugTrace(DEBUG_sched, "allocated %d more capabilities", to - from); if (old_capabilities != NULL) { stgFree(old_capabilities); } #endif }
/* --------------------------------------------------------------------------- * Function: initCapabilities() * * Purpose: set up the Capability handling. For the THREADED_RTS build, * we keep a table of them, the size of which is * controlled by the user via the RTS flag -N. * * ------------------------------------------------------------------------- */ void initCapabilities( void ) { #if defined(THREADED_RTS) nat i; #ifndef REG_Base // We can't support multiple CPUs if BaseReg is not a register if (RtsFlags.ParFlags.nNodes > 1) { errorBelch("warning: multiple CPUs not supported in this build, reverting to 1"); RtsFlags.ParFlags.nNodes = 1; } #endif n_capabilities = RtsFlags.ParFlags.nNodes; if (n_capabilities == 1) { capabilities = &MainCapability; // THREADED_RTS must work on builds that don't have a mutable // BaseReg (eg. unregisterised), so in this case // capabilities[0] must coincide with &MainCapability. } else { capabilities = stgMallocBytes(n_capabilities * sizeof(Capability), "initCapabilities"); } for (i = 0; i < n_capabilities; i++) { initCapability(&capabilities[i], i); } debugTrace(DEBUG_sched, "allocated %d capabilities", n_capabilities); #else /* !THREADED_RTS */ n_capabilities = 1; capabilities = &MainCapability; initCapability(&MainCapability, 0); #endif // There are no free capabilities to begin with. We will start // a worker Task to each Capability, which will quickly put the // Capability on the free list when it finds nothing to do. last_free_capability = &capabilities[0]; }
/* --------------------------------------------------------------------------- * Function: initCapabilities() * * Purpose: set up the Capability handling. For the THREADED_RTS build, * we keep a table of them, the size of which is * controlled by the user via the RTS flag -N. * * ------------------------------------------------------------------------- */ void initCapabilities( void ) { n_capabilities = 1; capabilities = &MainCapability; initCapability(&MainCapability, 0); last_free_capability = &capabilities[0]; }
Capability * moreCapabilities (nat from USED_IF_THREADS, nat to USED_IF_THREADS) { #if defined(THREADED_RTS) nat i; Capability *old_capabilities = capabilities; if (to == 1) { // THREADED_RTS must work on builds that don't have a mutable // BaseReg (eg. unregisterised), so in this case // capabilities[0] must coincide with &MainCapability. capabilities = &MainCapability; } else { capabilities = stgMallocBytes(to * sizeof(Capability), "moreCapabilities"); if (from > 0) { memcpy(capabilities, old_capabilities, from * sizeof(Capability)); } } for (i = from; i < to; i++) { initCapability(&capabilities[i], i); } last_free_capability = &capabilities[0]; debugTrace(DEBUG_sched, "allocated %d more capabilities", to - from); // Return the old array to free later. if (from > 1) { return old_capabilities; } else { return NULL; } #else return NULL; #endif }
/* --------------------------------------------------------------------------- * Function: initCapabilities() * * Purpose: set up the Capability handling. For the THREADED_RTS build, * we keep a table of them, the size of which is * controlled by the user via the RTS flag -N. * * ------------------------------------------------------------------------- */ void initCapabilities( void ) { /* Declare a couple capability sets representing the process and clock domain. Each capability will get added to these capsets. */ traceCapsetCreate(CAPSET_OSPROCESS_DEFAULT, CapsetTypeOsProcess); traceCapsetCreate(CAPSET_CLOCKDOMAIN_DEFAULT, CapsetTypeClockdomain); #if defined(THREADED_RTS) #ifndef REG_Base // We can't support multiple CPUs if BaseReg is not a register if (RtsFlags.ParFlags.nNodes > 1) { errorBelch("warning: multiple CPUs not supported in this build, reverting to 1"); RtsFlags.ParFlags.nNodes = 1; } #endif n_capabilities = 0; moreCapabilities(0, RtsFlags.ParFlags.nNodes); n_capabilities = RtsFlags.ParFlags.nNodes; #else /* !THREADED_RTS */ n_capabilities = 1; capabilities = stgMallocBytes(sizeof(Capability*), "initCapabilities"); capabilities[0] = &MainCapability; initCapability(&MainCapability, 0); #endif enabled_capabilities = n_capabilities; // There are no free capabilities to begin with. We will start // a worker Task to each Capability, which will quickly put the // Capability on the free list when it finds nothing to do. last_free_capability = capabilities[0]; }
/* --------------------------------------------------------------------------- * Function: initCapabilities() * * Purpose: set up the Capability handling. For the THREADED_RTS build, * we keep a table of them, the size of which is * controlled by the user via the RTS flag -N. * * ------------------------------------------------------------------------- */ void initCapabilities (void) { uint32_t i; /* Declare a couple capability sets representing the process and clock domain. Each capability will get added to these capsets. */ traceCapsetCreate(CAPSET_OSPROCESS_DEFAULT, CapsetTypeOsProcess); traceCapsetCreate(CAPSET_CLOCKDOMAIN_DEFAULT, CapsetTypeClockdomain); // Initialise NUMA if (!RtsFlags.GcFlags.numa) { n_numa_nodes = 1; for (i = 0; i < MAX_NUMA_NODES; i++) { numa_map[i] = 0; } } else { uint32_t nNodes = osNumaNodes(); if (nNodes > MAX_NUMA_NODES) { barf("Too many NUMA nodes (max %d)", MAX_NUMA_NODES); } StgWord mask = RtsFlags.GcFlags.numaMask & osNumaMask(); uint32_t logical = 0, physical = 0; for (; physical < MAX_NUMA_NODES; physical++) { if (mask & 1) { numa_map[logical++] = physical; } mask = mask >> 1; } n_numa_nodes = logical; if (logical == 0) { barf("%s: available NUMA node set is empty"); } } #if defined(THREADED_RTS) #ifndef REG_Base // We can't support multiple CPUs if BaseReg is not a register if (RtsFlags.ParFlags.nCapabilities > 1) { errorBelch("warning: multiple CPUs not supported in this build, reverting to 1"); RtsFlags.ParFlags.nCapabilities = 1; } #endif n_capabilities = 0; moreCapabilities(0, RtsFlags.ParFlags.nCapabilities); n_capabilities = RtsFlags.ParFlags.nCapabilities; #else /* !THREADED_RTS */ n_capabilities = 1; capabilities = stgMallocBytes(sizeof(Capability*), "initCapabilities"); capabilities[0] = &MainCapability; initCapability(&MainCapability, 0); #endif enabled_capabilities = n_capabilities; // There are no free capabilities to begin with. We will start // a worker Task to each Capability, which will quickly put the // Capability on the free list when it finds nothing to do. for (i = 0; i < n_numa_nodes; i++) { last_free_capability[i] = capabilities[0]; } }