region.hpp
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Christian Schulte <schulte@gecode.org> 00005 * 00006 * Contributing authors: 00007 * Filip Konvicka <filip.konvicka@logis.cz> 00008 * 00009 * Copyright: 00010 * Christian Schulte, 2008 00011 * LOGIS, s.r.o., 2009 00012 * 00013 * Last modified: 00014 * $Date: 2009-04-14 19:41:10 +0200 (Tue, 14 Apr 2009) $ by $Author: schulte $ 00015 * $Revision: 8698 $ 00016 * 00017 * This file is part of Gecode, the generic constraint 00018 * development environment: 00019 * http://www.gecode.org 00020 * 00021 * Permission is hereby granted, free of charge, to any person obtaining 00022 * a copy of this software and associated documentation files (the 00023 * "Software"), to deal in the Software without restriction, including 00024 * without limitation the rights to use, copy, modify, merge, publish, 00025 * distribute, sublicense, and/or sell copies of the Software, and to 00026 * permit persons to whom the Software is furnished to do so, subject to 00027 * the following conditions: 00028 * 00029 * The above copyright notice and this permission notice shall be 00030 * included in all copies or substantial portions of the Software. 00031 * 00032 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00033 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00034 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00035 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00036 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00037 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00038 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00039 * 00040 */ 00041 00042 namespace Gecode { 00043 00060 00061 class Region { 00062 private: 00064 Space& home; 00066 size_t free_reset; 00068 class HeapInfo { 00069 public: 00071 unsigned int n; 00073 unsigned int size; 00075 void* blocks[1]; 00076 }; 00084 void* hi; 00086 GECODE_KERNEL_EXPORT void* heap_alloc(size_t s); 00088 GECODE_KERNEL_EXPORT void heap_free(void); 00089 public: 00091 Region(const Space& home); 00093 00094 00100 template<class T> 00101 T* alloc(long unsigned int n); 00108 template<class T> 00109 T* alloc(long int n); 00116 template<class T> 00117 T* alloc(unsigned int n); 00124 template<class T> 00125 T* alloc(int n); 00135 template<class T> 00136 void free(T* b, long unsigned int n); 00146 template<class T> 00147 void free(T* b, long int n); 00157 template<class T> 00158 void free(T* b, unsigned int n); 00168 template<class T> 00169 void free(T* b, int n); 00181 template<class T> 00182 T* realloc(T* b, long unsigned int n, long unsigned int m); 00194 template<class T> 00195 T* realloc(T* b, long int n, long int m); 00207 template<class T> 00208 T* realloc(T* b, unsigned int n, unsigned int m); 00220 template<class T> 00221 T* realloc(T* b, int n, int m); 00223 00224 00225 00226 void* ralloc(size_t s); 00233 void rfree(void* p, size_t s); 00235 00236 00237 00240 template<class T> 00241 T& construct(void); 00247 template<class T, typename A1> 00248 T& construct(A1 const& a1); 00254 template<class T, typename A1, typename A2> 00255 T& construct(A1 const& a1, A2 const& a2); 00261 template<class T, typename A1, typename A2, typename A3> 00262 T& construct(A1 const& a1, A2 const& a2, A3 const& a3); 00268 template<class T, typename A1, typename A2, typename A3, typename A4> 00269 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4); 00275 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5> 00276 T& construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5); 00278 00279 ~Region(void); 00280 private: 00282 static void* operator new(size_t s) throw() { (void) s; return NULL; } 00284 static void operator delete(void* p) { (void) p; }; 00286 Region(const Region& r) : home(r.home) {} 00288 const Region& operator =(const Region&) { return *this; } 00289 }; 00291 00292 00293 /* 00294 * Implementation 00295 * 00296 */ 00297 forceinline 00298 Region::Region(const Space& h) 00299 : home(const_cast<Space&>(h)), free_reset(home.sm->region.free), hi(0) {} 00300 00301 forceinline void* 00302 Region::ralloc(size_t s) { 00303 void* p; 00304 if (home.sm->region_alloc(s,p)) 00305 return p; 00306 return heap_alloc(s); 00307 } 00308 00309 forceinline void 00310 Region::rfree(void*, size_t) {} 00311 00312 forceinline 00313 Region::~Region(void) { 00314 home.sm->region.free = free_reset; 00315 if (hi != NULL) 00316 heap_free(); 00317 } 00318 00319 00320 /* 00321 * Typed allocation routines 00322 * 00323 */ 00324 template<class T> 00325 forceinline T* 00326 Region::alloc(long unsigned int n) { 00327 T* p = static_cast<T*>(ralloc(sizeof(T)*n)); 00328 for (long unsigned int i=n; i--; ) 00329 (void) new (p+i) T(); 00330 return p; 00331 } 00332 template<class T> 00333 forceinline T* 00334 Region::alloc(long int n) { 00335 assert(n >= 0); 00336 return alloc<T>(static_cast<long unsigned int>(n)); 00337 } 00338 template<class T> 00339 forceinline T* 00340 Region::alloc(unsigned int n) { 00341 return alloc<T>(static_cast<long unsigned int>(n)); 00342 } 00343 template<class T> 00344 forceinline T* 00345 Region::alloc(int n) { 00346 assert(n >= 0); 00347 return alloc<T>(static_cast<long unsigned int>(n)); 00348 } 00349 00350 template<class T> 00351 forceinline void 00352 Region::free(T* b, long unsigned int n) { 00353 for (long unsigned int i=n; i--; ) 00354 b[i].~T(); 00355 rfree(b,n*sizeof(T)); 00356 } 00357 template<class T> 00358 forceinline void 00359 Region::free(T* b, long int n) { 00360 assert(n >= 0); 00361 free<T>(b,static_cast<long unsigned int>(n)); 00362 } 00363 template<class T> 00364 forceinline void 00365 Region::free(T* b, unsigned int n) { 00366 free<T>(b,static_cast<long unsigned int>(n)); 00367 } 00368 template<class T> 00369 forceinline void 00370 Region::free(T* b, int n) { 00371 assert(n >= 0); 00372 free<T>(b,static_cast<long unsigned int>(n)); 00373 } 00374 00375 template<class T> 00376 forceinline T* 00377 Region::realloc(T* b, long unsigned int n, long unsigned int m) { 00378 if (n < m) { 00379 T* p = static_cast<T*>(ralloc(sizeof(T)*m)); 00380 for (long unsigned int i=n; i--; ) 00381 (void) new (p+i) T(b[i]); 00382 for (long unsigned int i=n; i<m; i++) 00383 (void) new (p+i) T(); 00384 free<T>(b,n); 00385 return p; 00386 } else { 00387 free<T>(b+m,m-n); 00388 return b; 00389 } 00390 } 00391 template<class T> 00392 forceinline T* 00393 Region::realloc(T* b, long int n, long int m) { 00394 assert((n >= 0) && (m >= 0)); 00395 return realloc<T>(b,static_cast<long unsigned int>(n), 00396 static_cast<long unsigned int>(m)); 00397 } 00398 template<class T> 00399 forceinline T* 00400 Region::realloc(T* b, unsigned int n, unsigned int m) { 00401 return realloc<T>(b,static_cast<long unsigned int>(n), 00402 static_cast<long unsigned int>(m)); 00403 } 00404 template<class T> 00405 forceinline T* 00406 Region::realloc(T* b, int n, int m) { 00407 assert((n >= 0) && (m >= 0)); 00408 return realloc<T>(b,static_cast<long unsigned int>(n), 00409 static_cast<long unsigned int>(m)); 00410 } 00411 00412 /* 00413 * Region construction support 00414 * 00415 */ 00416 template<class T> 00417 forceinline T& 00418 Region::construct(void) { 00419 return alloc<T>(1); 00420 } 00421 template<class T, typename A1> 00422 forceinline T& 00423 Region::construct(A1 const& a1) { 00424 T& t = *static_cast<T*>(ralloc(sizeof(T))); 00425 new (&t) T(a1); 00426 return t; 00427 } 00428 template<class T, typename A1, typename A2> 00429 forceinline T& 00430 Region::construct(A1 const& a1, A2 const& a2) { 00431 T& t = *static_cast<T*>(ralloc(sizeof(T))); 00432 new (&t) T(a1,a2); 00433 return t; 00434 } 00435 template<class T, typename A1, typename A2, typename A3> 00436 forceinline T& 00437 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3) { 00438 T& t = *static_cast<T*>(ralloc(sizeof(T))); 00439 new (&t) T(a1,a2,a3); 00440 return t; 00441 } 00442 template<class T, typename A1, typename A2, typename A3, typename A4> 00443 forceinline T& 00444 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4) { 00445 T& t = *static_cast<T*>(ralloc(sizeof(T))); 00446 new (&t) T(a1,a2,a3,a4); 00447 return t; 00448 } 00449 template<class T, typename A1, typename A2, typename A3, typename A4, typename A5> 00450 forceinline T& 00451 Region::construct(A1 const& a1, A2 const& a2, A3 const& a3, A4 const& a4, A5 const& a5) { 00452 T& t = *static_cast<T*>(ralloc(sizeof(T))); 00453 new (&t) T(a1,a2,a3,a4,a5); 00454 return t; 00455 } 00456 00457 } 00458 00459 // STATISTICS: kernel-other