This patch adds documentation and DejaGNU test cases for GOMP_WAIT_POLICY, a new
GCC-specific environment variable extending OMP_WAIT_POLICY to support the
paravirtualized pv-barrier-sync policy (GOMP_WAIT_POLICY=pvsched), as well as
ACTIVE and PASSIVE wait policies.

The documentation in libgomp.texi describes the behavior of pv-barrier-sync:
when no phantom vCPUs are detected (phantom_average == 0), spinning is
maximized at barriers to achieve faster synchronization; as soon as host-side
vCPU contention is detected (phantom_average > 0), threads block immediately to
prevent wasting CPU cycles. The documentation also notes that initialization
errors or policy conflicts safely fall back to the default OMP_WAIT_POLICY.

The install documentation in install.texi notes the requirement for SystemTap 
SDT
headers (sys/sdt.h) to build USDT tracing probes.

The test cases in libgomp/testsuite/libgomp.c/ verify:
- Parsing of active, passive, and pvsched policies.
- Case-insensitive parsing of policy keywords.
- Proper fallback to default wait policy on invalid values, device/mmap
  initialization failures, or conflicting OMP_WAIT_POLICY settings.

gcc/ChangeLog:

        * doc/install.texi: Document SystemTap SDT headers dependency
        (sys/sdt.h) for libgomp USDT probes.

libgomp/ChangeLog:

        * libgomp.texi: Add documentation for GOMP_WAIT_POLICY environment
        variable and pv-barrier-sync policy.
        * testsuite/libgomp.c/pvsched_wait_policy-1.c: New test.
        * testsuite/libgomp.c/pvsched_wait_policy-2.c: New test.
        * testsuite/libgomp.c/pvsched_wait_policy-3.c: New test.
        * testsuite/libgomp.c/pvsched_wait_policy-4.c: New test.
        * testsuite/libgomp.c/pvsched_wait_policy-5.c: New test.
---
 gcc/doc/install.texi                          |  9 ++++
 libgomp/libgomp.texi                          | 46 ++++++++++++++++++-
 .../libgomp.c/pvsched_wait_policy-1.c         | 20 ++++++++
 .../libgomp.c/pvsched_wait_policy-2.c         | 17 +++++++
 .../libgomp.c/pvsched_wait_policy-3.c         | 23 ++++++++++
 .../libgomp.c/pvsched_wait_policy-4.c         | 25 ++++++++++
 .../libgomp.c/pvsched_wait_policy-5.c         | 21 +++++++++
 7 files changed, 160 insertions(+), 1 deletion(-)
 create mode 100644 libgomp/testsuite/libgomp.c/pvsched_wait_policy-1.c
 create mode 100644 libgomp/testsuite/libgomp.c/pvsched_wait_policy-2.c
 create mode 100644 libgomp/testsuite/libgomp.c/pvsched_wait_policy-3.c
 create mode 100644 libgomp/testsuite/libgomp.c/pvsched_wait_policy-4.c
 create mode 100644 libgomp/testsuite/libgomp.c/pvsched_wait_policy-5.c

diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi
index 4e4c40edf84..159eb0cac04 100644
--- a/gcc/doc/install.texi
+++ b/gcc/doc/install.texi
@@ -491,6 +491,15 @@ Necessary to build GCC with zstd compression used for LTO 
bytecode.
 The library is searched in your default library patch search.
 Alternatively, the @option{--with-zstd} configure option should be used.
 
+@item SystemTap SDT headers (@file{sys/sdt.h}), packaged as
+@samp{systemtap-sdt-dev} on Debian/Ubuntu or @samp{systemtap-sdt-devel}
+on Fedora/RHEL.
+
+Necessary to build libgomp's Userspace Statically Defined Tracing
+(USDT) probes, used by Phantom Tracker and other eBPF-based tooling to
+observe libgomp's OpenMP thread lifecycle and the pv-barrier-sync wait
+policy without relying on non-exported internal symbols.
+
 @item Python3 modules
 
 The complete list of Python3 modules broken down by GCC subcomponent
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi
index dd3e7de924c..8b7933198d0 100644
--- a/libgomp/libgomp.texi
+++ b/libgomp/libgomp.texi
@@ -4016,6 +4016,7 @@ variable is not set.
 * GOMP_DEBUG::              Enable debugging output
 * GOMP_STACKSIZE::          Set default thread stack size
 * GOMP_SPINCOUNT::          Set the busy-wait spin count
