[llvm] [flang-rt] Add the ability to have user supplied callback functions too further customize the runtime environment. (PR #155646)
David Parks via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 27 08:59:15 PDT 2025
https://github.com/d-parks created https://github.com/llvm/llvm-project/pull/155646
Add the ability to have pre and post call back functions to ExecutionEnvironment::Configure() to allow further customization of the flang runtime environment (called from _FortranAStartProgam) in situations where either the desired features/functionality are proprietary or are too specific to be accepted by the flang community.
Example:
Custom constructor object linked with flang objects:
```
#include "flang-rt/runtime/environment.h"
#include "flang/Runtime/entry-names.h"
#include "flang/Runtime/extensions.h"
namespace Fortran::runtime {
// Do something specific to the flang runtime environment prior to the
// core logic of ExecutionEnvironment::Configure().
static void
CustomPreConfigureEnv(int argc, const char *argv[], const char *envp[],
const EnvironmentDefaultList *envDefaultList) {
puts(__func__);
}
// Do something specific to the flang runtime environment after running the
// core logic of ExecutionEnvironment::Configure().
static void
CustomPostConfigureEnv(int argc, const char *argv[], const char *envp[],
const EnvironmentDefaultList *envDefaultList) {
puts(__func__);
}
void __attribute__((constructor)) CustomInitCstor(void) {
// Possibilities:
// RTNAME(RegisterConfigureEnv)(&CustomPreConfigureEnv,
// &CustomPostConfigureEnv); RTNAME(RegisterConfigureEnv)(nullptr,
// &CustomPostConfigureEnv);
RTNAME(RegisterConfigureEnv)(&CustomPreConfigureEnv, nullptr);
}
} // namespace Fortran::runtime
```
>From b616c34fe3bc0a8992ffc7dc8eb993b5ed76538c Mon Sep 17 00:00:00 2001
From: David Parks <dparks at nvidia.com>
Date: Wed, 27 Aug 2025 08:22:09 -0700
Subject: [PATCH] [flang-rt] Add the ability to have user supplied callback
functions to further customize the runtime environment.
modified: flang-rt/include/flang-rt/runtime/environment.h
modified: flang-rt/lib/runtime/environment.cpp
---
.../include/flang-rt/runtime/environment.h | 21 +++++++++++++
flang-rt/lib/runtime/environment.cpp | 31 +++++++++++++++++++
2 files changed, 52 insertions(+)
diff --git a/flang-rt/include/flang-rt/runtime/environment.h b/flang-rt/include/flang-rt/runtime/environment.h
index e579f6012ce86..d90f930ddfe59 100644
--- a/flang-rt/include/flang-rt/runtime/environment.h
+++ b/flang-rt/include/flang-rt/runtime/environment.h
@@ -11,9 +11,22 @@
#include "flang/Common/optional.h"
#include "flang/Decimal/decimal.h"
+#include "flang/Runtime/entry-names.h"
struct EnvironmentDefaultList;
+// ExecutionEnvironment::Configure() allows for optional callback functions
+// to be run pre and post the core logic.
+// Most likely scenario is when a user supplied constructor function is
+// run prior to _QQmain calling RTNAME(ProgramStart)().
+
+extern "C" {
+void RTNAME(RegisterConfigureEnv)(void (*)(int, const char *[], const char *[],
+ const EnvironmentDefaultList *),
+ void (*)(
+ int, const char *[], const char *[], const EnvironmentDefaultList *));
+}
+
namespace Fortran::runtime {
class Terminator;
@@ -42,6 +55,14 @@ struct ExecutionEnvironment {
ExecutionEnvironment(){};
void Configure(int argc, const char *argv[], const char *envp[],
const EnvironmentDefaultList *envDefaults);
+
+ // Optional callback routines to be invoked pre and post
+ // execution environment setup.
+ void (*PreConfigureEnv)(int, const char *[], const char *[],
+ const EnvironmentDefaultList *){nullptr};
+ void (*PostConfigureEnv)(int, const char *[], const char *[],
+ const EnvironmentDefaultList *){nullptr};
+
const char *GetEnv(
const char *name, std::size_t name_length, const Terminator &terminator);
diff --git a/flang-rt/lib/runtime/environment.cpp b/flang-rt/lib/runtime/environment.cpp
index 0f0564403c0e2..0d8a492b808f6 100644
--- a/flang-rt/lib/runtime/environment.cpp
+++ b/flang-rt/lib/runtime/environment.cpp
@@ -78,6 +78,13 @@ void ExecutionEnvironment::Configure(int ac, const char *av[],
argc = ac;
argv = av;
SetEnvironmentDefaults(envDefaults);
+
+ if (PreConfigureEnv) {
+ // Run an optional callback function prior to the core of the
+ // ExecutionEnvironment() logic.
+ PreConfigureEnv(ac, av, env, envDefaults);
+ }
+
#ifdef _WIN32
envp = _environ;
#else
@@ -173,6 +180,12 @@ void ExecutionEnvironment::Configure(int ac, const char *av[],
}
// TODO: Set RP/ROUND='PROCESSOR_DEFINED' from environment
+
+ if (PostConfigureEnv) {
+ // Run an optional callback function after the core of the
+ // ExecutionEnvironment() logic.
+ PostConfigureEnv(ac, av, env, envDefaults);
+ }
}
const char *ExecutionEnvironment::GetEnv(
@@ -249,4 +262,22 @@ std::int32_t ExecutionEnvironment::UnsetEnv(
return status;
}
+extern "C" {
+
+// User supplied callback functions to further customize the configuration
+// of the runtime environment.
+// The pre and post callback functions are called upon entry and exit
+// of ExecutionEnvironment::Configure() respectively.
+
+void RTNAME(RegisterConfigureEnv)(
+ void (*pre)(int argc, const char *argv[], const char *envp[],
+ const EnvironmentDefaultList *),
+ void (*post)(int argc, const char *argv[], const char *envp[],
+ const EnvironmentDefaultList *)) {
+
+ executionEnvironment.PreConfigureEnv = pre;
+ executionEnvironment.PostConfigureEnv = post;
+}
+} // extern "C"
+
} // namespace Fortran::runtime
More information about the llvm-commits
mailing list