+#ifdef PERL_MEM_LOG
+
+ /* A major complication arises under PERL_MEM_LOG. When that is active,
+ * every memory allocation may result in logging, depending on the value of
+ * ENV{PERL_MEM_LOG} at the moment. That means, as we create the SV for
+ * saving ENV{foo}'s value (but before saving it), the logging code will
+ * call us recursively to find out what ENV{PERL_MEM_LOG} is. Without some
+ * care that could lead to: 1) infinite recursion; or 2) deadlock (trying to
+ * lock a boolean mutex recursively); 3) destroying the getenv() static
+ * buffer; or 4) destroying the temporary created by this for the copy
+ * causes a log entry to be made which could cause a new temporary to be
+ * created, which will need to be destroyed at some point, leading to an
+ * infinite loop.
+ *
+ * The solution adopted here (after some gnashing of teeth) is to detect
+ * the recursive calls and calls from the logger, and treat them specially.
+ * Let's say we want to do getenv("foo"). We first find
+ * getenv(PERL_MEM_LOG) and save it to a fixed-length per-interpreter
+ * variable, so no temporary is required. Then we do getenv(foo}, and in
+ * the process of creating a temporary to save it, this function will be
+ * called recursively to do a getenv(PERL_MEM_LOG). On the recursed call,
+ * we detect that it is such a call and return our saved value instead of
+ * locking and doing a new getenv(). This solves all of problems 1), 2),
+ * and 3). Because all the getenv()s are done while the mutex is locked,
+ * the state cannot have changed. To solve 4), we don't create a temporary
+ * when this is called from the logging code. That code disposes of the
+ * return value while the mutex is still locked.
+ *
+ * The value of getenv(PERL_MEM_LOG) can be anything, but only initial
+ * digits and 3 particular letters are significant; the rest are ignored by
+ * the memory logging code. Thus the per-interpreter variable only needs
+ * to be large enough to save the significant information, the size of
+ * which is known at compile time. The first byte is extra, reserved for
+ * flags for our use. To protect against overflowing, only the reserved
+ * byte, as many digits as don't overflow, and the three letters are
+ * stored.
+ *
+ * The reserved byte has two bits:
+ * 0x1 if set indicates that if we get here, it is a recursive call of
+ * getenv()
+ * 0x2 if set indicates that the call is from the logging code.
+ *
+ * If the flag indicates this is a recursive call, just return the stored
+ * value of PL_mem_log; An empty value gets turned into NULL. */
+ if (strEQ(str, "PERL_MEM_LOG") && PL_mem_log[0] & 0x1) {
+ if (PL_mem_log[1] == '\0') {
+ return NULL;
+ } else {
+ return PL_mem_log + 1;
+ }
+ }
+
+#endif
+