+* GOMP_WAIT_POLICY::        Select the phantom-guided wait policy
 * GOMP_RTEMS_THREAD_POOLS:: Set the RTEMS specific thread pools
 * GOMP_REVERSE_OFFLOAD_THREADS:: Set the maximum number of host threads
 @end menu
@@ -4690,7 +4691,50 @@ undefined, respectively; unless the @env{GOMP_SPINCOUNT} 
is lower
 or @env{OMP_WAIT_POLICY} is @code{PASSIVE}.
 
 @item @emph{See also}:
-@ref{OMP_WAIT_POLICY}
+@ref{OMP_WAIT_POLICY}, @ref{GOMP_WAIT_POLICY}
+@end table
+
+
+
+@node GOMP_WAIT_POLICY
+@section @env{GOMP_WAIT_POLICY} -- Select the phantom-guided wait policy
+@cindex Environment Variable
+@cindex Implementation specific setting
+@table @asis
+@item @emph{Description}:
+GCC-specific extension of the OpenMP @env{OMP_WAIT_POLICY} ICV.
+libgomp's default spin/block behavior at barriers.
+
+When set to @code{PVSCHED}, @env{GOMP_WAIT_POLICY} enables
+@code{pv-barrier-sync}, a paravirtualized barrier synchronization
+policy: it overrides the normal fixed spin/block behavior so that a
+thread spins at every barrier and, on every spin iteration, checks a
+host-provided metric called @code{phantom_average} (a time-weighted
+average of how many of the guest's vCPUs were not actually running on
+a host pCPU during the last scheduler tick, published over shared
+memory via @code{/dev/guest_ivshmem}).  As long as @code{phantom_average}
+is zero, the thread continues spinning, maximizing spinning during
+non-contended phases on the host to achieve faster synchronization at
+barriers.  As soon as @code{phantom_average} becomes positive, indicating
+host-side vCPU contention, the thread blocks immediately instead of
+continuing to spin.  Checking @code{phantom_average} is a plain
+shared-memory read, so it adds negligible overhead per iteration.  If the
+shared-memory channel cannot be established (device unavailable), a warning is
+printed and libgomp falls back to the default @env{OMP_WAIT_POLICY}.
+
+@code{ACTIVE} and @code{PASSIVE} behave the same as the corresponding
+@env{OMP_WAIT_POLICY} values.  Setting @env{OMP_WAIT_POLICY} and
+@env{GOMP_WAIT_POLICY} to conflicting values (one @code{ACTIVE} and
+the other @code{PASSIVE}) is an error; in case of such errors or
+initialization failures, execution safely falls back to the default 
@env{OMP_WAIT_POLICY}.
+
+@item @emph{See also}:
+@ref{OMP_WAIT_POLICY}, @ref{GOMP_SPINCOUNT}
+
+@item @emph{Reference}:
+Himadri Chhaya-Shailesh,
+@uref{https://inria.hal.science/tel-05438117v2, Scheduler Guided OpenMP
+Execution in Cloud VMs} (PhD thesis)
 @end table
 
 
