Generated on for Gecode by doxygen 1.17.0
heap.hpp
Go to the documentation of this file.
1/* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2/*
3 * Main authors:
4 * Christian Schulte <schulte@gecode.dev>
5 *
6 * Contributing authors:
7 * Mikael Zayenz Lagerkvist <lagerkvist@gecode.dev>
8 *
9 * Copyright:
10 * Christian Schulte, 2008
11 * Mikael Zayenz Lagerkvist, 2026
12 *
13 * This file is part of Gecode, the generic constraint
14 * development environment:
15 * http://www.gecode.dev
16 *
17 * Permission is hereby granted, free of charge, to any person obtaining
18 * a copy of this software and associated documentation files (the
19 * "Software"), to deal in the Software without restriction, including
20 * without limitation the rights to use, copy, modify, merge, publish,
21 * distribute, sublicense, and/or sell copies of the Software, and to
22 * permit persons to whom the Software is furnished to do so, subject to
23 * the following conditions:
24 *
25 * The above copyright notice and this permission notice shall be
26 * included in all copies or substantial portions of the Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35 *
36 */
37
38#include <cstring>
39#include <cstdlib>
40#include <algorithm>
41
42#ifdef GECODE_PEAKHEAP_MALLOC_H
43#include <malloc.h>
44#endif
45
46#ifdef GECODE_PEAKHEAP_MALLOC_MALLOC_H
47#include <malloc/malloc.h>
48#endif
49
50namespace Gecode {
51
57
58
66 class Heap {
67 public:
69 Heap(void);
71
72
78 template<class T>
79 T* alloc(long unsigned int n);
86 template<class T>
87 T* alloc(long int n);
94 template<class T>
95 T* alloc(unsigned int n);
102 template<class T>
103 T* alloc(int n);
110 template<class T>
111 void free(T* b, long unsigned int n);
118 template<class T>
119 void free(T* b, long int n);
126 template<class T>
127 void free(T* b, unsigned int n);
134 template<class T>
135 void free(T* b, int n);
147 template<class T>
148 T* realloc(T* b, long unsigned int n, long unsigned int m);
160 template<class T>
161 T* realloc(T* b, long int n, long int m);
173 template<class T>
174 T* realloc(T* b, unsigned int n, unsigned int m);
186 template<class T>
187 T* realloc(T* b, int n, int m);
195 template<class T>
196 T** realloc(T** b, long unsigned int n, long unsigned int m);
204 template<class T>
205 T** realloc(T** b, long int n, long int m);
213 template<class T>
214 T** realloc(T** b, unsigned int n, unsigned int m);
222 template<class T>
223 T** realloc(T** b, int n, int m);
232 template<class T>
233 static T* copy(T* d, const T* s, long unsigned int n);
242 template<class T>
243 static T* copy(T* d, const T* s, long int n);
252 template<class T>
253 static T* copy(T* d, const T* s, unsigned int n);
262 template<class T>
263 static T* copy(T* d, const T* s, int n);
271 template<class T>
272 static T** copy(T** d, const T** s, long unsigned int n);
280 template<class T>
281 static T** copy(T** d, const T** s, long int n);
289 template<class T>
290 static T** copy(T** d, const T** s, unsigned int n);
298 template<class T>
299 static T** copy(T** d, const T** s, int n);
301
303
304 void* ralloc(size_t s);
306 void rfree(void* p);
308 void rfree(void* p, size_t s);
310 void* rrealloc(void* p, size_t s);
312#ifdef GECODE_PEAKHEAP
313 private:
317 size_t _peak;
319 size_t _cur;
320public:
321 size_t peak(void);
322#endif
324 static void* operator new(size_t s) = delete;
326 static void operator delete(void* p) = delete;
328 Heap(const Heap&) = delete;
330 const Heap& operator =(const Heap&) = delete;
331 };
332
338 Heap heap;
339
345 public:
347
348
349 static void* operator new(size_t s);
351 static void operator delete(void* p);
353 };
354
355
356 /*
357 * Wrappers for raw allocation routines
358 *
359 */
360 forceinline void*
361 Heap::ralloc(size_t s) {
362#ifdef GECODE_HAS_FAULT_INJECTION
364#endif
365 void* p = Support::allocator.alloc(s);
366#ifdef GECODE_PEAKHEAP
367 _m.acquire();
368 _cur += GECODE_MSIZE(p);
369 _peak = std::max(_peak,_cur);
370 _m.release();
371#endif
372 if (p != nullptr)
373 return p;
374 throw MemoryExhausted();
375 }
376
377 forceinline void
378 Heap::rfree(void* p) {
379#ifdef GECODE_PEAKHEAP
380 _m.acquire();
381 _cur -= GECODE_MSIZE(p);
382 _m.release();
383#endif
384 Support::allocator.free(p);
385 }
386
387 forceinline void
388 Heap::rfree(void* p, size_t) {
389#ifdef GECODE_PEAKHEAP
390 _m.acquire();
391 _cur -= GECODE_MSIZE(p);
392 _m.release();
393#endif
394 Support::allocator.free(p);
395 }
396
397 forceinline void*
398 Heap::rrealloc(void* p, size_t s) {
399#ifdef GECODE_HAS_FAULT_INJECTION
401#endif
402#ifdef GECODE_PEAKHEAP
403 _m.acquire();
404 _cur -= GECODE_MSIZE(p);
405 _m.release();
406#endif
407 p = Support::allocator.realloc(p,s);
408#ifdef GECODE_PEAKHEAP
409 _m.acquire();
410 _cur += GECODE_MSIZE(p);
411 _peak = std::max(_peak,_cur);
412 _m.release();
413#endif
414 if (p != nullptr || s == 0)
415 return p;
416 throw MemoryExhausted();
417 }
418
419
420 /*
421 * Heap allocated objects
422 *
423 */
424 forceinline void*
425 HeapAllocated::operator new(size_t s) {
426 return heap.ralloc(s);
427 }
428 forceinline void
429 HeapAllocated::operator delete(void* p) {
430 heap.rfree(p);
431 }
432
433
434
435 /*
436 * Typed allocation routines
437 *
438 */
439 template<class T>
440 forceinline T*
441 Heap::alloc(long unsigned int n) {
442 T* p = static_cast<T*>(ralloc(sizeof(T)*n));
443 for (long unsigned int i=0U; i<n; i++)
444 (void) new (p+i) T();
445 return p;
446 }
447 template<class T>
448 forceinline T*
449 Heap::alloc(long int n) {
450 assert(n >= 0);
451 return alloc<T>(static_cast<long unsigned int>(n));
452 }
453 template<class T>
454 forceinline T*
455 Heap::alloc(unsigned int n) {
456 return alloc<T>(static_cast<long unsigned int>(n));
457 }
458 template<class T>
459 forceinline T*
460 Heap::alloc(int n) {
461 assert(n >= 0);
462 return alloc<T>(static_cast<long unsigned int>(n));
463 }
464
465 template<class T>
466 forceinline void
467 Heap::free(T* b, long unsigned int n) {
468 for (long unsigned int i=0U; i<n; i++)
469 b[i].~T();
470 rfree(b);
471 }
472 template<class T>
473 forceinline void
474 Heap::free(T* b, long int n) {
475 assert(n >= 0);
476 free<T>(b, static_cast<long unsigned int>(n));
477 }
478 template<class T>
479 forceinline void
480 Heap::free(T* b, unsigned int n) {
481 free<T>(b, static_cast<long unsigned int>(n));
482 }
483 template<class T>
484 forceinline void
485 Heap::free(T* b, int n) {
486 assert(n >= 0);
487 free<T>(b, static_cast<long unsigned int>(n));
488 }
489
490 template<class T>
491 forceinline T*
492 Heap::realloc(T* b, long unsigned int n, long unsigned int m) {
493 if (n == m)
494 return b;
495 T* p = static_cast<T*>(ralloc(sizeof(T)*m));
496 for (long unsigned int i=0U; i<std::min(n,m); i++)
497 (void) new (p+i) T(b[i]);
498 for (long unsigned int i=n; i<m; i++)
499 (void) new (p+i) T();
500 free<T>(b,n);
501 return p;
502 }
503 template<class T>
504 forceinline T*
505 Heap::realloc(T* b, long int n, long int m) {
506 assert((n >= 0) && (m >= 0));
507 return realloc<T>(b,static_cast<long unsigned int>(n),
508 static_cast<long unsigned int>(m));
509 }
510 template<class T>
511 forceinline T*
512 Heap::realloc(T* b, unsigned int n, unsigned int m) {
513 return realloc<T>(b,static_cast<long unsigned int>(n),
514 static_cast<long unsigned int>(m));
515 }
516 template<class T>
517 forceinline T*
518 Heap::realloc(T* b, int n, int m) {
519 assert((n >= 0) && (m >= 0));
520 return realloc<T>(b,static_cast<long unsigned int>(n),
521 static_cast<long unsigned int>(m));
522 }
523
524#define GECODE_SUPPORT_REALLOC(T) \
525 template<> \
526 forceinline T* \
527 Heap::realloc<T>(T* b, long unsigned int, long unsigned int m) { \
528 return static_cast<T*>(rrealloc(b,m*sizeof(T))); \
529 } \
530 template<> \
531 forceinline T* \
532 Heap::realloc<T>(T* b, long int n, long int m) { \
533 assert((n >= 0) && (m >= 0)); \
534 return realloc<T>(b,static_cast<long unsigned int>(n), \
535 static_cast<long unsigned int>(m)); \
536 } \
537 template<> \
538 forceinline T* \
539 Heap::realloc<T>(T* b, unsigned int n, unsigned int m) { \
540 return realloc<T>(b,static_cast<long unsigned int>(n), \
541 static_cast<long unsigned int>(m)); \
542 } \
543 template<> \
544 forceinline T* \
545 Heap::realloc<T>(T* b, int n, int m) { \
546 assert((n >= 0) && (m >= 0)); \
547 return realloc<T>(b,static_cast<long unsigned int>(n), \
548 static_cast<long unsigned int>(m)); \
549 }
550
552 GECODE_SUPPORT_REALLOC(signed char)
553 GECODE_SUPPORT_REALLOC(unsigned char)
554 GECODE_SUPPORT_REALLOC(signed short int)
555 GECODE_SUPPORT_REALLOC(unsigned short int)
556 GECODE_SUPPORT_REALLOC(signed int)
557 GECODE_SUPPORT_REALLOC(unsigned int)
558 GECODE_SUPPORT_REALLOC(signed long int)
559 GECODE_SUPPORT_REALLOC(unsigned long int)
562
563#undef GECODE_SUPPORT_REALLOC
564
565 template<class T>
566 forceinline T**
567 Heap::realloc(T** b, long unsigned int, long unsigned int m) {
568 return static_cast<T**>(rrealloc(b,m*sizeof(T*)));
569 }
570 template<class T>
571 forceinline T**
572 Heap::realloc(T** b, long int n, long int m) {
573 assert((n >= 0) && (m >= 0));
574 return realloc<T*>(b,static_cast<long unsigned int>(n),
575 static_cast<long unsigned int>(m));
576 }
577 template<class T>
578 forceinline T**
579 Heap::realloc(T** b, unsigned int n, unsigned int m) {
580 return realloc<T*>(b,static_cast<long unsigned int>(n),
581 static_cast<long unsigned int>(m));
582 }
583 template<class T>
584 forceinline T**
585 Heap::realloc(T** b, int n, int m) {
586 assert((n >= 0) && (m >= 0));
587 return realloc<T*>(b,static_cast<long unsigned int>(n),
588 static_cast<long unsigned int>(m));
589 }
590
591 template<class T>
592 forceinline T*
593 Heap::copy(T* d, const T* s, long unsigned int n) {
594 for (long unsigned int i=0U; i<n; i++)
595 d[i]=s[i];
596 return d;
597 }
598 template<class T>
599 forceinline T*
600 Heap::copy(T* d, const T* s, long int n) {
601 assert(n >= 0);
602 return copy<T>(d,s,static_cast<long unsigned int>(n));
603 }
604 template<class T>
605 forceinline T*
606 Heap::copy(T* d, const T* s, unsigned int n) {
607 return copy<T>(d,s,static_cast<long unsigned int>(n));
608 }
609 template<class T>
610 forceinline T*
611 Heap::copy(T* d, const T* s, int n) {
612 assert(n >= 0);
613 return copy<T>(d,s,static_cast<long unsigned int>(n));
614 }
615
616#define GECODE_SUPPORT_COPY(T) \
617 template<> \
618 forceinline T* \
619 Heap::copy(T* d, const T* s, long unsigned int n) { \
620 return static_cast<T*>(Support::allocator.memcpy(d,s,n*sizeof(T))); \
621 } \
622 template<> \
623 forceinline T* \
624 Heap::copy(T* d, const T* s, long int n) { \
625 assert(n >= 0); \
626 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
627 } \
628 template<> \
629 forceinline T* \
630 Heap::copy(T* d, const T* s, unsigned int n) { \
631 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
632 } \
633 template<> \
634 forceinline T* \
635 Heap::copy(T* d, const T* s, int n) { \
636 assert(n >= 0); \
637 return copy<T>(d,s,static_cast<long unsigned int>(n)); \
638 }
639
641 GECODE_SUPPORT_COPY(signed char)
642 GECODE_SUPPORT_COPY(unsigned char)
643 GECODE_SUPPORT_COPY(signed short int)
644 GECODE_SUPPORT_COPY(unsigned short int)
645 GECODE_SUPPORT_COPY(signed int)
646 GECODE_SUPPORT_COPY(unsigned int)
647 GECODE_SUPPORT_COPY(signed long int)
648 GECODE_SUPPORT_COPY(unsigned long int)
650 GECODE_SUPPORT_COPY(double)
651
652#undef GECODE_SUPPORT_COPY
653
654 template<class T>
655 forceinline T**
656 Heap::copy(T** d, const T** s, long unsigned int n) {
657 return static_cast<T**>(Support::allocator.memcpy(d,s,n*sizeof(T*)));
658 }
659 template<class T>
660 forceinline T**
661 Heap::copy(T** d, const T** s, long int n) {
662 assert(n >= 0);
663 return copy<T*>(d,s,static_cast<long unsigned int>(n));
664 }
665 template<class T>
666 forceinline T**
667 Heap::copy(T** d, const T** s, unsigned int n) {
668 return copy<T*>(d,s,static_cast<long unsigned int>(n));
669 }
670 template<class T>
671 forceinline T**
672 Heap::copy(T** d, const T** s, int n) {
673 assert(n >= 0);
674 return copy<T*>(d,s,static_cast<long unsigned int>(n));
675 }
676
677#ifdef GECODE_PEAKHEAP
678 forceinline size_t
679 Heap::peak(void) {
680 _m.acquire();
681 size_t ret = _peak;
682 _m.release();
683 return ret;
684 }
685#endif
686
687}
688
689// STATISTICS: support-any
Base class for heap allocated objects.
Definition heap.hpp:344
Heap memory management class
Definition heap.hpp:66
Heap(const Heap &)=delete
Copy constructor (disabled).
Heap(void)
Default constructor (ensuring that only a single instance is created).
void * rrealloc(void *p, size_t s)
Change memory block starting at p to size s.
Definition heap.hpp:398
T * realloc(T *b, long unsigned int n, long unsigned int m)
Reallocate block of n objects starting at b to m objects of type T from heap.
Definition heap.hpp:492
static T * copy(T *d, const T *s, long unsigned int n)
Copy n objects starting at s to d.
Definition heap.hpp:593
void free(T *b, long unsigned int n)
Delete n objects starting at b.
Definition heap.hpp:467
T * alloc(long unsigned int n)
Allocate block of n objects of type T from heap.
Definition heap.hpp:441
void rfree(void *p)
Free memory block starting at p.
Definition heap.hpp:378
const Heap & operator=(const Heap &)=delete
Assignment operator (disabled).
void * ralloc(size_t s)
Allocate s bytes from heap.
Definition heap.hpp:361
Exception: Memory exhausted
Definition exception.hpp:63
A mutex for mutual exclausion among several threads.
Definition thread.hpp:78
Heap heap
The single global heap.
Allocator allocator
The single global default memory allocator.
#define GECODE_SUPPORT_REALLOC(T)
Definition heap.hpp:524
#define GECODE_SUPPORT_COPY(T)
Definition heap.hpp:616
void check(Phase p)
Check failpoint for phase p.
Gecode toplevel namespace
#define GECODE_SUPPORT_EXPORT
Definition support.hh:75