1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-22 07:37:38 +01:00

(Logical change 1.19)

This commit is contained in:
mostang.com!davidm 2002-07-18 03:58:34 +00:00
parent 5b6078357d
commit dd3c681c6a
2 changed files with 238 additions and 0 deletions

View file

@ -0,0 +1,152 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/mman.h>
#include "libunwind.h"
#include "mempool.h"
#define SOSLOCK() /* XXX fix me */
#define SOSUNLOCK() /* XXX fix me */
#define LOCK(p) /* XXX fix me */
#define UNLOCK(p) /* XXX fix me */
#define MAX_ALIGN (sizeof (long double))
#define SOS_MEMORY_SIZE 16384
static char sos_memory[SOS_MEMORY_SIZE];
static char *sos_memp = sos_memory;
static size_t pg_size = 0;
void *
sos_alloc (size_t size)
{
char *mem;
size = (size + MAX_ALIGN - 1) & -MAX_ALIGN;
mem = (char *) (((unsigned long) sos_memp + MAX_ALIGN - 1)
& -MAX_ALIGN);
if (mem + size >= sos_memory + sizeof (sos_memory))
sos_memp = mem + size;
if (!mem)
abort ();
return mem;
}
void
sos_free (void *ptr)
{
}
static void *
alloc_memory (size_t size)
{
/* Hopefully, mmap() goes straight through to a system call stub... */
void *mem = mmap (0, size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED)
return NULL;
return mem;
}
/* Must be called while holding the mempool lock. */
static void
free_object (struct mempool *pool, void *object)
{
struct object *obj = object;
obj->next = pool->free_list;
pool->free_list = obj;
++pool->num_free;
}
static void
add_memory (struct mempool *pool, char *mem, size_t size, size_t obj_size)
{
char *obj;
for (obj = mem; obj + obj_size <= mem + size; obj += obj_size)
free_object (pool, obj);
}
static void
expand (struct mempool *pool)
{
size_t size;
char *mem;
size = pool->chunk_size;
mem = alloc_memory (size);
if (!mem)
{
size = (pool->obj_size + pg_size - 1) & -pg_size;
mem = alloc_memory (size);
if (!mem)
{
/* last chance: try to allocate one object from the SOS memory */
size = pool->obj_size;
mem = sos_alloc (size);
}
}
add_memory (pool, mem, size, pool->obj_size);
}
void
mempool_init (struct mempool *pool, size_t obj_size, size_t reserve)
{
if (pg_size == 0)
pg_size = getpagesize ();
memset (pool, 0, sizeof (*pool));
/* round object-size up to integer multiple of MAX_ALIGN */
obj_size = (obj_size + MAX_ALIGN - 1) & -MAX_ALIGN;
if (!reserve)
{
reserve = pg_size / obj_size / 2;
if (!reserve)
reserve = 16;
}
pool->obj_size = obj_size;
pool->reserve = reserve;
pool->chunk_size = (2*reserve*obj_size + pg_size - 1) & -pg_size;
expand (pool);
}
void *
mempool_alloc (struct mempool *pool)
{
struct object *obj;
LOCK(pool);
{
if (pool->num_free <= pool->reserve)
expand (pool);
assert (pool->num_free > 0);
--pool->num_free;
obj = pool->free_list;
pool->free_list = obj->next;
}
UNLOCK(pool);
return obj;
}
void
mempool_free (struct mempool *pool, void *object)
{
LOCK(pool);
free_object (pool, object);
UNLOCK(pool);
}

View file

@ -0,0 +1,86 @@
/* libunwind - a platform-independent unwind library
Copyright (C) 2002 Hewlett-Packard Co
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of libunwind.
libunwind is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
libunwind is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
As a special exception, if you link this library with other files to
produce an executable, this library does not by itself cause the
resulting executable to be covered by the GNU General Public License.
This exception does not however invalidate any other reasons why the
executable file might be covered by the GNU General Public
License. */
#ifndef mempool_h
#define mempool_h
/* Memory pools provide simple memory management of fixed-size
objects. Memory pools are used for two purposes:
o To ensure a stack can be unwound even when a process
is out of memory.
o To ensure a stack can be unwound at any time in a
multi-threaded process (e.g., even at a time when the normal
malloc-lock is taken, possibly by the very thread that is
being unwind).
To achieve the second objective, memory pools allocate memory
directly via mmap() system call (or an equivalent facility).
The first objective is accomplished by reserving memory ahead of
time. Since the memory requirements of stack unwinding generally
depends on the complexity of the procedures being unwind, there is
no absolute guarantee that unwinding will always work, but in
practice, this should not be a serious problem. */
#include <sys/types.h>
#define IPREFIX UNW_PASTE(_UI,UNW_TARGET)
#define sos_alloc(s) UNW_PASTE(IPREFIX, _sos_alloc)(s)
#define sos_free(p) UNW_PASTE(IPREFIX, _sos_free)(p)
#define mempool_init(p,s,r) UNW_PASTE(IPREFIX, _mempool_init)(p,s,r)
#define mempool_alloc(p) UNW_PASTE(IPREFIX, _mempool_alloc)(p)
#define mempool_free(p,o) UNW_PASTE(IPREFIX, _mempool_free)(p,o)
/* The mempool structure should be treated as an opaque object. It's
declared here only to enable static allocation of mempools. */
struct mempool
{
size_t obj_size; /* object size (rounded up for alignment) */
unsigned int reserve; /* minimum (desired) size of the free-list */
size_t chunk_size; /* allocation granularity */
unsigned int num_free; /* number of objects on the free-list */
struct object
{
struct object *next;
}
*free_list;
};
/* Emergency allocation for one-time stuff that doesn't fit the memory
pool model. */
extern void *sos_alloc (size_t size);
extern void sos_free (void *ptr);
/* Initialize POOL for an object size of OBJECT_SIZE bytes. RESERVE
is the number of objects that should be reserved for use under
tight memory situations. If it is zero, mempool attempts to pick a
reasonable default value. */
extern void mempool_init (struct mempool *pool,
size_t obj_size, size_t reserve);
extern void *mempool_alloc (struct mempool *pool);
extern void mempool_free (struct mempool *pool, void *object);
#endif /* mempool_h */