diff --git a/libgomp/testsuite/libgomp.c/pvsched_wait_policy-1.c 
b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-1.c
new file mode 100644
index 00000000000..1470fab6647
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-1.c
@@ -0,0 +1,20 @@
+/* Verify GOMP_WAIT_POLICY=active resolves to the active spin/throttle
+   constants in env.c's initialize_env().  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wl,-Bstatic,-lgomp,-Bdynamic" } */
+/* { dg-set-target-env-var GOMP_WAIT_POLICY "active" } */
+
+extern int gomp_pv_wait_policy;
+extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
+
+int
+main (void)
+{
+  if (gomp_pv_wait_policy != 1)
+    __builtin_abort ();
+  if (gomp_spin_count_var != 30000000000ULL)
+    __builtin_abort ();
+  if (gomp_throttled_spin_count_var != 1000ULL)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pvsched_wait_policy-2.c 
b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-2.c
new file mode 100644
index 00000000000..8a716eb8ef1
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-2.c
@@ -0,0 +1,17 @@
+/* Verify GOMP_WAIT_POLICY=passive resolves to a zero spin count.  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wl,-Bstatic,-lgomp,-Bdynamic" } */
+/* { dg-set-target-env-var GOMP_WAIT_POLICY "passive" } */
+
+extern int gomp_pv_wait_policy;
+extern unsigned long long gomp_spin_count_var;
+
+int
+main (void)
+{
+  if (gomp_pv_wait_policy != 0)
+    __builtin_abort ();
+  if (gomp_spin_count_var != 0)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pvsched_wait_policy-3.c 
b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-3.c
new file mode 100644
index 00000000000..3cd78b3900c
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-3.c
@@ -0,0 +1,23 @@
+/* Verify that conflicting OMP_WAIT_POLICY / GOMP_WAIT_POLICY settings
+   are handled by printing a conflict error and safely falling back to
+   the default wait policy (gomp_pv_wait_policy = -1, default spin counts).  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wl,-Bstatic,-lgomp,-Bdynamic" } */
+/* { dg-set-target-env-var OMP_WAIT_POLICY "passive" } */
+/* { dg-set-target-env-var GOMP_WAIT_POLICY "active" } */
+/* { dg-output "Conflicting OMP_WAIT_POLICY and GOMP_WAIT_POLICY" } */
+
+extern int gomp_pv_wait_policy;
+extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
+
+int
+main (void)
+{
+  if (gomp_pv_wait_policy != -1)
+    __builtin_abort ();
+  if (gomp_spin_count_var != 300000ULL)
+    __builtin_abort ();
+  if (gomp_throttled_spin_count_var != 100ULL)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pvsched_wait_policy-4.c 
b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-4.c
new file mode 100644
index 00000000000..8739fd9db9f
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-4.c
@@ -0,0 +1,25 @@
+/* Verify GOMP_WAIT_POLICY parsing is case-insensitive: "PvSched" must
+   be recognized as the pvsched keyword.  There's normally no
+   /dev/guest_ivshmem on a test machine, so gomp_pvsched_init() fails
+   and initialize_env() resets gomp_pv_wait_policy back to -1 - the
+   "Error initializing pvsched" message only appears if the keyword
+   was matched in the first place, which is what we're checking.  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wl,-Bstatic,-lgomp,-Bdynamic" } */
+/* { dg-set-target-env-var GOMP_WAIT_POLICY "PvSched" } */
+/* { dg-output "Error initializing pvsched" } */
+
+extern int gomp_pv_wait_policy;
+extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
+
+int
+main (void)
+{
+  if (gomp_pv_wait_policy != -1)
+    __builtin_abort ();
+  if (gomp_spin_count_var != 300000ULL)
+    __builtin_abort ();
+  if (gomp_throttled_spin_count_var != 100ULL)
+    __builtin_abort ();
+  return 0;
+}
diff --git a/libgomp/testsuite/libgomp.c/pvsched_wait_policy-5.c 
b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-5.c
new file mode 100644
index 00000000000..d6d937ba1df
--- /dev/null
+++ b/libgomp/testsuite/libgomp.c/pvsched_wait_policy-5.c
@@ -0,0 +1,21 @@
+/* Verify an unrecognized GOMP_WAIT_POLICY value is rejected and
+   safely falls back to the default wait policy.  */
+/* { dg-do run } */
+/* { dg-additional-options "-Wl,-Bstatic,-lgomp,-Bdynamic" } */
+/* { dg-set-target-env-var GOMP_WAIT_POLICY "bogus" } */
+/* { dg-output "Invalid value for environment variable GOMP_WAIT_POLICY" } */
+
+extern int gomp_pv_wait_policy;
+extern unsigned long long gomp_spin_count_var, gomp_throttled_spin_count_var;
+
+int
+main (void)
+{
+  if (gomp_pv_wait_policy != -1)
+    __builtin_abort ();
+  if (gomp_spin_count_var != 300000ULL)
+    __builtin_abort ();
+  if (gomp_throttled_spin_count_var != 100ULL)
+    __builtin_abort ();
+  return 0;
+}
-- 
2.34.1

Reply via email to