]> git.ipfire.org Git - thirdparty/squid.git/blame - src/stmem.cc
Mucking about with storeAbort. Removed squid_error_entry() (need
[thirdparty/squid.git] / src / stmem.cc
CommitLineData
df92bd2a 1
30a4f2a8 2/*
a3d5953d 3 * $Id: stmem.cc,v 1.43 1997/06/04 06:16:10 wessels Exp $
30a4f2a8 4 *
5 * DEBUG: section 19 Memory Primitives
6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
30a4f2a8 9 * --------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
13 * National Laboratory for Applied Network Research and funded by
14 * the National Science Foundation.
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 *
30 */
019dd986 31
30a4f2a8 32/*
33 * Copyright (c) 1994, 1995. All rights reserved.
34 *
35 * The Harvest software was developed by the Internet Research Task
36 * Force Research Group on Resource Discovery (IRTF-RD):
37 *
38 * Mic Bowman of Transarc Corporation.
39 * Peter Danzig of the University of Southern California.
40 * Darren R. Hardy of the University of Colorado at Boulder.
41 * Udi Manber of the University of Arizona.
42 * Michael F. Schwartz of the University of Colorado at Boulder.
43 * Duane Wessels of the University of Colorado at Boulder.
44 *
45 * This copyright notice applies to software in the Harvest
46 * ``src/'' directory only. Users should consult the individual
47 * copyright notices in the ``components/'' subdirectories for
48 * copyright information about other software bundled with the
49 * Harvest source code distribution.
50 *
51 * TERMS OF USE
52 *
53 * The Harvest software may be used and re-distributed without
54 * charge, provided that the software origin and research team are
55 * cited in any use of the system. Most commonly this is
56 * accomplished by including a link to the Harvest Home Page
57 * (http://harvest.cs.colorado.edu/) from the query page of any
58 * Broker you deploy, as well as in the query result pages. These
59 * links are generated automatically by the standard Broker
60 * software distribution.
61 *
62 * The Harvest software is provided ``as is'', without express or
63 * implied warranty, and with no support nor obligation to assist
64 * in its use, correction, modification or enhancement. We assume
65 * no liability with respect to the infringement of copyrights,
66 * trade secrets, or any patents, and are not responsible for
67 * consequential damages. Proper use of the Harvest software is
68 * entirely the responsibility of the user.
69 *
70 * DERIVATIVE WORKS
71 *
72 * Users may make derivative works from the Harvest software, subject
73 * to the following constraints:
74 *
75 * - You must include the above copyright notice and these
76 * accompanying paragraphs in all forms of derivative works,
77 * and any documentation and other materials related to such
78 * distribution and use acknowledge that the software was
79 * developed at the above institutions.
80 *
81 * - You must notify IRTF-RD regarding your distribution of
82 * the derivative work.
83 *
84 * - You must clearly notify users that your are distributing
85 * a modified version and not the original Harvest software.
86 *
87 * - Any derivative product is also subject to these copyright
88 * and use restrictions.
89 *
90 * Note that the Harvest software is NOT in the public domain. We
91 * retain copyright, as specified above.
92 *
93 * HISTORY OF FREE SOFTWARE STATUS
94 *
95 * Originally we required sites to license the software in cases
96 * where they were going to build commercial products/services
97 * around Harvest. In June 1995 we changed this policy. We now
98 * allow people to use the core Harvest software (the code found in
99 * the Harvest ``src/'' directory) for free. We made this change
100 * in the interest of encouraging the widest possible deployment of
101 * the technology. The Harvest software is really a reference
102 * implementation of a set of protocols and formats, some of which
103 * we intend to standardize. We encourage commercial
104 * re-implementations of code complying to this set of standards.
019dd986 105 */
ed43818f 106
44a47c6e 107#include "squid.h"
090089c4 108
1750e760 109stmem_stats sm_stats;
110stmem_stats disk_stats;
30a4f2a8 111stmem_stats request_pool;
112stmem_stats mem_obj_pool;
090089c4 113
114#define min(x,y) ((x)<(y)? (x) : (y))
115
116#ifndef USE_MEMALIGN
117#define USE_MEMALIGN 0
118#endif
119
24382924 120static void *get_free_thing _PARAMS((stmem_stats *));
121static void put_free_thing _PARAMS((stmem_stats *, void *));
122static void stmemFreeThingMemory _PARAMS((stmem_stats *));
7ecd0a2f 123
d89d1fb6 124void
b8d8561b 125memFree(mem_ptr mem)
090089c4 126{
127 mem_node lastp, p = mem->head;
128
129 if (p) {
130 while (p && (p != mem->tail)) {
131 lastp = p;
132 p = p->next;
133 if (lastp) {
2daae136 134 put_free_4k_page(lastp->data);
090089c4 135 safe_free(lastp);
136 }
137 }
138
139 if (p) {
2daae136 140 put_free_4k_page(p->data);
090089c4 141 safe_free(p);
142 }
143 }
144 memset(mem, '\0', sizeof(mem_ptr)); /* nuke in case ref'ed again */
145 safe_free(mem);
146}
147
38f0f5d4 148#ifdef UNUSED_CODE
d89d1fb6 149void
b8d8561b 150memFreeData(mem_ptr mem)
090089c4 151{
152 mem_node lastp, p = mem->head;
090089c4 153 while (p != mem->tail) {
154 lastp = p;
155 p = p->next;
2daae136 156 put_free_4k_page(lastp->data);
090089c4 157 safe_free(lastp);
158 }
090089c4 159 if (p != NULL) {
2daae136 160 put_free_4k_page(p->data);
090089c4 161 safe_free(p);
162 p = NULL;
163 }
164 mem->head = mem->tail = NULL; /* detach in case ref'd */
165 mem->origin_offset = 0;
166}
38f0f5d4 167#endif
090089c4 168
d89d1fb6 169int
b8d8561b 170memFreeDataUpto(mem_ptr mem, int target_offset)
090089c4 171{
172 int current_offset = mem->origin_offset;
173 mem_node lastp, p = mem->head;
174
175 while (p && ((current_offset + p->len) <= target_offset)) {
176 if (p == mem->tail) {
177 /* keep the last one to avoid change to other part of code */
178 mem->head = mem->tail;
179 mem->origin_offset = current_offset;
180 return current_offset;
181 } else {
182 lastp = p;
183 p = p->next;
184 current_offset += lastp->len;
2daae136 185 put_free_4k_page(lastp->data);
090089c4 186 safe_free(lastp);
187 }
188 }
189
190 mem->head = p;
191 mem->origin_offset = current_offset;
192 if (current_offset < target_offset) {
193 /* there are still some data left. */
194 return current_offset;
195 }
196 if (current_offset != target_offset) {
a3d5953d 197 debug(19, 1) ("memFreeDataUpto: This shouldn't happen. Some odd condition.\n");
198 debug(19, 1) (" Current offset: %d Target offset: %d p: %p\n",
090089c4 199 current_offset, target_offset, p);
200 }
201 return current_offset;
090089c4 202}
203
204
205/* Append incoming data. */
e6e5d90d 206void
0ee4272b 207memAppend(mem_ptr mem, const char *data, int len)
090089c4 208{
209 mem_node p;
210 int avail_len;
211 int len_to_copy;
212
a3d5953d 213 debug(19, 6) ("memAppend: len %d\n", len);
090089c4 214
215 /* Does the last block still contain empty space?
216 * If so, fill out the block before dropping into the
217 * allocation loop */
218
219 if (mem->head && mem->tail && (mem->tail->len < SM_PAGE_SIZE)) {
220 avail_len = SM_PAGE_SIZE - (mem->tail->len);
221 len_to_copy = min(avail_len, len);
30a4f2a8 222 xmemcpy((mem->tail->data + mem->tail->len), data, len_to_copy);
090089c4 223 /* Adjust the ptr and len according to what was deposited in the page */
224 data += len_to_copy;
225 len -= len_to_copy;
226 mem->tail->len += len_to_copy;
227 }
228 while (len > 0) {
229 len_to_copy = min(len, SM_PAGE_SIZE);
30a4f2a8 230 p = xcalloc(1, sizeof(Mem_Node));
090089c4 231 p->next = NULL;
232 p->len = len_to_copy;
2daae136 233 p->data = get_free_4k_page();
30a4f2a8 234 xmemcpy(p->data, data, len_to_copy);
090089c4 235
236 if (!mem->head) {
237 /* The chain is empty */
238 mem->head = mem->tail = p;
239 } else {
240 /* Append it to existing chain */
241 mem->tail->next = p;
242 mem->tail = p;
243 }
244 len -= len_to_copy;
245 data += len_to_copy;
246 }
090089c4 247}
248
d89d1fb6 249size_t
250memCopy(const mem_ptr mem, off_t offset, char *buf, size_t size)
090089c4 251{
252 mem_node p = mem->head;
d89d1fb6 253 off_t t_off = mem->origin_offset;
254 size_t bytes_to_go = size;
30a4f2a8 255 char *ptr_to_buf = NULL;
090089c4 256 int bytes_from_this_packet = 0;
257 int bytes_into_this_packet = 0;
a3d5953d 258 debug(19, 6) ("memCopy: offset %d: size %d\n", offset, size);
30a4f2a8 259 if (p == NULL)
0a0bf5db 260 return -1;
261 /* fatal_dump("memCopy: NULL mem_node"); *//* Can happen on async */
97a88399 262 assert(size > 0);
090089c4 263 /* Seek our way into store */
264 while ((t_off + p->len) < offset) {
265 t_off += p->len;
d89d1fb6 266 assert(p->next);
267 p = p->next;
090089c4 268 }
090089c4 269 /* Start copying begining with this block until
270 * we're satiated */
090089c4 271 bytes_into_this_packet = offset - t_off;
d89d1fb6 272 bytes_from_this_packet = min(bytes_to_go, p->len - bytes_into_this_packet);
30a4f2a8 273 xmemcpy(buf, p->data + bytes_into_this_packet, bytes_from_this_packet);
090089c4 274 bytes_to_go -= bytes_from_this_packet;
275 ptr_to_buf = buf + bytes_from_this_packet;
276 p = p->next;
090089c4 277 while (p && bytes_to_go > 0) {
278 if (bytes_to_go > p->len) {
30a4f2a8 279 xmemcpy(ptr_to_buf, p->data, p->len);
090089c4 280 ptr_to_buf += p->len;
281 bytes_to_go -= p->len;
282 } else {
30a4f2a8 283 xmemcpy(ptr_to_buf, p->data, bytes_to_go);
090089c4 284 bytes_to_go -= bytes_to_go;
285 }
286 p = p->next;
287 }
d89d1fb6 288 return size - bytes_to_go;
090089c4 289}
290
291
292/* Do whatever is necessary to begin storage of new object */
b8d8561b 293mem_ptr
0673c0ba 294memInit(void)
090089c4 295{
30a4f2a8 296 mem_ptr new = xcalloc(1, sizeof(Mem_Hdr));
090089c4 297 new->tail = new->head = NULL;
090089c4 298 return new;
299}
300
b8d8561b 301static void *
302get_free_thing(stmem_stats * thing)
30a4f2a8 303{
7ecd0a2f 304 void *p = NULL;
305 if (!empty_stack(&thing->free_page_stack)) {
55bb9c51 306 p = pop(&thing->free_page_stack);
307 if (p == NULL)
7ecd0a2f 308 fatal_dump("get_free_thing: NULL pointer?");
30a4f2a8 309 } else {
55bb9c51 310 p = xmalloc(thing->page_size);
7ecd0a2f 311 thing->total_pages_allocated++;
30a4f2a8 312 }
7ecd0a2f 313 thing->n_pages_in_use++;
314 memset(p, '\0', thing->page_size);
315 return p;
30a4f2a8 316}
317
b8d8561b 318void *
0673c0ba 319get_free_request_t(void)
30a4f2a8 320{
7ecd0a2f 321 return get_free_thing(&request_pool);
30a4f2a8 322}
323
b8d8561b 324void *
0673c0ba 325get_free_mem_obj(void)
30a4f2a8 326{
7ecd0a2f 327 return get_free_thing(&mem_obj_pool);
30a4f2a8 328}
329
b8d8561b 330char *
0673c0ba 331get_free_4k_page(void)
30a4f2a8 332{
f7a5493b 333 return (char *) get_free_thing(&sm_stats);
30a4f2a8 334}
335
b8d8561b 336char *
0673c0ba 337get_free_8k_page(void)
7ecd0a2f 338{
f7a5493b 339 return (char *) get_free_thing(&disk_stats);
7ecd0a2f 340}
090089c4 341
b8d8561b 342static void
343put_free_thing(stmem_stats * thing, void *p)
090089c4 344{
cadbacbd 345 if (p == NULL)
346 fatal_dump("Somebody is putting a NULL pointer!");
7ecd0a2f 347 thing->n_pages_in_use--;
348 if (thing->total_pages_allocated > thing->max_pages) {
349 xfree(p);
350 thing->total_pages_allocated--;
351 } else if (full_stack(&thing->free_page_stack)) {
352 xfree(p);
353 thing->total_pages_allocated--;
090089c4 354 } else {
55bb9c51 355 push(&thing->free_page_stack, p);
090089c4 356 }
090089c4 357}
358
ea6f43cd 359void
67508012 360put_free_request_t(void *req)
090089c4 361{
7ecd0a2f 362 put_free_thing(&request_pool, req);
090089c4 363}
364
b8d8561b 365void
366put_free_mem_obj(void *mem)
090089c4 367{
7ecd0a2f 368 put_free_thing(&mem_obj_pool, mem);
369}
370
b8d8561b 371void
372put_free_4k_page(void *page)
7ecd0a2f 373{
374 put_free_thing(&sm_stats, page);
090089c4 375}
376
b8d8561b 377void
378put_free_8k_page(void *page)
090089c4 379{
7ecd0a2f 380 put_free_thing(&disk_stats, page);
090089c4 381}
382
b8d8561b 383void
0673c0ba 384stmemInit(void)
090089c4 385{
386 sm_stats.page_size = SM_PAGE_SIZE;
387 sm_stats.total_pages_allocated = 0;
090089c4 388 sm_stats.n_pages_in_use = 0;
e954773d 389 sm_stats.max_pages = Config.Mem.maxSize / SM_PAGE_SIZE;
090089c4 390
391 disk_stats.page_size = DISK_PAGE_SIZE;
392 disk_stats.total_pages_allocated = 0;
090089c4 393 disk_stats.n_pages_in_use = 0;
7ecd0a2f 394 disk_stats.max_pages = 200;
090089c4 395
30a4f2a8 396 request_pool.page_size = sizeof(request_t);
397 request_pool.total_pages_allocated = 0;
30a4f2a8 398 request_pool.n_pages_in_use = 0;
e83892e9 399 request_pool.max_pages = Squid_MaxFD >> 3;
30a4f2a8 400
401 mem_obj_pool.page_size = sizeof(MemObject);
402 mem_obj_pool.total_pages_allocated = 0;
30a4f2a8 403 mem_obj_pool.n_pages_in_use = 0;
e83892e9 404 mem_obj_pool.max_pages = Squid_MaxFD >> 3;
30a4f2a8 405
9864ee44 406#if PURIFY
a3d5953d 407 debug(19, 0) ("Disabling stacks under purify\n");
9864ee44 408 sm_stats.max_pages = 0;
409 disk_stats.max_pages = 0;
410 request_pool.max_pages = 0;
411 mem_obj_pool.max_pages = 0;
412#endif
caebbe00 413 if (!opt_mem_pools) {
414 sm_stats.max_pages = 0;
415 disk_stats.max_pages = 0;
416 request_pool.max_pages = 0;
417 mem_obj_pool.max_pages = 0;
418 }
7ecd0a2f 419 init_stack(&sm_stats.free_page_stack, sm_stats.max_pages);
420 init_stack(&disk_stats.free_page_stack, disk_stats.max_pages);
421 init_stack(&request_pool.free_page_stack, request_pool.max_pages);
422 init_stack(&mem_obj_pool.free_page_stack, mem_obj_pool.max_pages);
090089c4 423}
0a21bd84 424
425static void
426stmemFreeThingMemory(stmem_stats * thing)
427{
428 void *p;
429 while (!empty_stack(&thing->free_page_stack)) {
430 p = pop(&thing->free_page_stack);
431 safe_free(p);
432 }
df92bd2a 433 stackFreeMemory(&thing->free_page_stack);
0a21bd84 434}
435
436void
437stmemFreeMemory(void)
438{
439 stmemFreeThingMemory(&sm_stats);
440 stmemFreeThingMemory(&disk_stats);
441 stmemFreeThingMemory(&request_pool);
442 stmemFreeThingMemory(&mem_obj_pool);
443}