mem.c revision 50f339a799d1e6d512d6056fa5dc01271a1f6e99
/*
* Copyright (c) 1997, 1998 by Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
* SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "attribute.h"
#include <isc/assertions.h>
#include <isc/memcluster.h>
#ifdef MULTITHREADED
#endif
#if !defined(LINT) && !defined(CODECENTER)
#endif /* not lint */
/*
* Types.
*/
typedef struct {
void * next;
typedef struct {
/*
* This structure must be ALIGNMENT_SIZE bytes.
*/
} *size_info;
struct stats {
unsigned long gets;
unsigned long totalgets;
unsigned long blocks;
unsigned long freefrags;
};
#ifdef MEMCLUSTER_RANGES
typedef struct range {
unsigned char * first;
unsigned char * last;
} range;
#endif
struct mem_context {
#ifdef MEMCLUSTER_RANGES
range * freeranges;
#else
unsigned char * lowest;
unsigned char * highest;
#endif
};
/* Private Data. */
/* Forward. */
/* Macros. */
#define DEF_MAX_SIZE 1100
#define DEF_MEM_TARGET 4096
#define ALIGNMENT_SIZE sizeof (void *)
#ifdef MULTITHREADED
#else
#define LOCK_CONTEXT(ctx)
#define UNLOCK_CONTEXT(ctx)
#endif
/* Private Inline-able. */
static inline size_t
int remainder;
/*
* If there is no remainder for the integer division of
*
*
* then we already have a good size; if not, then we need
* to round up the result in order to get a size big
* enough to satisfy the request and be aligned on ALIGNMENT_SIZE
* byte boundaries.
*/
if (remainder != 0)
return (size);
}
/* Public. */
int
mem_context_t *ctxp) {
if (init_max_size == 0)
else
if (target_size == 0)
else
return (-1);
}
return (-1);
}
return (-1);
}
return (0);
}
void
/* XXX Free Basic Blocks. XXX */
}
void *
void *ret;
/* memget() was called on something beyond our upper limit. */
}
goto done;
}
/*
* If there are no blocks in the free list for this size, get a chunk
* of memory and then break it up into "new_size"-sized blocks, adding
* them to the free list.
*/
int i, frags;
void *new;
unsigned char *first;
#ifdef MEMCLUSTER_RANGES
range *r;
#else
unsigned char *last;
#endif
goto done;
}
for (i = 0; i < (NUM_BASIC_BLOCKS - 1); i++) {
}
/*
* curr is now pointing at the last block in the
* array.
*/
#ifdef MEMCLUSTER_RANGES
for (i = 0; i < (frags - 1); i++) {
}
/*
* curr is now pointing at the last block in
* the array.
*/
}
r = ctx->freeranges;
#else
#endif
}
/* Set up a linked-list of blocks of size "new_size". */
for (i = 0; i < (frags - 1); i++) {
}
/* curr is now pointing at the last block in the array. */
}
/* The free list uses the "rounded-up" size "new_size": */
/*
* The stats[] uses the _actual_ "size" requested by the
* caller, with the caveat (in the code above) that "size" >= the
* max. size (max_size) ends up getting recorded as a call to
* max_size.
*/
done:
return (ret);
}
/*
* This is a call from an external caller,
* so we want to count this as a user "put".
*/
void
/* memput() called on something beyond our upper limit */
goto done;
}
/* The free list uses the "rounded-up" size "new_size": */
/*
* The stats[] uses the _actual_ "size" requested by the
* caller, with the caveat (in the code above) that "size" >= the
* max. size (max_size) ends up getting recorded as a call to
* max_size.
*/
done:
}
void *
void *ptr;
return (ptr);
}
void
int line)
{
}
/*
* Print the stats[] on the stream "out" with suitable formatting.
*/
void
size_t i;
return;
continue;
if (s->blocks != 0)
}
}
int
int ret;
#ifdef MEMCLUSTER_RANGES
range *r;
#endif
ret = 0;
#ifdef MEMCLUSTER_RANGES
/* should use a tree for this... */
ret = 1;
break;
}
}
#else
ret = 1;
#endif
return (ret);
}
/*
* Replacements for malloc() and free().
*/
void *
size += ALIGNMENT_SIZE;
return (NULL);
return (&si[1]);
}
void
}
/*
* Public Legacy.
*/
int
/* need default_context lock here */
if (default_context != NULL)
return (-1);
&default_context));
}
mem_default_context(void) {
/* need default_context lock here */
return (NULL);
return (default_context);
}
void *
/* need default_context lock here */
return (NULL);
}
void
/* need default_context lock here */
}
void *
void *ptr;
return (ptr);
}
void
}
int
/* need default_context lock here */
}
void
/* need default_context lock here */
}