1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
1
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
2
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
3
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
4
|
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
5
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
6
|
* THE BSD LICENSE
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
7
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
8
|
* Redistribution and use in source and binary forms, with or without
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
9
|
* modification, are permitted provided that the following conditions are met:
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
10
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
11
|
* Redistributions of source code must retain the above copyright notice, this
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
12
|
* list of conditions and the following disclaimer.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
13
|
* Redistributions in binary form must reproduce the above copyright notice,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
14
|
* this list of conditions and the following disclaimer in the documentation
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
15
|
* and/or other materials provided with the distribution.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
16
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
17
|
* Neither the name of the nor the names of its contributors may be
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
18
|
* used to endorse or promote products derived from this software without
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
19
|
* specific prior written permission.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
20
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
21
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
22
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
23
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
24
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
25
|
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
26
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
27
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
28
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
29
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
30
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
31
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
32
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
33
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
34
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
35
|
* Generic pool handling routines.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
36
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
37
|
* These routines reduce contention on the heap and guard against
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
38
|
* memory leaks.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
39
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
40
|
* Thread warning:
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
41
|
* This implementation is thread safe. However, simultaneous
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
42
|
* mallocs/frees to the same "pool" are not safe. Do not share
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
43
|
* pools across multiple threads without providing your own
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
44
|
* synchronization.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
45
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
46
|
* Mike Belshe
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
47
|
* 11-20-95
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
48
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
49
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
50
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
51
|
//include "netsite.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
52
|
//include "systems.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
53
|
#include "systhr.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
54
|
#include "pool_pvt.h"
|
29
|
55
|
//include "ereport.h"
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
56
|
//include "base/session.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
57
|
//include "frame/req.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
58
|
//include "frame/http.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
59
|
#include "util.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
60
|
//include "base/crit.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
61
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
62
|
//include "base/dbtbase.h"
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
63
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
64
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
65
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
66
|
#include <stdlib.h>
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
67
|
#include <string.h>
|
339
|
68
|
#include <limits.h>
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
69
|
//define PERM_MALLOC malloc
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
70
|
//define PERM_FREE free
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
71
|
//define PERM_REALLOC realloc
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
72
|
//define PERM_CALLOC calloc
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
73
|
//define PERM_STRDUP strdup
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
74
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
75
|
/* Pool configuration parameters */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
76
|
static pool_config_t pool_config = POOL_CONFIG_INIT;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
77
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
78
|
/* Pool global statistics */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
79
|
static pool_global_stats_t pool_global_stats;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
80
|
|
415
|
81
|
/* ucx allocator pool class */
|
|
82
|
static cx_allocator_class pool_allocator_class = {
|
|
83
|
(void *(*)(void *,size_t )) pool_malloc,
|
|
84
|
(void *(*)(void *,void *, size_t )) pool_realloc,
|
|
85
|
(void *(*)(void *,size_t ,size_t )) pool_calloc,
|
|
86
|
(void (*)(void *, void *))pool_free
|
|
87
|
};
|
|
88
|
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
89
|
static int
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
90
|
pool_internal_init()
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
91
|
{
|
40
|
92
|
//if (pool_global_stats.lock == NULL) {
|
|
93
|
// pool_global_stats.lock = PR_NewLock(); // TODO: remove
|
|
94
|
//}
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
95
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
96
|
if (pool_config.block_size == 0) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
97
|
//ereport(LOG_INFORM, XP_GetAdminStr(DBT_poolInitInternalAllocatorDisabled_));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
98
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
99
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
100
|
return 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
101
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
102
|
|
339
|
103
|
#define POOL_MIN_BLOCKSIZE 128
|
|
104
|
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
105
|
NSAPI_PUBLIC int
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
106
|
pool_init(pblock *pb, Session *sn, Request *rq)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
107
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
108
|
//char *str_block_size = pblock_findval("block-size", pb);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
109
|
//char *str_pool_disable = pblock_findval("disable", pb);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
110
|
char *str_block_size = "16384";
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
111
|
char *str_pool_disable = "false";
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
112
|
int n;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
113
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
114
|
//printf("standard block size: %d\n", pool_config.block_size);
|
339
|
115
|
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
116
|
if (str_block_size != NULL) {
|
339
|
117
|
int64_t value;
|
|
118
|
if(!util_strtoint(str_block_size, &value)) {
|
|
119
|
log_ereport(LOG_MISCONFIG, "pool-init: param 'block-size' is not an integer");
|
|
120
|
return REQ_ABORTED;
|
|
121
|
}
|
|
122
|
if(value > INT_MAX) {
|
|
123
|
log_ereport(LOG_MISCONFIG, "pool-init: block-size is too big");
|
|
124
|
return REQ_ABORTED;
|
|
125
|
}
|
|
126
|
if(value < POOL_MIN_BLOCKSIZE) {
|
|
127
|
log_ereport(LOG_MISCONFIG, "pool-init: block-size is too small");
|
|
128
|
return REQ_ABORTED;
|
|
129
|
}
|
|
130
|
pool_config.block_size = value;
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
131
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
132
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
133
|
if (str_pool_disable && util_getboolean(str_pool_disable, PR_TRUE)) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
134
|
/* We'll call PERM_MALLOC() on each pool_malloc() call */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
135
|
pool_config.block_size = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
136
|
pool_config.retain_size = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
137
|
pool_config.retain_num = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
138
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
139
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
140
|
pool_internal_init();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
141
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
142
|
return REQ_PROCEED;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
143
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
144
|
|
415
|
145
|
CxAllocator* pool_allocator(pool_handle_t *pool) {
|
|
146
|
return &((pool_t *)pool)->allocator;
|
|
147
|
}
|
|
148
|
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
149
|
static block_t *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
150
|
_create_block(pool_t *pool, int size)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
151
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
152
|
block_t *newblock;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
153
|
char *newdata;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
154
|
block_t **blk_ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
155
|
long blen;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
156
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
157
|
/* Does the pool have any retained blocks on its free list? */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
158
|
for (blk_ptr = &pool->free_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
159
|
(newblock = *blk_ptr) != NULL; blk_ptr = &newblock->next) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
160
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
161
|
/* Yes, is this block large enough? */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
162
|
blen = newblock->end - newblock->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
163
|
if (blen >= size) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
164
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
165
|
/* Yes, take it off the free list */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
166
|
*blk_ptr = newblock->next;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
167
|
pool->free_size -= blen;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
168
|
--pool->free_num;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
169
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
170
|
/* Give the block to the caller */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
171
|
newblock->start = newblock->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
172
|
goto done;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
173
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
174
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
175
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
176
|
newblock = (block_t *)PERM_MALLOC(sizeof(block_t));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
177
|
newdata = (char *)PERM_MALLOC(size);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
178
|
if (newblock == NULL || (newdata == NULL && size != 0)) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
179
|
//ereport(LOG_CATASTROPHE,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
180
|
// XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
181
|
PERM_FREE(newblock);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
182
|
PERM_FREE(newdata);
|
29
|
183
|
//PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
184
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
185
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
186
|
newblock->data = newdata;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
187
|
newblock->start = newblock->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
188
|
newblock->end = newblock->data + size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
189
|
newblock->next = NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
190
|
blen = size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
191
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
192
|
#ifdef POOL_GLOBAL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
193
|
PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkAlloc);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
194
|
#endif /* POOL_GLOBAL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
195
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
196
|
done:
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
197
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
198
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
199
|
++pool->stats.blkAlloc;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
200
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
201
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
202
|
return newblock;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
203
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
204
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
205
|
static void
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
206
|
_free_block(block_t *block)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
207
|
{
|
71
|
208
|
#ifdef POOL_ZERO_DEBUG
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
209
|
long blen = block->end - block->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
210
|
memset(block->data, POOL_ZERO_DEBUG, blen);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
211
|
#endif /* POOL_ZERO_DEBUG */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
212
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
213
|
PERM_FREE(block->data);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
214
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
215
|
#ifdef POOL_ZERO_DEBUG
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
216
|
memset(block, POOL_ZERO_DEBUG, sizeof(block));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
217
|
#endif /* POOL_ZERO_DEBUG */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
218
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
219
|
PERM_FREE(block);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
220
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
221
|
#ifdef POOL_GLOBAL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
222
|
PR_AtomicIncrement((PRInt32 *)&pool_global_stats.blkFree);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
223
|
#endif /* POOL_GLOBAL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
224
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
225
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
226
|
/* ptr_in_pool()
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
227
|
* Checks to see if the given pointer is in the given pool.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
228
|
* If true, returns a ptr to the block_t containing the ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
229
|
* otherwise returns NULL
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
230
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
231
|
block_t *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
232
|
_ptr_in_pool(pool_t *pool, const void *ptr)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
233
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
234
|
block_t *block_ptr = NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
235
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
236
|
/* try to find a block which contains this ptr */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
237
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
238
|
if (POOL_PTR_IN_BLOCK(pool->curr_block, ptr)) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
239
|
block_ptr = pool->curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
240
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
241
|
else {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
242
|
for (block_ptr = pool->used_blocks; block_ptr; block_ptr = block_ptr->next) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
243
|
if (POOL_PTR_IN_BLOCK(block_ptr, ptr))
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
244
|
break;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
245
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
246
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
247
|
return block_ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
248
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
249
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
250
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
251
|
NSAPI_PUBLIC pool_handle_t *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
252
|
pool_create()
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
253
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
254
|
pool_t *newpool;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
255
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
256
|
newpool = (pool_t *)PERM_MALLOC(sizeof(pool_t));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
257
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
258
|
if (newpool) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
259
|
/* Have to initialize now, as pools get created sometimes
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
260
|
* before pool_init can be called...
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
261
|
*/
|
40
|
262
|
//if (pool_global_stats.lock == NULL) { // TODO: remove
|
|
263
|
// pool_internal_init();
|
|
264
|
//}
|
415
|
265
|
|
|
266
|
newpool->allocator.cl = &pool_allocator_class;
|
|
267
|
newpool->allocator.data = newpool;
|
|
268
|
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
269
|
newpool->used_blocks = NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
270
|
newpool->free_blocks = NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
271
|
newpool->free_size = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
272
|
newpool->free_num = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
273
|
newpool->size = 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
274
|
newpool->next = NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
275
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
276
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
277
|
/* Initial per pool statistics */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
278
|
memset((void *)(&newpool->stats), 0, sizeof(newpool->stats));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
279
|
newpool->stats.thread = PR_GetCurrentThread();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
280
|
newpool->stats.created = PR_Now();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
281
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
282
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
283
|
/* No need to lock, since pool has not been exposed yet */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
284
|
newpool->curr_block =_create_block(newpool, pool_config.block_size);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
285
|
if (newpool->curr_block == NULL) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
286
|
//ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
287
|
pool_destroy((pool_handle_t *)newpool);
|
29
|
288
|
//PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
289
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
290
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
291
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
292
|
/* Add to known pools list */
|
40
|
293
|
|
|
294
|
// NOTICE:
|
|
295
|
// known pools list removed
|
|
296
|
|
|
297
|
//PR_Lock(pool_global_stats.lock);
|
|
298
|
//newpool->next = pool_global_stats.poolList;
|
|
299
|
//pool_global_stats.poolList = newpool;
|
|
300
|
//++pool_global_stats.createCnt;
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
301
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
302
|
newpool->stats.poolId = pool_global_stats.createCnt;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
303
|
#endif /* PER_POOL_STATISTICS */
|
40
|
304
|
//PR_Unlock(pool_global_stats.lock);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
305
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
306
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
307
|
else {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
308
|
//ereport(LOG_CATASTROPHE, XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
|
29
|
309
|
//PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
310
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
311
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
312
|
return (pool_handle_t *)newpool;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
313
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
314
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
315
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
316
|
* pool_mark - get mark for subsequent recycle
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
317
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
318
|
* This function returns a value that can be used to free all pool
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
319
|
* memory which is subsequently allocated, without freeing memory
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
320
|
* that has already been allocated when pool_mark() is called.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
321
|
* The pool_recycle() function is used to free the memory allocated
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
322
|
* since pool_mark() was called.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
323
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
324
|
* This function may be called several times before pool_recycle()
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
325
|
* is called, but some care must be taken not to pass an invalid
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
326
|
* mark value to pool_recycle(), which would cause all pool memory
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
327
|
* to be freed. A mark value becomes invalid when pool_recycle is
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
328
|
* called with a previously returned mark value.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
329
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
330
|
NSAPI_PUBLIC void *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
331
|
pool_mark(pool_handle_t *pool_handle)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
332
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
333
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
334
|
|
40
|
335
|
//PR_ASSERT(pool != NULL);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
336
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
337
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
338
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
339
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
340
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
341
|
pool->stats.thread = PR_GetCurrentThread();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
342
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
343
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
344
|
/* Never return end as it points outside the block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
345
|
if (pool->curr_block->start == pool->curr_block->end)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
346
|
return pool->curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
347
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
348
|
return (void *)(pool->curr_block->start);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
349
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
350
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
351
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
352
|
* pool_recycle - recycle memory in a pool
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
353
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
354
|
* This function returns all the allocated memory for a pool back to
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
355
|
* a free list associated with the pool. It is like pool_destroy() in
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
356
|
* the sense that all data structures previously allocated from the
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
357
|
* pool are freed, but it keeps the memory associated with the pool,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
358
|
* and doesn't actually destroy the pool.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
359
|
*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
360
|
* The "mark" argument can be a value previously returned by
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
361
|
* pool_mark(), in which case the pool is returned to the state it
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
362
|
* was in when pool_mark() was called, or it can be NULL, in which
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
363
|
* case the pool is completely recycled.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
364
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
365
|
NSAPI_PUBLIC void
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
366
|
pool_recycle(pool_handle_t *pool_handle, void *mark)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
367
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
368
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
369
|
block_t *tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
370
|
unsigned long blen;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
371
|
|
40
|
372
|
//PR_ASSERT(pool != NULL);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
373
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
374
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
375
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
376
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
377
|
/* Fix up curr_block. There should always be a curr_block. */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
378
|
tmp_blk = pool->curr_block;
|
40
|
379
|
//PR_ASSERT(tmp_blk != NULL);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
380
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
381
|
/* Start with curr_block, then scan blocks on used_blocks list */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
382
|
for (;;) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
383
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
384
|
/* Check if the mark is at the end of this block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
385
|
if (tmp_blk == mark) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
386
|
pool->curr_block = tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
387
|
break;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
388
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
389
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
390
|
/* Look for a block containing the mark */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
391
|
if (POOL_PTR_IN_BLOCK(tmp_blk, mark)) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
392
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
393
|
/* Reset block start pointer to marked spot */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
394
|
if (tmp_blk == pool->curr_block) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
395
|
blen = tmp_blk->start - (char *)mark;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
396
|
} else {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
397
|
blen = tmp_blk->end - (char *)mark;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
398
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
399
|
pool->size -= blen;
|
40
|
400
|
//PR_ASSERT(pool->size >= 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
401
|
tmp_blk->start = (char *)mark;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
402
|
pool->curr_block = tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
403
|
break;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
404
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
405
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
406
|
/* Reset block start pointer to base of block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
407
|
if (tmp_blk == pool->curr_block) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
408
|
/* Count just the allocated length in the current block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
409
|
blen = tmp_blk->start - tmp_blk->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
410
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
411
|
else {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
412
|
/* Count the entire size of a used_block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
413
|
blen = tmp_blk->end - tmp_blk->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
414
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
415
|
tmp_blk->start = tmp_blk->data;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
416
|
pool->size -= blen;
|
40
|
417
|
//PR_ASSERT(pool->size >= 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
418
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
419
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
420
|
* If there are no more used blocks after this one, then set
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
421
|
* this block up as the current block and return.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
422
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
423
|
if (pool->used_blocks == NULL) {
|
40
|
424
|
//PR_ASSERT(mark == NULL);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
425
|
pool->curr_block = tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
426
|
break;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
427
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
428
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
429
|
/* Otherwise free this block one way or another */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
430
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
431
|
/* Add block length to total retained length and check limit */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
432
|
if ((pool->free_size + blen) <= pool_config.retain_size &&
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
433
|
pool->free_num < pool_config.retain_num) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
434
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
435
|
/* Retain block on pool free list */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
436
|
/*
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
437
|
* XXX hep - could sort blocks on free list in order
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
438
|
* ascending size to get "best fit" allocation in
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
439
|
* _create_block(), but the default block size is large
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
440
|
* enough that fit should rarely be an issue.
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
441
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
442
|
tmp_blk->next = pool->free_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
443
|
pool->free_blocks = tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
444
|
pool->free_size += blen;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
445
|
++pool->free_num;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
446
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
447
|
else {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
448
|
/* Limit exceeded - free block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
449
|
_free_block(tmp_blk);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
450
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
451
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
452
|
#ifdef PER_POOL_STATISTICS
|
40
|
453
|
//++pool->stats.blkFree;
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
454
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
455
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
456
|
/* Remove next block from used blocks list */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
457
|
tmp_blk = pool->used_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
458
|
pool->used_blocks = tmp_blk->next;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
459
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
460
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
461
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
462
|
NSAPI_PUBLIC void
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
463
|
pool_destroy(pool_handle_t *pool_handle)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
464
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
465
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
466
|
block_t *tmp_blk;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
467
|
|
40
|
468
|
//PR_ASSERT(pool != NULL);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
469
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
470
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
471
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
472
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
473
|
if (pool->curr_block)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
474
|
_free_block(pool->curr_block);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
475
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
476
|
while(pool->used_blocks) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
477
|
tmp_blk = pool->used_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
478
|
pool->used_blocks = tmp_blk->next;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
479
|
_free_block(tmp_blk);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
480
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
481
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
482
|
while(pool->free_blocks) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
483
|
tmp_blk = pool->free_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
484
|
pool->free_blocks = tmp_blk->next;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
485
|
_free_block(tmp_blk);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
486
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
487
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
488
|
{
|
71
|
489
|
//pool_t **ppool;
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
490
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
491
|
/* Remove from the known pools list */
|
40
|
492
|
// NOTICE: known pools list removed
|
|
493
|
/*
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
494
|
PR_Lock(pool_global_stats.lock);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
495
|
for (ppool = &pool_global_stats.poolList;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
496
|
*ppool; ppool = &(*ppool)->next) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
497
|
if (*ppool == pool) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
498
|
++pool_global_stats.destroyCnt;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
499
|
*ppool = pool->next;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
500
|
break;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
501
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
502
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
503
|
PR_Unlock(pool_global_stats.lock);
|
40
|
504
|
*/
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
505
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
506
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
507
|
#ifdef POOL_ZERO_DEBUG
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
508
|
memset(pool, POOL_ZERO_DEBUG, sizeof(pool));
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
509
|
#endif /* POOL_ZERO_DEBUG */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
510
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
511
|
PERM_FREE(pool);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
512
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
513
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
514
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
515
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
516
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
517
|
NSAPI_PUBLIC void *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
518
|
pool_malloc(pool_handle_t *pool_handle, size_t size)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
519
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
520
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
521
|
block_t *curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
522
|
long reqsize, blocksize;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
523
|
char *ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
524
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
525
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
526
|
return PERM_MALLOC(size);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
527
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
528
|
reqsize = ALIGN(size);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
529
|
if (reqsize == 0) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
530
|
/* Assign a unique address to each 0-byte allocation */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
531
|
reqsize = WORD_SIZE;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
532
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
533
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
534
|
curr_block = pool->curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
535
|
ptr = curr_block->start;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
536
|
curr_block->start += reqsize;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
537
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
538
|
/* does this fit into the last allocated block? */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
539
|
if (curr_block->start > curr_block->end) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
540
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
541
|
/* Did not fit; time to allocate a new block */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
542
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
543
|
curr_block->start -= reqsize; /* keep structs in tact */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
544
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
545
|
/* Count unallocated bytes in current block in pool size */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
546
|
pool->size += curr_block->end - curr_block->start;
|
40
|
547
|
//PR_ASSERT(pool->size >= 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
548
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
549
|
if (pool->size > pool->stats.maxAlloc) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
550
|
pool->stats.maxAlloc = pool->size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
551
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
552
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
553
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
554
|
/* Move current block to used block list */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
555
|
curr_block->next = pool->used_blocks;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
556
|
pool->used_blocks = curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
557
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
558
|
/* Allocate a chunk of memory which is at least block_size bytes */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
559
|
blocksize = reqsize;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
560
|
if (blocksize < pool_config.block_size)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
561
|
blocksize = pool_config.block_size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
562
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
563
|
curr_block = _create_block(pool, blocksize);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
564
|
pool->curr_block = curr_block;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
565
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
566
|
if (curr_block == NULL) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
567
|
//ereport(LOG_CATASTROPHE,
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
568
|
// XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
|
29
|
569
|
//PR_SetError(PR_OUT_OF_MEMORY_ERROR, 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
570
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
571
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
572
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
573
|
ptr = curr_block->start;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
574
|
curr_block->start += reqsize;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
575
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
576
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
577
|
pool->size += reqsize;
|
40
|
578
|
//PR_ASSERT(pool->size >= 0);
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
579
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
580
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
581
|
if (pool->size > pool->stats.maxAlloc) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
582
|
pool->stats.maxAlloc = pool->size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
583
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
584
|
++pool->stats.allocCnt;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
585
|
pool->stats.thread = PR_GetCurrentThread();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
586
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
587
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
588
|
return ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
589
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
590
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
591
|
NSAPI_PUBLIC void
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
592
|
pool_free(pool_handle_t *pool_handle, void *ptr)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
593
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
594
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
595
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
596
|
if (ptr == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
597
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
598
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
599
|
if (pool == NULL) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
600
|
PERM_FREE(ptr);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
601
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
602
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
603
|
|
40
|
604
|
//PR_ASSERT(_ptr_in_pool(pool, ptr));
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
605
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
606
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
607
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
608
|
++pool->stats.freeCnt;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
609
|
pool->stats.thread = PR_GetCurrentThread();
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
610
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
611
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
612
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
613
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
614
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
615
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
616
|
NSAPI_PUBLIC void *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
617
|
pool_calloc(pool_handle_t *pool_handle, size_t nelem, size_t elsize)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
618
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
619
|
void *ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
620
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
621
|
if (pool_handle == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
622
|
return calloc(1, elsize * nelem);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
623
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
624
|
ptr = pool_malloc(pool_handle, elsize * nelem);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
625
|
if (ptr)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
626
|
memset(ptr, 0, elsize * nelem);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
627
|
return ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
628
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
629
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
630
|
NSAPI_PUBLIC void *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
631
|
pool_realloc(pool_handle_t *pool_handle, void *ptr, size_t size)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
632
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
633
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
634
|
void *newptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
635
|
block_t *block_ptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
636
|
size_t oldsize;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
637
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
638
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
639
|
return PERM_REALLOC(ptr, size);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
640
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
641
|
if ( (newptr = pool_malloc(pool_handle, size)) == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
642
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
643
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
644
|
/* With our structure we don't know exactly where the end
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
645
|
* of the original block is. But we do know an upper bound
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
646
|
* which is a valid ptr. Search the outstanding blocks
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
647
|
* for the block which contains this ptr, and copy...
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
648
|
*/
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
649
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
650
|
if ( !(block_ptr = _ptr_in_pool(pool, ptr)) ) {
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
651
|
/* User is trying to realloc nonmalloc'd space! */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
652
|
return newptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
653
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
654
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
655
|
oldsize = block_ptr->end - (char *)ptr ;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
656
|
if (oldsize > size)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
657
|
oldsize = size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
658
|
memmove((char *)newptr, (char *)ptr, oldsize);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
659
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
660
|
return newptr;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
661
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
662
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
663
|
NSAPI_PUBLIC char *
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
664
|
pool_strdup(pool_handle_t *pool_handle, const char *orig_str)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
665
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
666
|
char *new_str;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
667
|
int len = strlen(orig_str);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
668
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
669
|
if (pool_handle == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
670
|
return PERM_STRDUP(orig_str);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
671
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
672
|
new_str = (char *)pool_malloc(pool_handle, len+1);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
673
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
674
|
if (new_str)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
675
|
memcpy(new_str, orig_str, len+1);
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
676
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
677
|
return new_str;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
678
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
679
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
680
|
NSAPI_PUBLIC long
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
681
|
pool_space(pool_handle_t *pool_handle)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
682
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
683
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
684
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
685
|
return pool->size;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
686
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
687
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
688
|
NSAPI_PUBLIC int pool_enabled()
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
689
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
690
|
if (getThreadMallocKey() == -1)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
691
|
return 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
692
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
693
|
if (!systhread_getdata(getThreadMallocKey()))
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
694
|
return 0;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
695
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
696
|
return 1;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
697
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
698
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
699
|
#ifdef DEBUG
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
700
|
NSAPI_PUBLIC void INTpool_assert(pool_handle_t *pool_handle, const void *ptr)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
701
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
702
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
703
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
704
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
705
|
return;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
706
|
|
40
|
707
|
//PR_ASSERT(_ptr_in_pool(pool, ptr));
|
1
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
708
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
709
|
#endif
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
710
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
711
|
NSAPI_PUBLIC pool_config_t *pool_getConfig(void)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
712
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
713
|
return &pool_config;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
714
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
715
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
716
|
#ifdef POOL_GLOBAL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
717
|
NSAPI_PUBLIC pool_global_stats_t *pool_getGlobalStats(void)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
718
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
719
|
return &pool_global_stats;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
720
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
721
|
#endif /* POOL_GLOBAL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
722
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
723
|
#ifdef PER_POOL_STATISTICS
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
724
|
NSAPI_PUBLIC pool_stats_t *pool_getPoolStats(pool_handle_t *pool_handle)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
725
|
{
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
726
|
pool_t *pool = (pool_t *)pool_handle;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
727
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
728
|
if (pool == NULL)
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
729
|
return NULL;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
730
|
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
731
|
return &pool->stats;
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
732
|
}
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
733
|
#endif /* PER_POOL_STATISTICS */
|
Olaf Wintermann <olaf.wintermann@gmail.com>
parents:
diff
changeset
|
734
|
|
91
|
735
|
// new
|
415
|
736
|
cxmutstr cx_strdup_pool(pool_handle_t *pool, cxmutstr s) {
|
|
737
|
cxmutstr newstring;
|
91
|
738
|
newstring.ptr = (char*)pool_malloc(pool, s.length + 1);
|
|
739
|
if (newstring.ptr != NULL) {
|
|
740
|
newstring.length = s.length;
|
|
741
|
newstring.ptr[newstring.length] = 0;
|
|
742
|
|
|
743
|
memcpy(newstring.ptr, s.ptr, s.length);
|
|
744
|
}
|
|
745
|
|
|
746
|
return newstring;
|
|
747
|
}
|
|
748
|
|