File: smartmem.C

package info (click to toggle)
mixviews 1.10-3
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 2,440 kB
  • ctags: 6,314
  • sloc: cpp: 31,647; ansic: 2,100; makefile: 1,782; sh: 17
file content (131 lines) | stat: -rw-r--r-- 3,669 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// smartmem.C

/******************************************************************************
 *
 *  MiXViews - an X window system based sound & data editor/processor
 *
 *  Copyright (c) 1993, 1994 Regents of the University of California
 *
 *  Author:     Douglas Scott
 *  Date:       December 13, 1994
 *
 *  Permission to use, copy and modify this software and its documentation
 *  for research and/or educational purposes and without fee is hereby granted,
 *  provided that the above copyright notice appear in all copies and that
 *  both that copyright notice and this permission notice appear in
 *  supporting documentation. The author reserves the right to distribute this
 *  software and its documentation.  The University of California and the author
 *  make no representations about the suitability of this software for any 
 *  purpose, and in no event shall University of California be liable for any
 *  damage, loss of data, or profits resulting from its use.
 *  It is provided "as is" without express or implied warranty.
 *
 ******************************************************************************/

#include "application.h"
#include "localdefs.h"
#include "smartmem.h"
#ifdef NeXT
#include <m68k/math.h>
#else
#include <values.h>
#endif


unsigned SmartMemory::totalBytes_Allocated = 0;
unsigned SmartMemory::max_TotalAllocation = unsigned(2.0e+08);	// 200 Mb.
unsigned SmartMemory::max_SingleAllocation = unsigned(1.0e+08);	// 100 Mb.

void
SmartMemory::setMaxTotalAllocation(unsigned maxTot) {
	max_TotalAllocation = maxTot;
}

void
SmartMemory::setMaxSingleAllocation(unsigned maxSingle) {
	max_SingleAllocation = maxSingle;
}

void *
SmartMemory::allocate(unsigned* size) {
	void* mem = 0;
	if(isLegalAllocation(*size)) {
		if((mem = calloc(*size, 1)) != 0)
			totalBytes_Allocated += *size;
		else {
			Application::error("Memory allocation failure:");
			*size = 0;
		}
	}
	else *size = 0;
	return mem;
}

void
SmartMemory::free(void* ptr, unsigned size) {
	if(ptr) {
		::cfree(ptr);
		totalBytes_Allocated -= size;
	}
}

void*
SmartMemory::changeAllocation(void* ptr, unsigned oldSize, unsigned* size) {
	void* oldMem = ptr;
	int delta = 0;
	if(*size < oldSize)					// deallocating
		delta = int(*size) - int(oldSize);
	else {								// allocating
		delta = int(*size - oldSize);
		if(delta < 0) delta = MAXINT;	// check for int overflow
	}
	if(delta < 0 || isLegalAllocation(delta)) {
		if((ptr = realloc(ptr, *size)) != 0) {
			totalBytes_Allocated += delta;
			if(delta > 0)
				zero(addr(ptr) + oldSize, delta);	// zero out extended space
		}
		else {
			Application::error("Memory reallocation failure:");
			ptr = oldMem;
			*size = oldSize;
		}
	}
	else *size = oldSize;
	return ptr;
}

void*
SmartMemory::zero(void* ptr, unsigned size, int zero) {
	if(ptr)
		memset(ptr, zero, size);
	return ptr;
}

void*
SmartMemory::copy(void* from, void* to, unsigned size) {
	if(from != nil && to != nil)
		bcopy(from, to, size);
	return to;
}

int
SmartMemory::isLegalAllocation(unsigned size) {
	int status = false;
	char msg[120];
	const float million = 1.0e+06;
	if(size > maxSingleAllocation()) {
		sprintf(msg, "Request for %.2fmB exceeds current limit (%.2fmB).",
			size/million, maxSingleAllocation()/million);
		status = Application::confirm("Memory limit alert:",
			msg, "Attempt anyway?");
	}
	else if(totalBytes_Allocated + size > maxTotalAllocation()) {
		sprintf(msg, "Request for %.2fmB goes beyond current total allocation limit (%.2fmB).",
			size/million, maxTotalAllocation()/million);
		status = Application::confirm("Memory limit alert:",
			msg, "Attempt anyway?");
	}
	else status = true;	
	return status;
}