ICGroupCpuInfo_abi#
Fully qualified name: omni::platforminfo::ICGroupCpuInfo_abi
Defined in omni/platforminfo/ICGroupCpuInfo.h
-
class ICGroupCpuInfo_abi : public omni::core::Inherits<omni::core::IObject, std::integral_constant<uint64_t, carb::fnv1aHash("omni.platforminfo.ICGroupCpuInfo")>::value>#
Interface to collect CPU information directly from Linux’s root level control group.
Interface to collect Linux control group (“cgroup”) information about the CPU(s) installed in the calling system. This can provide some basic information about the CPU core count, scheduling quotas, and active CPU sets. The values reported from this interface will reflect any CPU resource limitations imposed on the system by an external source. For example, the available CPUs could be limited in a container, a VM, or by an OS level per-user quota.
This interface is intended to be used to directly retrieve the cgroup information about the CPU if set. If a particular value is not set (ie: logical core count, CPU set, scheduling quota), the corresponding function will fail allowing the caller to fall back to another information source such as the bare metal values.
This interface is available on Windows for convenience, but all functions will simply fail when called. This makes it easier to call into the interface without needing additional
nullptr
checks.Note
The CPU information will only be collected once on loading this plugin and cached for later retrieval. If the CPU core allocation changes dynamically while the calling process is still running (and therefore the container is still running), this change will not be reflected in the returned values.
Note
This interface supports cgroup versions 1 and 2 on Linux.
Subclassed by omni::core::Generated< omni::platforminfo::ICGroupCpuInfo_abi >
Public Functions
-
inline void *cast(omni::core::TypeId id) noexcept#
Returns a pointer to the interface defined by the given type id if this object implements the type id’s interface.
Objects can support multiple interfaces, even interfaces that are in different inheritance chains.
The returned object will have omni::core::IObject::acquire() called on it before it is returned, meaning it is up to the caller to call omni::core::IObject::release() on the returned pointer.
The returned pointer can be safely
reinterpret_cast<>
to the type id’s C++ class. For example, “omni.windowing.IWindow” can be cast toomni::windowing::IWindow
.Do not directly use this method, rather use a wrapper function like omni::core::cast() or omni::core::ObjectPtr::as().
- Thread Safety
This method is thread safe.
-
inline void acquire() noexcept#
Increments the object’s reference count.
Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().
Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.
- Thread Safety
This method is thread safe.
-
inline void release() noexcept#
Decrements the objects reference count.
Most implementations will destroy the object if the reference count reaches 0 (though this is not a requirement).
Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().
Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.
- Thread Safety
This method is thread safe.
Protected Functions
-
virtual size_t getCpuSetLogicalCoreCount_abi() const noexcept = 0#
Retrieves the total number of logical cores in the active CPU set.
Remark
This retrieves the total number of logical cores in the active CPU set. Depending on the cgroup version that is supported in the system, this value can come from either one of the following files in this priority order:
/sys/fs/cgroup/cpuset.cpus.effective
(v2)/sys/fs/cgroup/cpuset.cpus
(v2)/sys/fs/cgroup/cpuset/cpuset.effective_cpus
(v1)/sys/fs/cgroup/cpuset/cpuset.cpus
(v1)
- Thread Safety
This call is thread safe.
Note
Because the available CPU cores may be limited in a container or at the OS level, it is possible that this may be an odd number. It is also possible that the number of logical cores may not be an integer multiple of the number of physical cores. This is expected behavior since the CPU set may have asymmetrically limited the cores between packages. It is most reliable to simply use the total number of logical cores to decide on things like worker thread counts or task load estimates.
Note
A CPU set may be defined in the cgroup even in a local bare metal situation on Linux. In these cases, the CPU set is often the same as the bare metal CPU info.
- Returns:
The total number of logical cores in the active CPU set if defined. This includes the sum of all available logical cores on all CPU packages. Returns 0 if no CPU set has been defined. In this case, all CPU cores will be available to the calling process but scheduling time may be limited.
-
virtual float getCoreUsageQuota_abi() const noexcept = 0#
Retrieves the effective CPU scheduling quota.
Remark
The CPU scheduling quota is an estimate of how many cores a process can effectively use. However, it does not mean that the process’ threads are restricted to only running on only a specific subset of cores. Instead it means that the threads of the process will only be scheduled to run for a portion of the total available time the CPU has. On Linux, this is expressed as a ratio of available run time versus a scheduling period. The scheduling period is 100000us by default and the run quota is expressed as the number of microseconds a given process is able to use out of that period. For example, a quota of 25000us means that the process may effectively use 25% of a single core’s processing time. A value of 275000us means that the process may effectively use 275% of a single core’s processing time (ie: it can effectively use 2.75 cores). Note that providing a quota value less than the period (ie: the 25000us example) does not mean that only one core may be used. The host OS is still free to schedule the process’ threads in parallel as needed, it just limits the number of time slices of the CPU’s time that it can use over a given period.
Remark
The value returned here is the effective CPU scheduling quota exactly as given in the root cgroup. If a fractional CPU quota is given, that fractional value will be returned. It is the caller’s responsibility to round the value up or down to the nearest full core if it is to be treated as a core count. This can be used as an estimate of how many CPU cores the calling process effectively has access to. Note that the given quota may still be larger than the total number of logical cores available to the process. This can occur in cases where both a CPU quota and a CPU set are specified for a container. In this case, the caller will need to clamp the value to the total number of logical cores.
Remark
Depending on the cgroup version supported in the system, this value comes from the following files:
/sys/fs/cgroup/cpu.max
(v2)/sys/fs/cgroup/cpu/cpu.cfs_quota_us
and/sys/fs/cgroup/cpu/cpu.cfs_period_us
(v1)
- Thread Safety
This call is thread safe.
- Returns:
The effective CPU scheduling quota. This is expressed as an estimate of how many cores the threads of the calling process can effectively be scheduled on. Note that this may be less than, equal to, or greater than the total logical core count available to the calling process. Returns omni::platforminfo::kNoQuotaSet if no CPU scheduling quota has been set. Note that fractional number of cores may be returned here. See remarks below for how to interpret these values.
- virtual size_t getCoreSetList_abi(
- int32_t *cores,
- size_t maxCores,
Retrieves the set of CPU cores available to the calling process.
/sys/fs/cgroup/cpuset.cpus.effective
(v2)/sys/fs/cgroup/cpuset.cpus
(v2)/sys/fs/cgroup/cpuset/cpuset.effective_cpus
(v1)/sys/fs/cgroup/cpuset/cpuset.cpus
(v1)
Remark
This retrieves the indices of the logical cores in the active CPU set. Depending on the cgroup version that is supported in the system, this value can come from either one of the following files in this priority order:
- Thread Safety
This call is thread safe.
- Parameters:
cores – [out] Receives the list of core indices for all CPU cores available to the calling process. If no CPU set has been defined that limits access to specific cores, this will simply return 0. This may be
nullptr
if the list of core indices is not needed. In this case the total required size of the buffer will be returned if a CPU set is defined.maxCores – [in] The maximum number of CPU core indices that can fit in
cores
. This may be 0 to retrieve the required size of the buffer.
- Returns:
The total number of CPU core indices written to the buffer
cores
if a CPU set has been defined in the cgroup andcores
is non-nullptr. Ifcores
isnullptr
the required size of the buffer in indices is returned. If the buffer is not large enough to hold the full CPU set indices, as many indices as will fit are written to the buffer and the required size of the buffer is returned. If no CPU set has been defined, 0 is returned.
-
virtual void *cast_abi(TypeId id) noexcept = 0#
Returns a pointer to the interface defined by the given type id if this object implements the type id’s interface.
Objects can support multiple interfaces, even interfaces that are in different inheritance chains.
The returned object will have omni::core::IObject::acquire() called on it before it is returned, meaning it is up to the caller to call omni::core::IObject::release() on the returned pointer.
The returned pointer can be safely
reinterpret_cast<>
to the type id’s C++ class. For example, “omni.windowing.IWindow” can be cast toomni::windowing::IWindow
.Do not directly use this method, rather use a wrapper function like omni::core::cast() or omni::core::ObjectPtr::as().
- Thread Safety
This method is thread safe.
-
virtual void acquire_abi() noexcept = 0#
Increments the object’s reference count.
Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().
Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.
- Thread Safety
This method is thread safe.
-
virtual void release_abi() noexcept = 0#
Decrements the objects reference count.
Most implementations will destroy the object if the reference count reaches 0 (though this is not a requirement).
Objects may have multiple reference counts (e.g. one per interface implemented). As such, it is important that you call omni::core::IObject::release() on the same pointer from which you called omni::core::IObject::acquire().
Do not directly use this method, rather use omni::core::ObjectPtr, which will manage calling omni::core::IObject::acquire() and omni::core::IObject::release() for you.
- Thread Safety
This method is thread safe.
-
inline void *cast(omni::core::TypeId id) noexcept#