1/* BEGIN LICENSE BLOCK 2 * Version: CMPL 1.1 3 * 4 * The contents of this file are subject to the Cisco-style Mozilla Public 5 * License Version 1.1 (the "License"); you may not use this file except 6 * in compliance with the License. You may obtain a copy of the License 7 * at www.eclipse-clp.org/license. 8 * 9 * Software distributed under the License is distributed on an "AS IS" 10 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11 * the License for the specific language governing rights and limitations 12 * under the License. 13 * 14 * The Original Code is The ECLiPSe Constraint Logic Programming System. 15 * The Initial Developer of the Original Code is Cisco Systems, Inc. 16 * Portions created by the Initial Developer are 17 * Copyright (C) 1994-2006 Cisco Systems, Inc. All Rights Reserved. 18 * 19 * Contributor(s): Joachim Schimpf, ECRC. 20 * 21 * END LICENSE BLOCK */ 22 23/*--------------------------------------------------------------------- 24 * IDENTIFICATION private_mem.c 25 * 26 * VERSION $Id: private_mem.c,v 1.2 2007/07/03 00:10:25 jschimpf Exp $ 27 * 28 * AUTHOR Joachim Schimpf 29 * 30 * CONTENTS - Private memory allocation 31 *---------------------------------------------------------------------*/ 32 33#include "config.h" 34#ifdef HAVE_UNISTD_H 35#include <unistd.h> 36#endif 37#ifdef HAVE_WINDOWS_H 38#include "windows.h" 39#endif 40 41#ifdef HAVE_MMAP 42#define USE_MMAP 43#endif 44 45#ifdef USE_MMAP 46 47#include <sys/mman.h> 48#include <fcntl.h> /* for O_RDWR */ 49 50#ifndef MAP_FAILED 51#define MAP_FAILED ((void *) -1) 52#endif 53 54#ifdef MAP_ANONYMOUS 55#define HAVE_MAP_ANONYMOUS 56#else 57#ifdef MAP_ANON 58#define MAP_ANONYMOUS MAP_ANON 59#define HAVE_MAP_ANONYMOUS 60#else 61#define MAP_ANONYMOUS 0 62#endif 63#endif 64 65#else 66 67#ifdef SBRK_UNDEF 68extern char *sbrk(); 69#endif 70 71#endif 72 73 74#include "memman.h" 75 76 77struct prmem { 78 /* first word reserved to be compatible with shared memory's 79 * application_header 80 */ 81 generic_ptr first_word_in_heap; 82 struct page_admin pages; 83 struct heap heap; 84}; 85 86struct heap_descriptor private_heap; 87 88 89/*--------------------------------------------------------------------- 90 * Primitive allocation function for private memory 91 *---------------------------------------------------------------------*/ 92 93/*ARGSUSED*/ 94static generic_ptr 95_private_sbrk(word size, int align, struct heap_descriptor *hd) 96{ 97#ifdef HAVE_WINDOWS_H 98 generic_ptr address = VirtualAlloc(NULL,size,MEM_COMMIT,PAGE_READWRITE); 99 return address ? address : (generic_ptr) -1; 100#else 101#ifdef USE_MMAP 102 generic_ptr address = mmap((void*) 0, size, 103 PROT_READ|PROT_WRITE, 104 MAP_ANONYMOUS|MAP_PRIVATE, 105 hd->map_fd, (off_t) 0); 106 return address == MAP_FAILED ? (generic_ptr) -1 : address; 107#else 108 register word difference = (word) sbrk(0) % align; 109 if (difference) 110 { 111#ifdef DEBUG_HEAP 112 (void) write(2, "WARNING: misaligned brk\n", 24); 113#endif 114 (void) sbrk(align - difference); 115 } 116 return (generic_ptr) sbrk(size); 117#endif 118#endif 119} 120 121static int 122_private_release(generic_ptr address, word size, struct heap_descriptor *hd) 123{ 124#ifdef HAVE_WINDOWS_H 125 return VirtualFree(address, 0, MEM_RELEASE); 126#else 127#ifdef USE_MMAP 128 return !munmap(address, size); 129#else 130 return 1; 131#endif 132#endif 133} 134 135char * 136private_mem_init_desc( 137 void (*panic_fct)(const char*, const char*), 138 struct heap_descriptor *hd) 139{ 140 struct prmem *private_memory; 141 /* 142 * Set up the private heap 143 */ 144#ifdef USE_MMAP 145#ifdef HAVE_MAP_ANONYMOUS 146 hd->map_fd = -1; 147#else 148 hd->map_fd = open("/dev/zero", O_RDWR); 149#endif 150#endif 151 private_memory = (struct prmem *) 152 _private_sbrk(sizeof(struct prmem), 1, hd); 153 if (private_memory == (struct prmem *) -1) 154 return (char *) -1; 155 156 hd->shared_header = 0; 157 hd->pages = &private_memory->pages; 158 hd->heap = &private_memory->heap; 159 hd->panic = panic_fct; 160 hd->more = _private_sbrk; 161 hd->less = _private_release; 162 pagemanager_init(hd); 163 alloc_init(hd); 164 return (char *) private_memory; 165} 166 167void 168private_mem_init(void (*panic_fct)(const char*, const char*)) 169{ 170 Disable_Int(); 171 (void) private_mem_init_desc(panic_fct, &private_heap); 172 Enable_Int(); 173} 174 175void 176private_mem_release_desc(struct heap_descriptor *hd) 177{ 178 struct prmem dummy; 179 char *prmem_struct_addr; 180 pagemanager_fini(hd); 181 /* sorry, hack to find lost address of the above allocated structure */ 182 prmem_struct_addr = (char*)hd->pages - ((char*)&dummy.pages - (char*)&dummy); 183 _private_release(prmem_struct_addr, sizeof(struct prmem), NULL); 184} 185 186void 187private_mem_release() 188{ 189 Disable_Int(); 190 (void) private_mem_release_desc(&private_heap); 191 Enable_Int(); 192} 193 194 195/*--------------------------------------------------------------------- 196 * Private heap interface 197 *---------------------------------------------------------------------*/ 198 199/* 200 * Header-less allocation 201 */ 202 203generic_ptr 204hp_alloc_size(word bytes_needed) 205{ 206 return alloc_size(&private_heap, bytes_needed); 207} 208 209void 210hp_free_size(generic_ptr ptr, word size) 211{ 212 free_size(&private_heap, ptr, size); 213} 214 215generic_ptr 216hp_realloc_size(generic_ptr ptr, word oldsize, word newsize) 217{ 218 return realloc_size(&private_heap, ptr, oldsize, newsize); 219} 220 221 222/*--------------------------------------------------------------------- 223 * Allocate memory that remembers its own size 224 * We need a double header for alignment. 225 * It gives us also space for a magic number. 226 *---------------------------------------------------------------------*/ 227 228generic_ptr 229hp_alloc(word size) 230{ 231 return h_alloc(&private_heap, size); 232} 233 234void 235hp_free(generic_ptr ptr) 236{ 237 h_free(&private_heap, ptr); 238} 239 240generic_ptr 241hp_resize(generic_ptr ptr, word newsize) 242{ 243 return h_realloc(&private_heap, ptr, newsize); 244} 245 246 247/*--------------------------------------------------------------------- 248 * Debugging and statistics 249 *---------------------------------------------------------------------*/ 250 251int 252hp_statistics(int what) 253{ 254 return alloc_statistics(&private_heap, what); 255} 256 257