Files
mercury/runtime/mercury_prof_mem.c
Fergus Henderson 97484ac018 Align memory allocated with MR_prof_malloc() to
Estimated hours taken: 2
Branches: main

runtime/mercury_prof_mem.h:
runtime/mercury_prof_mem.c:
	Align memory allocated with MR_prof_malloc() to
	double-word boundaries, rather than word boundaries.
	This is needed to avoid bus errors on Solaris,
	now that we use `long long' for MR_Dword.
2002-02-21 23:51:42 +00:00

99 lines
2.9 KiB
C

/*
** Copyright (C) 1996-1997, 1999-2000, 2002 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** prof_mem.c
**
** Author: petdr
**
** This module is needed to get around the problem that when a signal occurs
** it may be in a malloc. The handling routine may also do a malloc which
** stuffs up the internal state of malloc and cause a seg fault.
** If we're using the conservative GC, that doesn't cause a problem,
** since the Boehm et al collector is signal safe if compiled without
** -DNO_SIGNALS, which we do for profiling grades. But if we're not
** using the conservative GC, then the handler will need to call malloc().
** To minimize this problem, we use our own version of malloc() which
** allocates memory in large chunks, reducing the chance of this
** problem occurring.
*/
#include "mercury_imp.h"
#include <stdio.h>
#include "mercury_prof_mem.h"
#include "mercury_memory.h" /* for MR_GC_malloc() */
#include "mercury_dword.h" /* for MR_Dword */
/*----------------------------------------------------------------------------*/
/*
** Constants
*/
#define MEMORY_BLOCK 2048 /* Testing on a big input file on */
/* the compiler normally required */
/* around 6000 nodes. */
/*----------------------------------------------------------------------------*/
/*
** Private Global Variables
*/
static size_t mem_left = 0; /* Number of bytes left */
static void *next = NULL; /* Pointer to next data block */
/* we can give away */
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/
void *
MR_prof_malloc(size_t size)
{
register void *p;
/*
** Ensure all allocations are word-aligned, by rounding size
** up to the nearest multiple of the word size.
**
** Note that the current implementation of MR_prof_malloc only
** guarantees that the memory will be MR_Dword-aligned; if you want to
** allocate types that contain data types (e.g. `double') which might
** require stricter alignment than that, then you will need to
** change this to round the size up accordingly.
*/
size = ((size + sizeof(MR_Dword) - 1) / sizeof(MR_Dword))
* sizeof(MR_Dword);
/* Here we waste a bit of space but hopefully not to much */
if (mem_left < size) {
/*
** XXX For the conservative GC, it would be better to
** allocate this memory with GC_malloc_atomic_uncollectable(),
** so that the collector doesn't scan it.
*/
next = MR_GC_malloc(MEMORY_BLOCK * size);
mem_left = MEMORY_BLOCK * size;
}
p = next;
next = (void *) ((char *) next + size);
mem_left = mem_left - size;
return p;
}
/*----------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------*/