[prev in list] [next in list] [prev in thread] [next in thread]
List: apr-cvs
Subject: cvs commit: apr/memory/unix apr_pools.c
From: wrowe () apache ! org
Date: 2001-09-28 15:22:35
[Download RAW message or body]
wrowe 01/09/28 08:22:35
Modified: . CHANGES
include apr_pools.h
memory/unix apr_pools.c
Log:
Introduce apr_pool_lock for debugging, in combination with
ALLOC_USE_MALLOC + DEBUG_WITH_MPROTECT. Only implemented
on Win32 today, very effective for debugging pool constness.
Fixed a double-reservation for the union block_hdr size in the
unix mprotect_alloc mmap() call. I suspect the mmap can be
modified to implement this on Unix, move the #define DO_LOCK()
out of the win32 block if this is implemented.
Revision Changes Path
1.163 +5 -0 apr/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apr/CHANGES,v
retrieving revision 1.162
retrieving revision 1.163
diff -u -r1.162 -r1.163
--- CHANGES 2001/09/28 03:43:04 1.162
+++ CHANGES 2001/09/28 15:22:34 1.163
@@ -1,5 +1,10 @@
Changes with APR b1
+ *) Introduce apr_pool_lock for debugging, in combination with
+ ALLOC_USE_MALLOC + DEBUG_WITH_MPROTECT. Only implemented
+ on Win32 today, very effective for debugging pool constness.
+ [William Rowe]
+
*) Optimize apr_pstrcat by caching lengths of first 6 strings
[Brian Pane <bpane@pacbell.net>]
1.61 +10 -0 apr/include/apr_pools.h
Index: apr_pools.h
===================================================================
RCS file: /home/cvs/apr/include/apr_pools.h,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- apr_pools.h 2001/09/28 14:05:23 1.60
+++ apr_pools.h 2001/09/28 15:22:35 1.61
@@ -291,6 +291,16 @@
apr_pool_t *cont);
/**
+ * Lock the pool. All the memory is write protected against changes.
+ * @param p The pool to lock
+ * @param writeprotect If true the pool's memory is locked read-only,
+ * otherwise the lock is released
+ * @remark This is a no-op if the program isn't built with appropriate flags
+ * on a platform that supports page locking.
+ */
+APR_DECLARE(void) apr_pool_lock(apr_pool_t *p, int writeprotect);
+
+/**
* Clear all memory in the pool and run all the cleanups. This also clears all
* subpools.
* @param p The pool to clear
1.113 +84 -1 apr/memory/unix/apr_pools.c
Index: apr_pools.c
===================================================================
RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
retrieving revision 1.112
retrieving revision 1.113
diff -u -r1.112 -r1.113
--- apr_pools.c 2001/09/20 09:03:25 1.112
+++ apr_pools.c 2001/09/28 15:22:35 1.113
@@ -168,8 +168,10 @@
#ifndef ALLOC_USE_MALLOC
#error "ALLOC_USE_MALLOC must be enabled to use DEBUG_WITH_MPROTECT"
#endif
+#ifndef WIN32
#include <sys/mman.h>
#endif
+#endif
/** The memory allocation structure
@@ -294,12 +296,15 @@
#define SIZEOF_BLOCK(p) (((union block_hdr *)(p) - 1)->a.l)
+#ifndef WIN32
+
static void *mprotect_malloc(apr_size_t size)
{
union block_hdr * addr;
size += sizeof(union block_hdr);
- addr = mmap(NULL, size + sizeof(union block_hdr),
+
+ addr = mmap(NULL, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS,
-1, 0);
if (addr == MAP_FAILED)
@@ -318,6 +323,64 @@
}
}
+#else /* WIN32 */
+
+/* return the number insignificant bits in size, e.g. the typical page
+ * size of 4096 on x86/WinNT will return 12, as the 12 low-order bits
+ * in the size aren't relevant to the number of pages.
+ */
+static int mprotect_pageshift()
+{
+ static int savesize = 0;
+ if (!savesize) {
+ SYSTEM_INFO sysinfo;
+ GetSystemInfo(&sysinfo);
+ --sysinfo.dwPageSize;
+ while (sysinfo.dwPageSize) {
+ ++savesize;
+ sysinfo.dwPageSize >>= 1;
+ }
+ }
+ return savesize;
+}
+
+static void *mprotect_malloc(apr_size_t size)
+{
+ union block_hdr * addr;
+ int pageshift = mprotect_pageshift();
+ size += sizeof(union block_hdr);
+ size = (((size - 1) >> pageshift) + 1) << pageshift;
+ addr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ if (!addr)
+ return NULL;
+ addr->a.l = size;
+ return addr + 1;
+}
+
+static void mprotect_free(void *addr)
+{
+ apr_size_t size = SIZEOF_BLOCK(addr);
+ BOOL rv = VirtualFree((union block_hdr *)addr - 1, size, MEM_DECOMMIT);
+ if (!rv) {
+ fprintf(stderr, "could not protect. errno=%d\n", errno);
+ abort();
+ }
+}
+
+static void mprotect_lock(void *addr, int lock)
+{
+ size_t size = SIZEOF_BLOCK(addr);
+ DWORD prot = (lock ? PAGE_READONLY : PAGE_READWRITE);
+ BOOL rv = VirtualProtect((union block_hdr *)addr - 1, size, prot, &prot);
+ if (!rv) {
+ fprintf(stderr, "could not protect. errno=%d\n", errno);
+ abort();
+ }
+}
+
+#define DO_LOCK(p,l) mprotect_lock(p,l)
+#endif
+
static void *mprotect_realloc(void *addr, apr_size_t size)
{
void *new_addr = mprotect_malloc(size);
@@ -846,6 +909,26 @@
alloc_mutex = NULL;
#endif
apr_pool_destroy(globalp);
+}
+
+APR_DECLARE(void) apr_pool_lock(apr_pool_t *a, int l)
+{
+#ifdef ALLOC_USE_MALLOC
+#ifdef DO_LOCK
+ /* lock the subpools. */
+ apr_pool_t *s;
+ void *c, *n;
+
+ for (s = a->sub_pools; s; s = s->sub_next) {
+ apr_pool_lock(s, l);
+ }
+
+ for (c = a->allocation_list; c; c = n) {
+ n = *(void **)c;
+ DO_LOCK(c, l);
+ }
+#endif
+#endif
}
/* We only want to lock the mutex if we are being called from apr_pool_clear.
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic