// // aegis - project change supervisor // Copyright (C) 1991-1994, 1999, 2002-2006, 2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see // . // #include #include #include #include #include #include #include #ifdef DMALLOC #undef new #undef delete #include #endif #ifdef _AIX // // Yet another AIX stupidity: // malloc does not guarantee that the space is available in swap. // #include #include static jmp_buf aix_bungy; // // Catch SIGDANGER and longjmp to aix_touch. // static void aix_danger(int n) { longjmp(aix_bungy, 1); } // // Touch the pages that cover [p, p+nbytes-1]. // static int aix_touch(void *vp, size_t nbytes) { char *p; char *endp; int pgsize; volatile char c; void (*oldsig)(int); oldsig = signal(SIGDANGER, aix_danger); if (setjmp(aix_bungy)) { signal(SIGDANGER, oldsig); return -1; } // // A load is enough to cause the // allocation of the paging space // p = vp; pgsize = getpagesize(); endp = p + nbytes; while (p < endp) { c = *(volatile char *)p; p += pgsize; } // // restore the signal handler // signal(SIGDANGER, oldsig); return 0; } #endif void * mem_alloc(size_t n) { if (n < 1) n = 1; int old_errno = errno; errno = 0; void *cp = malloc(n); if (!cp) { if (!errno) errno = ENOMEM; nfatal("malloc(%ld)", (long)n); } #ifdef _AIX // // watch out for AIX stupidity // if (aix_touch(cp, n)) { errno = ENOMEM; nfatal("malloc(%ld)", (long)n); } #endif errno = old_errno; return cp; } #ifdef DMALLOC void * dmem_alloc(const char* file, int line, size_t n) { if (n < 1) n = 1; int old_errno = errno; errno = 0; void *cp = dmalloc_malloc(file, line, n, DMALLOC_FUNC_MALLOC, 0, 0); if (!cp) { if (!errno) errno = ENOMEM; nfatal("malloc(%ld)", (long)n); } #ifdef _AIX // // watch out for AIX stupidity // if (aix_touch(cp, n)) { errno = ENOMEM; nfatal("malloc(%ld)", (long)n); } #endif errno = old_errno; return cp; } #endif // DMALLOC void * mem_alloc_clear(size_t n) { void *cp = mem_alloc(n); memset(cp, 0, n); return cp; } #ifdef DMALLOC void * dmem_alloc_clear(const char *file, int line, size_t n) { void *cp = dmem_alloc(file, line, n); memset(cp, 0, n); return cp; } #endif // DMALLOC void mem_free(void *cp) { free(cp); } #ifdef DMALLOC void dmem_free(const char *file, int line, void *cp) { dmalloc_free(file, line, cp, DMALLOC_FUNC_FREE); } #endif // DMALLOC char * mem_copy_string(const char *s, size_t len) { char *cp = (char *)mem_alloc(len + 1); if (len) memcpy(cp, s, len); cp[len] = 0; return cp; } #ifdef DMALLOC char * dmem_copy_string(const char *file, int line, const char *s, size_t len) { char *cp = (char *)dmem_alloc(file, line, len + 1); if (len) memcpy(cp, s, len); cp[len] = 0; return cp; } #endif // DMALLOC char * mem_copy_string(const char *s) { return mem_copy_string(s, (s ? strlen(s) : 0)); } #ifdef DMALLOC char * dmem_copy_string(const char *file, int line, const char *s) { return dmem_copy_string(file, line, s, (s ? strlen(s) : 0)); } #endif // DMALLOC void * operator new(size_t nbytes) THROW_BAD_ALLOC { return mem_alloc(nbytes); } #ifdef DMALLOC void * operator new(size_t nbytes, const char *file, int line) THROW_BAD_ALLOC { return dmem_alloc(file, line, nbytes); } #endif // DMALLOC void * operator new[](size_t nbytes) THROW_BAD_ALLOC { return mem_alloc(nbytes); } #ifdef DMALLOC void * operator new[](size_t nbytes, const char *file, int line) THROW_BAD_ALLOC { return dmem_alloc(file, line, nbytes); } #endif // DMALLOC void operator delete(void *ptr) throw() { if (ptr) mem_free(ptr); } #ifdef DMALLOC void operator delete(void *ptr, const char *file, int line) throw() { if (ptr) dmem_free(file, line, ptr); } #endif // DMALLOC void operator delete[](void *ptr) throw() { if (ptr) mem_free(ptr); } #ifdef DMALLOC void operator delete[](void *ptr, const char *file, int line) throw() { if (ptr) dmem_free(file, line, ptr); } #endif // DMALLOC #if HAVE_HEADER_NEW || HAVE_NEW_H void * operator new(size_t nbytes, std::nothrow_t &) throw() { return mem_alloc(nbytes); } #ifdef DMALLOC void * operator new(size_t nbytes, std::nothrow_t &, const char *file, int line) throw() { return dmem_alloc(file, line, nbytes); } #endif // DMALLOC void * operator new[](size_t nbytes, std::nothrow_t &) throw() { return mem_alloc(nbytes); } void operator delete(void *ptr, std::nothrow_t const &) throw() { if (ptr) mem_free(ptr); } #ifdef DMALLOC void operator delete(void *ptr, std::nothrow_t const &, const char *file, int line) throw() { if (ptr) dmem_free(file, line, ptr); } #endif // DMALLOC void operator delete[](void *ptr, std::nothrow_t const &) throw() { if (ptr) mem_free(ptr); } #ifdef DMALLOC void operator delete[](void *ptr, std::nothrow_t const &, const char *file, int line) throw() { if (ptr) dmem_free(file, line, ptr); } #endif // DMALLOC #endif