This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Add STATIC_GETENV macro.


Hi,

This adds a STATIC_GETENV macro for avoiding possible getenv bottlenecks as 
documented in 'Make getenv O(1)' thread.

As this is useful addition this could be a gnu extension.

An patch that converts internal getenv uses to STATIC_GETENV will
follow.

There is question if we should make STATIC_GETENV call a secure_getenv
by default or add STATIC_SECURE_GETENV.

This depends on if getenv calls in next patch could be replaced by
secure getenv or not.

So far both choices are possible.

	* stdlib/stdlib.h (STATIC_GETENV): Add.
	* manual/startup.texi (Environment Access): Document STATIC_GETENV.
	* NEWS: Mention STATIC_GETENV.

---
 NEWS                |  2 ++
 manual/startup.texi | 12 ++++++++++++
 stdlib/stdlib.h     | 18 ++++++++++++++++++
 3 files changed, 32 insertions(+)

diff --git a/NEWS b/NEWS
index 6a72724..e72b479 100644
--- a/NEWS
+++ b/NEWS
@@ -88,6 +88,8 @@ Version 2.19
 * Support for powerpc64le has been added.
 
 * The soft-float powerpc port now supports e500 processors.
+
+* A STATIC_GETENV macro to speed up repeated getenv calls by caching.
 
 Version 2.18
 
diff --git a/manual/startup.texi b/manual/startup.texi
index a277714..c3040c5 100644
--- a/manual/startup.texi
+++ b/manual/startup.texi
@@ -342,6 +342,18 @@ vulnerabilities if the library is referenced from a SUID/SGID program.
 This function is a GNU extension.
 @end deftypefun
 
+@comment stdlib.h
+@comment GNU
+@deftypefun {char *} STATIC_GETENV (const char *@var{name})
+This macro return on first invocation result of call of @code{getenv (name)}.
+In each subsequent invocation it returns a cached result of first call.
+
+When you have a library function where you need to call getenv to determine
+its behaviour this call can be bottleneck as getenv calls have O(n) complexity.
+A @code{STATIC_GETENV} provides a easy way to avoid this bottleneck.
+
+This macro is a GNU extension.
+@end deftypefun
 
 @comment stdlib.h
 @comment SVID
diff --git a/stdlib/stdlib.h b/stdlib/stdlib.h
index 813da19..f52163b 100644
--- a/stdlib/stdlib.h
+++ b/stdlib/stdlib.h
@@ -569,6 +569,24 @@ __END_NAMESPACE_STD
    programs is running with SUID or SGID enabled.  */
 extern char *secure_getenv (const char *__name)
      __THROW __nonnull ((1)) __wur;
+
+/* When function behaviour depends on environment variable it could be
+   bottleneck as getenv is O(n) call. If we disallow changing corresponding
+   environment variable in runtime we can STATIC_GETENV to cache results.  */
+
+#define STATIC_GETENV(c) \
+({									      \
+  static char *__p = (char *) &__p;					      \
+  char *__new = __p;							      \
+  if (__p == (char *) &__p)						      \
+    {									      \
+      __new = getenv (c);						      \
+      char *__val = __sync_val_compare_and_swap (&__p, (char *) &__p, __new); \
+      __new = (__val ==  (char *) &__p) ? __new : __val;		      \
+    }									      \
+  __new;								      \
+})
+
 #endif
 
 #if defined __USE_SVID || defined __USE_XOPEN
-- 
1.8.4.rc3


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]