Skip to content

Commit a53c186

Browse files
committed
Document cache leaf function
1 parent f4edff9 commit a53c186

1 file changed

Lines changed: 27 additions & 8 deletions

File tree

include/xsimd/config/xsimd_cpu_features_x86.hpp

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -603,13 +603,32 @@ namespace xsimd
603603
return m_leaf80000000;
604604
}
605605

606+
/**
607+
* Internal utility to lazily read and cache a CPUID leaf.
608+
*
609+
* @tparam status_id The status bit tracking whether this leaf has been read and cached.
610+
* @tparam L The CPUID leaf type (e.g. x86_cpuid_leaf1, x86_cpuid_leaf7).
611+
* @param leaf_cache A non-const reference to the class member that stores the leaf
612+
* value. It must be non-const because this function may write to it on first
613+
* call. It is passed explicitly (rather than accessed via `this`) to allow
614+
* factoring the caching logic across different leaf members.
615+
* @return A const reference to `leaf_cache`. The non-const input / const-ref output
616+
* asymmetry is intentional: callers must not modify the cached value, but
617+
* this function needs write access to populate it.
618+
*
619+
* On first call, checks whether the leaf number is within the range advertised as
620+
* supported by CPUID (via leaf 0 for the standard range, leaf 0x80000000 for the
621+
* extended range). If supported, reads the leaf from the CPU; otherwise leaves
622+
* `leaf_cache` at its zero-initialized default (all feature bits false). Either
623+
* way, `status_id` is set so subsequent calls return immediately.
624+
*/
606625
template <status status_id, typename L>
607-
inline auto const& safe_get_leaf(L& leaf) const
626+
inline auto const& safe_read_leaf(L& leaf_cache) const
608627
{
609628
// Check if already initialized
610629
if (m_status.bit_is_set<status_id>())
611630
{
612-
return leaf;
631+
return leaf_cache;
613632
}
614633

615634
// Limit where we need to check leaf0 or leaf 80000000.
@@ -623,32 +642,32 @@ namespace xsimd
623642
// Check leaf0 in regular range
624643
if (L::leaf <= leaf0().highest_leaf())
625644
{
626-
leaf = L::read();
645+
leaf_cache = L::read();
627646
}
628647
}
629648
else
630649
{
631650
// Check leaf80000000 in extended range
632651
if (L::leaf <= leaf80000000().highest_leaf())
633652
{
634-
leaf = L::read();
653+
leaf_cache = L::read();
635654
}
636655
}
637656

638657
// Mark as valid in all cases, including if it was not read.
639658
// In this case it will be filled with zeros (all false).
640659
m_status.set_bit<status_id>();
641-
return leaf;
660+
return leaf_cache;
642661
}
643662

644663
inline x86_cpuid_leaf1 const& leaf1() const
645664
{
646-
return safe_get_leaf<status::leaf1_valid>(m_leaf1);
665+
return safe_read_leaf<status::leaf1_valid>(m_leaf1);
647666
}
648667

649668
inline x86_cpuid_leaf7 const& leaf7() const
650669
{
651-
return safe_get_leaf<status::leaf7_valid>(m_leaf7);
670+
return safe_read_leaf<status::leaf7_valid>(m_leaf7);
652671
}
653672

654673
inline x86_cpuid_leaf7sub1 const& leaf7sub1() const
@@ -676,7 +695,7 @@ namespace xsimd
676695

677696
inline x86_cpuid_leaf80000001 const& leaf80000001() const
678697
{
679-
return safe_get_leaf<status::leaf80000001_valid>(m_leaf80000001);
698+
return safe_read_leaf<status::leaf80000001_valid>(m_leaf80000001);
680699
}
681700
};
682701

0 commit comments

Comments
 (0)