Revision 3df61d16c51c6cbbe49ca3faabd2215e6061887f authored by Alexander Kruppa on 20 February 2014, 16:47:44 UTC, committed by Alexander Kruppa on 20 February 2014, 16:47:44 UTC
1 parent 744a265
electric_alloc.h
#ifndef CADO_UTILS_ELECTRIC_ALLOC_H_
#define CADO_UTILS_ELECTRIC_ALLOC_H_
/* This file is a debugging aid. It carries good chances of working on
* POSIX system, but I wouldn't bet much on it, since mmap is kind of
* strongly tied to the OS.
*
* To use, simply include this .h file, and use electric_alloc and
* electric_free for for allocation/free routines.
*
* The vanilla electric_free needs the size of the allocated area. If
* this is an inconvenient, try the _nosize versions below. Never tested.
*/
/* By default we protect overruns. Undefine this macro to protect
* underruns instead */
#define PROTECT_OVERRUN
#include <fcntl.h>
#include <sys/mman.h>
#ifndef MAP_ANONYMOUS
#error "Please define _GNU_SOURCE or _BSD_SOURCE on top of the translation unit"
#endif
static inline
void * electric_alloc(size_t s)
{
/* Use the method of the good old days from electric fence. */
char *p;
size_t r = 8192; /* Any multiple of the page size will do. */
unsigned int multip = (s+r-1)/r;
p = (char *)
mmap(0, (multip + 1) * r, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
// could please valgrind ?
// memset(p, 0, (multip + 1) * r);
#ifdef PROTECT_OVERRUN
p += (multip + 1) * r;
mprotect((void*) (p-r), r, PROT_NONE);
p -= r+s;
#else
/* protect underrun */
mprotect(p, r, PROT_NONE);
p += r;
#endif
return (void *) p;
}
static inline
void electric_free(void * p0, size_t s)
{
char * p = (char *) p0;
size_t r = 8192;
unsigned int multip = (s+r-1)/r;
#ifdef PROTECT_OVERRUN
p += s;
mprotect((void*) p, r, PROT_READ | PROT_WRITE);
p -= multip * r;
#else
p -= r;
mprotect(p, r, PROT_READ | PROT_WRITE);
#endif
munmap(p, (multip + 1) * r);
}
static inline
void * electric_alloc_nosize(size_t s)
{
void * ptr = electric_alloc(s + sizeof(s));
*(size_t *)ptr = s;
return (void *) (((size_t *) ptr) + 1);
}
static inline
void electric_free_nosize(void * p0)
{
p0 = (void*) (((size_t *)p0)-1);
size_t s = * (size_t *) p0;
electric_free(p0, s + sizeof(s));
}
#ifdef __cplusplus
template<typename T> inline T * electric_new(size_t s) {
return (T*) electric_alloc(sizeof(T)*s);
}
template<typename T> inline void electric_delete(T * p, size_t s) {
electric_free(p, sizeof(T)*s);
}
#endif
#endif /* CADO_UTILS_ELECTRIC_ALLOC_H_ */
Computing file changes ...