File: alloc.c

package info (click to toggle)
diablo 1.13-1
  • links: PTS
  • area: non-free
  • in suites: hamm
  • size: 804 kB
  • ctags: 875
  • sloc: ansic: 8,308; perl: 1,908; sh: 186; csh: 81; makefile: 67
file content (172 lines) | stat: -rw-r--r-- 3,819 bytes parent folder | download
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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

/*
 * LIB/ALLOC.C	- memory allocation
 *
 * These routines are used to allocate buffers with the express intent 
 * of being able to *truely* deallocate the memory when we free it.
 * malloc()/free() does not normally do this, which will bloat the binary
 * and cause inefficiencies on fork().
 *
 * If you are running a large number of incoming connections or outgoing
 * feeds, using either USE_ANON_MMAP or USE_FALL_MMAP is an absolute 
 * requirement.  If you are not, then it doesn't matter.
 *
 * USE_ANON_MMAP is supported on BSDish platforms.  It uses MAP_ANON to
 *		 allocate areas of swap-backed memory.
 *
 * USE_FALL_MMAP should be supported on all platforms.  It creates a file
 *		 in /tmp and maps it MAP_PRIVATE, then remove()s the file.
 *		 Since this is a private map, the file is not actually used
 *		 for backing store so there is no real filesystem overhead.
 *		 The memory winds up being swap-backed.
 *
 * If neither option is set, malloc/free is used.  This is not recommended
 * if you run more then 10 feeds.
 */

#include "defs.h"

Prototype void *pagealloc(int *psize, int bytes);
Prototype void pagefree(void *p, int bytes);
Prototype int ZoneFd;		/* only necessary for USE_FALL_MMAP */

static int PageSize;
static int PageMask;
int ZoneFd = -1;		/* only necessary for USE_FALL_MMAP */

#if USE_ANON_MMAP

/*
 * Our first choice is to use MAP_ANON if the system understands it
 */

void *
pagealloc(int *psize, int bytes)
{
    void *b;
    if (PageSize == 0) {
	PageSize = getpagesize();
	PageMask = PageSize - 1;
    }
    bytes = (bytes + PageMask) & ~PageMask;

    *psize = bytes;
    b = (void *)mmap((caddr_t)0, bytes, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0);
    if (b == NULL || b == (void *)-1) {
	syslog(LOG_EMERG, "mmap/allocation/1 failed: %s", strerror(errno));
	exit(1);
    }
    return(b);
}

void
pagefree(void *page, int bytes)
{
    bytes = (bytes + PageMask) & ~PageMask;
    if (page != NULL) {
	munmap((caddr_t)page, bytes);
    }
}

#else
#if USE_FALL_MMAP

/*
 * Our second choice is to use a MAP_PRIVATE file mmap()
 */

void *
pagealloc(int *psize, int bytes)
{
    void *b;

    if (PageSize == 0) {
	PageSize = getpagesize();
	PageMask = PageSize - 1;
    }
    bytes = (bytes + PageMask) & ~PageMask;

    if (ZoneFd < 0) {
	int i;
	int pid = (int)getpid();

	for (i = 0; i < 1000; ++i) {
	    char path[256];

	    sprintf(path, "/tmp/diablo.zone.%d.%d", pid, i);
	    if ((ZoneFd=open(path, O_CREAT|O_TRUNC|O_RDWR|O_EXCL, 0600)) >= 0){
		remove(path);
		break;
	    }
	}
	if (ZoneFd < 0) {
	    syslog(LOG_EMERG, "unable to create %dK zone file in /tmp: %s", 
		bytes / 1024,
		strerror(errno)
	    );
	    exit(1);
	}
	if (ftruncate(ZoneFd, bytes) < 0) {
	    syslog(LOG_EMERG, "unable to extend zone file in /tmp: %s", 
		strerror(errno)
	    );
	    exit(1);
	}
	fcntl(ZoneFd, F_SETFD, 1);	/* set close-on-exec */
    }

    *psize = bytes;
    b = (void *)mmap((caddr_t)0, bytes, PROT_READ|PROT_WRITE, MAP_PRIVATE, ZoneFd, 0);
    if (b == NULL || b == (void *)-1) {
	syslog(LOG_EMERG, "mmap/allocation/2 failed: %s", strerror(errno));
	exit(1);
    }
    return(b);
}

void
pagefree(void *page, int bytes)
{
    bytes = (bytes + PageMask) & ~PageMask;

    if (page != NULL) {
	munmap((caddr_t)page, bytes);
    }
}

#else

void *
pagealloc(int *psize, int bytes)
{
    void *b;

    if (PageSize == 0) {
	PageSize = getpagesize();
	PageMask = PageSize - 1;
    }
    bytes = (bytes + PageMask) & ~PageMask;

    *psize = bytes;
    b = malloc(bytes);
    if (b == NULL) {
	syslog(LOG_EMERG, "mmap/allocation/3 failed: %s", strerror(errno));
	exit(1);
    }
    bzero(b, bytes);
    return(b);
}

void
pagefree(void *page, int bytes)
{
    /* bytes = (bytes + PageMask) & ~PageMask; */

    if (page != NULL) {
	free(page);
    }
}

#endif
#endif