[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20464] branches/soc-2007-joeedh/intern/ guardedalloc/intern/mallocn.c: bleh try to fix this file, which is different on my checkout then svn
Joseph Eagar
joeedh at gmail.com
Thu May 28 06:50:12 CEST 2009
Revision: 20464
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20464
Author: joeedh
Date: 2009-05-28 06:50:12 +0200 (Thu, 28 May 2009)
Log Message:
-----------
bleh try to fix this file, which is different on my checkout then svn
Added Paths:
-----------
branches/soc-2007-joeedh/intern/guardedalloc/intern/mallocn.c
Added: branches/soc-2007-joeedh/intern/guardedalloc/intern/mallocn.c
===================================================================
--- branches/soc-2007-joeedh/intern/guardedalloc/intern/mallocn.c (rev 0)
+++ branches/soc-2007-joeedh/intern/guardedalloc/intern/mallocn.c 2009-05-28 04:50:12 UTC (rev 20464)
@@ -0,0 +1,708 @@
+/**
+ * $Id: mallocn.c 17612 2008-11-29 09:56:22Z joeedh $
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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 2
+ * 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, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/**
+
+ * $Id: mallocn.c 17612 2008-11-29 09:56:22Z joeedh $
+ * Copyright (C) 2001 NaN Technologies B.V.
+ * Guarded memory allocation, and boundary-write detection.
+ */
+
+#include <stdlib.h>
+#include <string.h> /* memcpy */
+#include <stdarg.h>
+
+/* mmap exception */
+#if defined(AMIGA) || defined(__BeOS)
+#elif defined(WIN32)
+#include <sys/types.h>
+#include "mmap_win.h"
+#else
+#include <sys/types.h>
+#include <sys/mman.h>
+#endif
+
+#include "MEM_guardedalloc.h"
+
+/* --------------------------------------------------------------------- */
+/* local functions */
+/* --------------------------------------------------------------------- */
+
+static void addtail(volatile localListBase *listbase, void *vlink);
+static void remlink(volatile localListBase *listbase, void *vlink);
+static void rem_memblock(MemHead *memh);
+static void MemorY_ErroR(const char *block, const char *error);
+static const char *check_memlist(MemHead *memh);
+
+/* --------------------------------------------------------------------- */
+/* locally used defines */
+/* --------------------------------------------------------------------- */
+
+#if defined( __sgi) || defined (__sun) || defined (__sun__) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || (defined (__APPLE__) && !defined(__LITTLE_ENDIAN__))
+#define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) )
+#else
+#define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) )
+#endif
+
+#define MEMTAG1 MAKE_ID('M', 'E', 'M', 'O')
+#define MEMTAG2 MAKE_ID('R', 'Y', 'B', 'L')
+#define MEMTAG3 MAKE_ID('O', 'C', 'K', '!')
+#define MEMFREE MAKE_ID('F', 'R', 'E', 'E')
+
+#define MEMNEXT(x) ((MemHead *)(((char *) x) - ((char *) & (((MemHead *)0)->next))))
+
+/* --------------------------------------------------------------------- */
+/* vars */
+/* --------------------------------------------------------------------- */
+
+
+static volatile int totblock= 0;
+static volatile uintptr_t mem_in_use= 0, mmap_in_use= 0;
+
+static volatile struct localListBase _membase;
+static volatile struct localListBase *membase = &_membase;
+static void (*error_callback)(char *) = NULL;
+static void (*thread_lock_callback)(void) = NULL;
+static void (*thread_unlock_callback)(void) = NULL;
+
+static int malloc_debug_memset= 0;
+
+#ifdef malloc
+#undef malloc
+#endif
+
+#ifdef calloc
+#undef calloc
+#endif
+
+#ifdef free
+#undef free
+#endif
+
+
+/* --------------------------------------------------------------------- */
+/* implementation */
+/* --------------------------------------------------------------------- */
+
+static void print_error(const char *str, ...)
+{
+ char buf[1024];
+ va_list ap;
+
+ va_start(ap, str);
+ vsprintf(buf, str, ap);
+ va_end(ap);
+
+ if (error_callback) error_callback(buf);
+}
+
+static void mem_lock_thread()
+{
+ if (thread_lock_callback)
+ thread_lock_callback();
+}
+
+static void mem_unlock_thread()
+{
+ if (thread_unlock_callback)
+ thread_unlock_callback();
+}
+
+int MEM_check_memory_integrity()
+{
+ const char* err_val = NULL;
+ MemHead* listend;
+ /* check_memlist starts from the front, and runs until it finds
+ * the requested chunk. For this test, that's the last one. */
+ listend = membase->last;
+
+ err_val = check_memlist(listend);
+
+ if (err_val == 0) return 0;
+ return 1;
+}
+
+
+void MEM_set_error_callback(void (*func)(char *))
+{
+ error_callback = func;
+}
+
+void MEM_set_lock_callback(void (*lock)(void), void (*unlock)(void))
+{
+ thread_lock_callback = lock;
+ thread_unlock_callback = unlock;
+}
+
+void MEM_set_memory_debug(void)
+{
+ malloc_debug_memset= 1;
+}
+
+int MEM_allocN_len(void *vmemh)
+{
+ if (vmemh) {
+ MemHead *memh= vmemh;
+
+ memh--;
+ return memh->len;
+ } else
+ return 0;
+}
+
+void *MEM_dupallocN(void *vmemh)
+{
+ void *newp= NULL;
+
+ if (vmemh) {
+ MemHead *memh= vmemh;
+ memh--;
+
+ if(memh->mmap)
+ newp= MEM_mapallocN(memh->len, "dupli_mapalloc");
+ else
+ newp= MEM_mallocN(memh->len, "dupli_alloc");
+
+ if (newp == NULL) return NULL;
+
+ memcpy(newp, vmemh, memh->len);
+ }
+
+ return newp;
+}
+
+static void make_memhead_header(MemHead *memh, unsigned int len, const char *str)
+{
+ MemTail *memt;
+
+ memh->tag1 = MEMTAG1;
+ memh->name = str;
+ memh->nextname = 0;
+ memh->len = len;
+ memh->mmap = 0;
+ memh->tag2 = MEMTAG2;
+
+ memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len);
+ memt->tag3 = MEMTAG3;
+
+ addtail(membase,&memh->next);
+ if (memh->next) memh->nextname = MEMNEXT(memh->next)->name;
+
+ totblock++;
+ mem_in_use += len;
+}
+
+void *MEM_mallocN(unsigned int len, const char *str)
+{
+ MemHead *memh;
+
+ mem_lock_thread();
+
+ len = (len + 3 ) & ~3; /* allocate in units of 4 */
+
+ memh= (MemHead *)malloc(len+sizeof(MemHead)+sizeof(MemTail));
+
+ if(memh) {
+ make_memhead_header(memh, len, str);
+ mem_unlock_thread();
+ if(malloc_debug_memset && len)
+ memset(memh+1, 255, len);
+ return (++memh);
+ }
+ mem_unlock_thread();
+ print_error("Malloc returns nill: len=%d in %s, total %u\n",len, str, mem_in_use);
+ return NULL;
+}
+
+void *MEM_callocN(unsigned int len, const char *str)
+{
+ MemHead *memh;
+
+ mem_lock_thread();
+
+ len = (len + 3 ) & ~3; /* allocate in units of 4 */
+
+ memh= (MemHead *)calloc(len+sizeof(MemHead)+sizeof(MemTail),1);
+
+ if(memh) {
+ make_memhead_header(memh, len, str);
+ mem_unlock_thread();
+ return (++memh);
+ }
+ mem_unlock_thread();
+ print_error("Calloc returns nill: len=%d in %s, total %u\n",len, str, mem_in_use);
+ return 0;
+}
+
+/* note; mmap returns zero'd memory */
+void *MEM_mapallocN(unsigned int len, const char *str)
+{
+#if defined(AMIGA) || defined(__BeOS)
+ return MEM_callocN(len, str);
+#else
+ MemHead *memh;
+
+ mem_lock_thread();
+
+ len = (len + 3 ) & ~3; /* allocate in units of 4 */
+
+#ifdef __sgi
+ {
+#include <fcntl.h>
+
+ int fd;
+ fd = open("/dev/zero", O_RDWR);
+
+ memh= mmap(0, len+sizeof(MemHead)+sizeof(MemTail),
+ PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ close(fd);
+ }
+#else
+ memh= mmap(0, len+sizeof(MemHead)+sizeof(MemTail),
+ PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
+#endif
+
+ if(memh!=(MemHead *)-1) {
+ make_memhead_header(memh, len, str);
+ memh->mmap= 1;
+ mmap_in_use += len;
+ mem_unlock_thread();
+ return (++memh);
+ }
+ else {
+ mem_unlock_thread();
+ print_error("Mapalloc returns nill, fallback to regular malloc: len=%d in %s, total %u\n",len, str, mmap_in_use);
+ return MEM_callocN(len, str);
+ }
+#endif
+}
+
+/* Memory statistics print */
+typedef struct MemPrintBlock {
+ const char *name;
+ uintptr_t len;
+ int items;
+} MemPrintBlock;
+
+static int compare_name(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1= (const MemPrintBlock*)p1;
+ const MemPrintBlock *pb2= (const MemPrintBlock*)p2;
+
+ return strcmp(pb1->name, pb2->name);
+}
+
+static int compare_len(const void *p1, const void *p2)
+{
+ const MemPrintBlock *pb1= (const MemPrintBlock*)p1;
+ const MemPrintBlock *pb2= (const MemPrintBlock*)p2;
+
+ if(pb1->len < pb2->len)
+ return 1;
+ else if(pb1->len == pb2->len)
+ return 0;
+ else
+ return -1;
+}
+
+void MEM_printmemlist_stats()
+{
+ MemHead *membl;
+ MemPrintBlock *pb, *printblock;
+ int totpb, a, b;
+
+ mem_lock_thread();
+
+ /* put memory blocks into array */
+ printblock= malloc(sizeof(MemPrintBlock)*totblock);
+
+ pb= printblock;
+ totpb= 0;
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ while(membl) {
+ pb->name= membl->name;
+ pb->len= membl->len;
+ pb->items= 1;
+
+ totpb++;
+ pb++;
+
+ if(membl->next)
+ membl= MEMNEXT(membl->next);
+ else break;
+ }
+
+ /* sort by name and add together blocks with the same name */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_name);
+ for(a=0, b=0; a<totpb; a++) {
+ if(a == b) {
+ continue;
+ }
+ else if(strcmp(printblock[a].name, printblock[b].name) == 0) {
+ printblock[b].len += printblock[a].len;
+ printblock[b].items++;
+ }
+ else {
+ b++;
+ memcpy(&printblock[b], &printblock[a], sizeof(MemPrintBlock));
+ }
+ }
+ totpb= b+1;
+
+ /* sort by length and print */
+ qsort(printblock, totpb, sizeof(MemPrintBlock), compare_len);
+ printf("\ntotal memory len: %.3f MB\n", (double)mem_in_use/(double)(1024*1024));
+ for(a=0, pb=printblock; a<totpb; a++, pb++)
+ printf("%s items: %d, len: %.3f MB\n", pb->name, pb->items, (double)pb->len/(double)(1024*1024));
+
+ free(printblock);
+
+ mem_unlock_thread();
+}
+
+/* Prints in python syntax for easy */
+static void MEM_printmemlist_internal( int pydict )
+{
+ MemHead *membl;
+
+ mem_lock_thread();
+
+ membl = membase->first;
+ if (membl) membl = MEMNEXT(membl);
+
+ if (pydict) {
+ print_error("# membase_debug.py\n");
+ print_error("membase = [\\\n");
+ }
+ while(membl) {
+ if (pydict) {
+ fprintf(stderr, "{'len':%i, 'name':'''%s''', 'pointer':'%p'},\\\n", membl->len, membl->name, membl+1);
+ } else {
+ print_error("%s len: %d %p\n",membl->name,membl->len, membl+1);
+ }
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list