[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