root/oshmem/mca/memheap/buddy/memheap_buddy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bits_per_long
  2. bitmap_zero
  3. __clear_bit
  4. __set_bit
  5. test_bit
  6. __ffs
  7. memheap_buddy_find_order
  8. find_next_bit
  9. mca_memheap_buddy_module_init
  10. buddy_init
  11. buddy_cleanup
  12. _buddy_alloc
  13. _buddy_free
  14. buddy_free
  15. buddy_private_free
  16. _do_alloc
  17. do_alloc
  18. do_private_alloc
  19. mca_memheap_buddy_alloc
  20. mca_memheap_buddy_private_alloc
  21. mca_memheap_buddy_private_free
  22. mca_memheap_buddy_align
  23. mca_memheap_buddy_realloc
  24. mca_memheap_buddy_free
  25. mca_memheap_buddy_finalize

   1 /* Copyright (c) 2013      Mellanox Technologies, Inc.
   2  *                         All rights reserved.
   3  * Copyright (c) 2019      Research Organization for Information Science
   4  *                         and Technology (RIST).  All rights reserved.
   5  * $COPYRIGHT$
   6  *
   7  * Additional copyrights may follow
   8  *
   9  * $HEADER$
  10  */
  11 
  12 #include "oshmem_config.h"
  13 #include "oshmem/proc/proc.h"
  14 #include "oshmem/mca/spml/spml.h"
  15 #include "oshmem/mca/memheap/memheap.h"
  16 #include "oshmem/mca/memheap/buddy/memheap_buddy.h"
  17 #include "oshmem/mca/memheap/buddy/memheap_buddy_component.h"
  18 #include "oshmem/mca/memheap/base/base.h"
  19 #include "opal/class/opal_hash_table.h"
  20 #include "opal/class/opal_object.h"
  21 
  22 static int buddy_init(mca_memheap_buddy_module_t* buddy);
  23 
  24 mca_memheap_buddy_module_t memheap_buddy = {
  25     {
  26         &mca_memheap_buddy_component,
  27         mca_memheap_buddy_finalize,
  28         mca_memheap_buddy_alloc,
  29         mca_memheap_buddy_align,
  30         mca_memheap_buddy_realloc,
  31         mca_memheap_buddy_free,
  32 
  33         mca_memheap_buddy_private_alloc,
  34         mca_memheap_buddy_private_free,
  35 
  36         mca_memheap_base_get_mkey,
  37         mca_memheap_base_is_symmetric_addr,
  38         mca_memheap_modex_recv_all,
  39 
  40         0
  41     },
  42     1   /* priority */
  43 };
  44 
  45 /* Memory Heap Buddy Implementation */
  46 
  47 /* Static inline functions */
  48 static inline unsigned int bits_per_long(void)
  49 {
  50     return BITS_PER_BYTE * sizeof(unsigned long);
  51 }
  52 
  53 static inline void bitmap_zero(unsigned long *dst, unsigned long nbits)
  54 {
  55     unsigned long len = BITS_TO_LONGS(nbits) * sizeof(unsigned long);
  56     memset(dst, 0, len);
  57 }
  58 
  59 /*
  60  * WARNING: Non atomic version.
  61  */
  62 static inline void __clear_bit(unsigned long nr, volatile void * addr)
  63 {
  64     int *m = ((int *) addr) + (nr >> 5);
  65     *m &= ~(1 << (nr & 31));
  66 }
  67 
  68 /*
  69  * WARNING: non atomic version.
  70  */
  71 static inline void __set_bit(unsigned long nr, volatile void * addr)
  72 {
  73     int *m = ((int *) addr) + (nr >> 5);
  74     *m |= 1 << (nr & 31);
  75 }
  76 
  77 static inline int test_bit(int nr, const volatile void * addr)
  78 {
  79     return (1UL & (((const int *) addr)[nr >> 5] >> (nr & 31))) != 0UL;
  80 }
  81 
  82 /*
  83  * __ffs - find first bit in word.
  84  * @word: The word to search
  85  *
  86  * Undefined if no bit exists, so code should check against 0 first.
  87  */
  88 static inline __opal_attribute_always_inline__ unsigned long __ffs(unsigned long word)
  89 {
  90     int num = 0;
  91 #if SIZEOF_LONG == 8
  92         if ((word & 0xffffffff) == 0) {
  93             num += 32;
  94             word >>= 32;
  95         }
  96 #endif
  97 
  98     if ((word & 0xffff) == 0) {
  99         num += 16;
 100         word >>= 16;
 101     }
 102     if ((word & 0xff) == 0) {
 103         num += 8;
 104         word >>= 8;
 105     }
 106     if ((word & 0xf) == 0) {
 107         num += 4;
 108         word >>= 4;
 109     }
 110     if ((word & 0x3) == 0) {
 111         num += 2;
 112         word >>= 2;
 113     }
 114     if ((word & 0x1) == 0)
 115     num += 1;
 116     return num;
 117 }
 118 
 119 /* round up to next power of two */
 120 static inline unsigned memheap_buddy_find_order(unsigned long size)
 121 {
 122     unsigned order;
 123 
 124     if (size & (size - 1))
 125         order = 1;
 126     else
 127         order = 0;
 128 
 129     while (size >>= 1) {
 130         order++;
 131     }
 132     return order;
 133 }
 134 
 135 /*
 136  * find the first set bit in a memory region
 137  * @addr: The address to base the search on
 138  * @offset: The bitnumber to start searching at
 139  * @size: The maximum size to search
 140  */
 141 
 142 static inline unsigned long find_next_bit(const unsigned long *addr,
 143                                           unsigned long size,
 144                                           unsigned long offset)
 145 {
 146     const unsigned long *p = addr + BITOP_WORD(offset);
 147     unsigned long result = offset & ~(bits_per_long() - 1);
 148     unsigned long tmp;
 149 
 150     if (offset >= size)
 151         return size;
 152     size -= result;
 153     offset %= bits_per_long();
 154     if (offset) {
 155         tmp = *(p++);
 156         tmp &= (~0UL << offset);
 157         if (size < bits_per_long())
 158             goto found_first;
 159         if (tmp)
 160             goto found_middle;
 161         size -= bits_per_long();
 162         result += bits_per_long();
 163     }
 164     while (size & ~(bits_per_long() - 1)) {
 165         if ((tmp = *(p++)))
 166             goto found_middle;
 167         result += bits_per_long();
 168         size -= bits_per_long();
 169     }
 170     if (!size)
 171         return result;
 172     tmp = *p;
 173 
 174     found_first: tmp &= (~0UL >> (bits_per_long() - size));
 175     if (tmp == 0UL) /* Are any bits set? */
 176         return result + size; /* Nope. */
 177     found_middle: return result + __ffs(tmp);
 178 }
 179 
 180 /**
 181  * Initialize the Memory Heap
 182  */
 183 int mca_memheap_buddy_module_init(memheap_context_t *context)
 184 {
 185     if (!context || !context->user_size || !context->private_size) {
 186         return OSHMEM_ERR_BAD_PARAM;
 187     }
 188 
 189     /* Construct a mutex object */
 190     OBJ_CONSTRUCT(&memheap_buddy.lock, opal_mutex_t);
 191 
 192     memheap_buddy.heap.max_order = memheap_log2(context->user_size);
 193     memheap_buddy.heap.min_order = MEMHEAP_BASE_MIN_ORDER;
 194     memheap_buddy.private_heap.max_order = memheap_log2(context->private_size);
 195     memheap_buddy.private_heap.min_order = MEMHEAP_BASE_MIN_ORDER;
 196 
 197     if (context->user_size != (1ULL << memheap_buddy.heap.max_order)) {
 198         MEMHEAP_VERBOSE(1,
 199                         "Memheap rounded to the nearest power of two: requested %llu bytes, allocated %llu bytes",
 200                         (unsigned long long)context->user_size, 1ULL << memheap_buddy.heap.max_order);
 201     }
 202 
 203     assert(context->private_size == (1ULL << memheap_buddy.private_heap.max_order));
 204 
 205     memheap_buddy.heap.symmetric_heap = context->user_base_addr;
 206     memheap_buddy.private_heap.symmetric_heap = context->private_base_addr;
 207 
 208     memheap_buddy.super.memheap_size = (1ULL << memheap_buddy.heap.max_order);
 209 
 210     MEMHEAP_VERBOSE(1,
 211                     "symmetric heap memory (user+private): %llu bytes",
 212                     (unsigned long long)(context->user_size + context->private_size));
 213 
 214     /* Initialize buddy allocator */
 215     if (OSHMEM_SUCCESS != buddy_init(&memheap_buddy)) {
 216         MEMHEAP_ERROR("Failed to setup MEMHEAP buddy allocator");
 217         goto err;
 218     }
 219 
 220     return OSHMEM_SUCCESS;
 221 
 222     err: mca_memheap_buddy_finalize();
 223     return OSHMEM_ERROR;
 224 }
 225 
 226 static int buddy_init(mca_memheap_buddy_module_t* buddy)
 227 {
 228     unsigned long long total_size;
 229     unsigned i;
 230     unsigned long long s;
 231 
 232     /* Allocate and init Hashtable */
 233     memheap_buddy.heap.symmetric_heap_hashtable = OBJ_NEW(opal_hash_table_t);
 234     if (NULL == memheap_buddy.heap.symmetric_heap_hashtable) {
 235         MEMHEAP_ERROR("Opal failed to allocate hashtable object");
 236         goto err;
 237     }
 238     memheap_buddy.private_heap.symmetric_heap_hashtable =
 239             OBJ_NEW(opal_hash_table_t);
 240     if (NULL == memheap_buddy.private_heap.symmetric_heap_hashtable) {
 241         MEMHEAP_ERROR("Opal failed to allocate hashtable object");
 242         goto err;
 243     }
 244 
 245     opal_hash_table_init(memheap_buddy.heap.symmetric_heap_hashtable,
 246                          DEFAULT_HASHTABLE_SIZE);
 247     opal_hash_table_init(memheap_buddy.private_heap.symmetric_heap_hashtable,
 248                          DEFAULT_HASHTABLE_SIZE);
 249     /* Init Buddy Allocator */
 250     buddy->heap.bits = (unsigned long**) calloc((buddy->heap.max_order + 1),
 251                                                 sizeof(unsigned long *));
 252     buddy->private_heap.bits =
 253             (unsigned long**) calloc((buddy->private_heap.max_order + 1),
 254                                      sizeof(unsigned long *));
 255     buddy->heap.num_free = (unsigned int*) calloc((buddy->heap.max_order + 1),
 256                                                   sizeof(unsigned int));
 257     buddy->private_heap.num_free =
 258             (unsigned int*) calloc((buddy->private_heap.max_order + 1),
 259                                    sizeof(unsigned int));
 260     if ((NULL == buddy->heap.bits) || (NULL == buddy->heap.num_free)
 261             || (NULL == buddy->private_heap.bits)
 262             || (NULL == buddy->private_heap.num_free)) {
 263 
 264         MEMHEAP_ERROR("Failed to allocate buddy allocator");
 265         goto err;
 266     }
 267 
 268     total_size = 0;
 269     for (i = buddy->heap.min_order; i <= buddy->heap.max_order; ++i) {
 270         s = BITS_TO_LONGS(1UL << (buddy->heap.max_order - i));
 271         MEMHEAP_VERBOSE(20,
 272                         "%d: (order=%d) allocating %llu longs (sizeof long = %d)",
 273                         i, buddy->heap.max_order, s, (int)sizeof(unsigned long));
 274         total_size += s * sizeof(unsigned long);
 275         buddy->heap.bits[i] = (unsigned long*) malloc(s
 276                 * sizeof(unsigned long));
 277         if (NULL == buddy->heap.bits[i]) {
 278             MEMHEAP_ERROR("Failed to allocate buddy->allocator");
 279             goto err;
 280         }
 281         bitmap_zero(buddy->heap.bits[i], 1UL << (buddy->heap.max_order - i));
 282     }
 283     MEMHEAP_VERBOSE(5, "MEMHEAP metadata size = %llu bytes", total_size);
 284 
 285     total_size = 0;
 286     for (i = buddy->private_heap.min_order; i <= buddy->private_heap.max_order;
 287             ++i) {
 288         s = BITS_TO_LONGS(1UL << (buddy->private_heap.max_order - i));
 289         MEMHEAP_VERBOSE(20,
 290                         "%d: (order=%d) allocating %llu longs (sizeof long = %d)",
 291                         i, buddy->private_heap.max_order, s, (int)sizeof(unsigned long));
 292         total_size += s * sizeof(unsigned long);
 293         buddy->private_heap.bits[i] = (unsigned long*) malloc(s
 294                 * sizeof(unsigned long));
 295         if (NULL == buddy->private_heap.bits[i]) {
 296             MEMHEAP_ERROR("Failed to allocate buddy->allocator");
 297             goto err;
 298         }
 299         bitmap_zero(buddy->private_heap.bits[i],
 300                     1UL << (buddy->private_heap.max_order - i));
 301     }
 302     MEMHEAP_VERBOSE(5,
 303                     "private MEMHEAP metadata size = %llu bytes",
 304                     total_size);
 305 
 306     set_bit(0, buddy->heap.bits[buddy->heap.max_order]);
 307     set_bit(0, buddy->private_heap.bits[buddy->private_heap.max_order]);
 308     buddy->heap.num_free[buddy->heap.max_order] = 1;
 309     buddy->private_heap.num_free[buddy->private_heap.max_order] = 1;
 310 
 311     return OSHMEM_SUCCESS;
 312 
 313     err: return OSHMEM_ERROR;
 314 }
 315 
 316 static int buddy_cleanup(mca_memheap_buddy_module_t* buddy)
 317 {
 318     unsigned int i;
 319 
 320     MEMHEAP_VERBOSE(5, "buddy cleanup");
 321     if (NULL == buddy) {
 322         return OSHMEM_SUCCESS;
 323     }
 324 
 325     for (i = 0; i <= buddy->heap.max_order; ++i) {
 326         if (NULL != buddy->heap.bits && NULL != buddy->heap.bits[i]) {
 327             free(buddy->heap.bits[i]);
 328         }
 329     }
 330 
 331     for (i = 0; i <= buddy->private_heap.max_order; ++i) {
 332         if (NULL != buddy->private_heap.bits
 333                 && NULL != buddy->private_heap.bits[i]) {
 334             free(buddy->private_heap.bits[i]);
 335         }
 336     }
 337 
 338     if (NULL != buddy->heap.bits) {
 339         free(buddy->heap.bits);
 340     }
 341     if (NULL != buddy->heap.num_free) {
 342         free(buddy->heap.num_free);
 343     }
 344 
 345     if (NULL != buddy->private_heap.bits) {
 346         free(buddy->private_heap.bits);
 347     }
 348     if (NULL != buddy->private_heap.num_free) {
 349         free(buddy->private_heap.num_free);
 350     }
 351 
 352     OBJ_DESTRUCT(&buddy->lock);
 353     return OSHMEM_SUCCESS;
 354 }
 355 
 356 static int _buddy_alloc(unsigned order,
 357                         uint32_t* seg,
 358                         mca_memheap_buddy_heap_t *heap)
 359 {
 360     uint32_t o;
 361     uint32_t m;
 362 
 363     MEMHEAP_VERBOSE(20, "order=%d size=%d", order, 1<<order);
 364     OPAL_THREAD_LOCK(&memheap_buddy.lock);
 365     for (o = order; o <= heap->max_order; ++o) {
 366         if (heap->num_free[o]) {
 367             m = 1 << (heap->max_order - o);
 368             *seg = find_first_bit(heap->bits[o], m);
 369             MEMHEAP_VERBOSE(20,
 370                             "found free bit: order=%d, bits=0x%lx m=%d, *seg=%d",
 371                             o, heap->bits[o][0], m, *seg);
 372             if (*seg < m)
 373                 goto found;
 374         }
 375     }
 376 
 377     OPAL_THREAD_UNLOCK(&memheap_buddy.lock);
 378     return OSHMEM_ERROR;
 379 
 380     found:
 381     clear_bit(*seg, heap->bits[o]);
 382     --(heap->num_free[o]);
 383 
 384     while (o > order) {
 385         --o;
 386         *seg <<= 1;
 387         set_bit(*seg ^ 1, heap->bits[o]);
 388         ++(heap->num_free[o]);
 389     }
 390 
 391     OPAL_THREAD_UNLOCK(&memheap_buddy.lock);
 392     *seg <<= order;
 393 
 394     return OSHMEM_SUCCESS;
 395 }
 396 
 397 static int _buddy_free(mca_memheap_buddy_module_t* buddy,
 398                        uint32_t seg,
 399                        unsigned order,
 400                        mca_memheap_buddy_heap_t *heap)
 401 {
 402     MEMHEAP_VERBOSE(20, "order=%d size=%d seg=%d", order, 1<<order, seg);
 403     seg >>= order;
 404     OPAL_THREAD_LOCK(&buddy->lock);
 405 
 406     while (test_bit(seg ^ 1, heap->bits[order])) {
 407         clear_bit(seg ^ 1, heap->bits[order]);
 408         --(heap->num_free[order]);
 409         seg >>= 1;
 410         ++order;
 411     }
 412 
 413     set_bit(seg, heap->bits[order]);
 414     ++(heap->num_free[order]);
 415     OPAL_THREAD_UNLOCK(&buddy->lock);
 416     return OSHMEM_SUCCESS;
 417 }
 418 
 419 static int buddy_free(mca_memheap_buddy_module_t* buddy,
 420                       uint32_t seg,
 421                       unsigned order)
 422 {
 423     return _buddy_free(buddy, seg, order, &buddy->heap);
 424 }
 425 
 426 static int buddy_private_free(mca_memheap_buddy_module_t* buddy,
 427                               uint32_t seg,
 428                               unsigned order)
 429 {
 430     return _buddy_free(buddy, seg, order, &buddy->private_heap);
 431 }
 432 
 433 static int _do_alloc(uint32_t order,
 434                      void **p_buff,
 435                      mca_memheap_buddy_heap_t *heap)
 436 {
 437     int rc;
 438     unsigned long base;
 439     uint32_t offset;
 440     unsigned long addr;
 441 
 442     if (order < heap->min_order)
 443         order = heap->min_order;
 444 
 445     *p_buff = 0;
 446     if (order > heap->max_order) {
 447         /* Test allocated size overflow */
 448         MEMHEAP_VERBOSE(5, "Allocation overflow of symmetric heap size");
 449         return OSHMEM_ERROR;
 450     }
 451 
 452     base = (unsigned long) heap->symmetric_heap;
 453 
 454     if (OSHMEM_SUCCESS != _buddy_alloc(order, &offset, heap)) {
 455         MEMHEAP_VERBOSE(5, "Buddy Allocator failed to return a base address");
 456         return OSHMEM_ERROR;
 457     }
 458 
 459     /* Save the order of the allocated variable */
 460     addr = base + offset;
 461 
 462     rc = opal_hash_table_set_value_uint64(heap->symmetric_heap_hashtable,
 463                                           addr,
 464                                           (void *) (unsigned long) order);
 465 
 466     if (OPAL_SUCCESS != rc) {
 467         MEMHEAP_VERBOSE(5, "Failed to insert order to hashtable");
 468         goto alloc_error;
 469     }
 470 
 471     *p_buff = (void*) addr;
 472     MCA_SPML_CALL(memuse_hook(*p_buff, 1ULL<<order));
 473     return OSHMEM_SUCCESS;
 474 
 475     alloc_error: _buddy_free(&memheap_buddy, offset, order, heap);
 476     return OSHMEM_ERROR;
 477 }
 478 
 479 static int do_alloc(uint32_t order, void **p_buff)
 480 {
 481     return _do_alloc(order, p_buff, &(memheap_buddy.heap));
 482 }
 483 
 484 static int do_private_alloc(uint32_t order, void **p_buff)
 485 {
 486     return _do_alloc(order, p_buff, &(memheap_buddy.private_heap));
 487 }
 488 
 489 /**
 490  * Allocate size bytes on the symmetric heap.
 491  * The allocated variable is aligned to its size.
 492  */
 493 int mca_memheap_buddy_alloc(size_t size, void** p_buff)
 494 {
 495 
 496     uint32_t order;
 497 
 498     order = memheap_buddy_find_order(size);
 499 
 500     return do_alloc(order, p_buff);
 501 }
 502 
 503 int mca_memheap_buddy_private_alloc(size_t size, void** p_buff)
 504 {
 505     uint32_t order;
 506     int status = 0;
 507     order = memheap_buddy_find_order(size);
 508 
 509     status = do_private_alloc(order, p_buff);
 510 
 511     MEMHEAP_VERBOSE(20, "private alloc addr: %p", *p_buff);
 512 
 513     return status;
 514 }
 515 
 516 int mca_memheap_buddy_private_free(void* ptr)
 517 {
 518     int rc;
 519     uint32_t offset;
 520     unsigned long addr;
 521     unsigned long base;
 522     void *order;
 523 
 524     if (0 == ptr) {
 525         return OSHMEM_SUCCESS;
 526     }
 527 
 528     base = (unsigned long) memheap_buddy.private_heap.symmetric_heap;
 529     addr = (unsigned long) ptr;
 530     offset = addr - base;
 531 
 532     rc =
 533             opal_hash_table_get_value_uint64(memheap_buddy.private_heap.symmetric_heap_hashtable,
 534                                              addr,
 535                                              &order);
 536     if (OPAL_SUCCESS != rc) {
 537         return OSHMEM_ERROR;
 538     }
 539 
 540     buddy_private_free(&memheap_buddy,
 541                        offset,
 542                        (unsigned) (unsigned long) order);
 543     opal_hash_table_remove_value_uint64(memheap_buddy.private_heap.symmetric_heap_hashtable,
 544                                         addr);
 545 
 546     return OSHMEM_SUCCESS;
 547 }
 548 
 549 int mca_memheap_buddy_align(size_t align, size_t size, void **p_buff)
 550 {
 551     uint32_t order;
 552 
 553     if (align == 0) {
 554         *p_buff = 0;
 555         return OSHMEM_ERROR;
 556     }
 557 
 558     /* check that align is power of 2 */
 559     if (align & (align - 1)) {
 560         *p_buff = 0;
 561         return OSHMEM_ERROR;
 562     }
 563 
 564     order = memheap_buddy_find_order(size);
 565     if ((unsigned long) align > (1UL << order))
 566         order = memheap_buddy_find_order(align);
 567 
 568     return do_alloc(order, p_buff);
 569 }
 570 
 571 int mca_memheap_buddy_realloc(size_t new_size, void *p_buff, void **p_new_buff)
 572 {
 573     int rc;
 574     unsigned long addr;
 575     void *order;
 576     size_t old_size;
 577     char *tmp_buf;
 578 
 579     /* equiv to alloc if old ptr is null */
 580     if (NULL == p_buff)
 581         return mca_memheap_buddy_alloc(new_size, p_new_buff);
 582 
 583     addr = (unsigned long) p_buff;
 584 
 585     rc =
 586             opal_hash_table_get_value_uint64(memheap_buddy.heap.symmetric_heap_hashtable,
 587                                              addr,
 588                                              &order);
 589     if (OPAL_SUCCESS != rc) {
 590         *p_new_buff = NULL;
 591         return OSHMEM_ERROR;
 592     }
 593 
 594     /* equiv to free if new_size is 0 */
 595     if (0 == new_size) {
 596         *p_new_buff = NULL;
 597         return mca_memheap_buddy_free(p_buff);
 598     }
 599 
 600     old_size = 1UL << (unsigned long) order;
 601 
 602     /* do nothing if new size is less then current size */
 603     if (new_size <= old_size) {
 604         *p_new_buff = p_buff;
 605         return OSHMEM_SUCCESS;
 606     }
 607 
 608     if (new_size > (1UL << memheap_buddy.heap.max_order)) {
 609         *p_new_buff = NULL;
 610         return OSHMEM_ERR_OUT_OF_RESOURCE;
 611     }
 612 
 613     if (old_size + new_size >= (1UL << memheap_buddy.heap.max_order)) {
 614         /* copy via temporary buffer */
 615 
 616         tmp_buf = (char *) malloc(old_size);
 617         if (!tmp_buf)
 618             return OSHMEM_ERR_OUT_OF_RESOURCE;
 619         memcpy(tmp_buf, p_buff, old_size);
 620         mca_memheap_buddy_free(p_buff);
 621     } else
 622         tmp_buf = p_buff;
 623 
 624     /* alloc and copy data to new buffer, free old one */
 625     rc = mca_memheap_buddy_alloc(new_size, p_new_buff);
 626     if (OSHMEM_SUCCESS != rc) {
 627         *p_new_buff = NULL;
 628         if (old_size + new_size >= (1UL << memheap_buddy.heap.max_order)
 629                 && tmp_buf) {
 630             free(tmp_buf);
 631         }
 632         return rc;
 633     }
 634 
 635     memcpy(*p_new_buff, tmp_buf, old_size);
 636 
 637     if (old_size + new_size < (1UL << memheap_buddy.heap.max_order))
 638         mca_memheap_buddy_free(p_buff);
 639     else if (tmp_buf)
 640         free(tmp_buf);
 641 
 642     return OSHMEM_SUCCESS;
 643 }
 644 
 645 /*
 646  * Free a variable allocated on the
 647  * symmetric heap.
 648  */
 649 int mca_memheap_buddy_free(void* ptr)
 650 {
 651     int rc;
 652     uint32_t offset;
 653     unsigned long addr;
 654     unsigned long base;
 655     void *order;
 656 
 657     base = (unsigned long) memheap_buddy.heap.symmetric_heap;
 658     addr = (unsigned long) ptr;
 659     offset = addr - base;
 660 
 661     rc =
 662             opal_hash_table_get_value_uint64(memheap_buddy.heap.symmetric_heap_hashtable,
 663                                              addr,
 664                                              &order);
 665     if (OPAL_SUCCESS != rc) {
 666         return OSHMEM_ERROR;
 667     }
 668 
 669     buddy_free(&memheap_buddy, offset, (unsigned) (unsigned long) order);
 670     opal_hash_table_remove_value_uint64(memheap_buddy.heap.symmetric_heap_hashtable,
 671                                         addr);
 672 
 673     return OSHMEM_SUCCESS;
 674 }
 675 
 676 int mca_memheap_buddy_finalize()
 677 {
 678     MEMHEAP_VERBOSE(5, "deregistering symmetric heap");
 679 
 680     /* was not initialized - do nothing */
 681     if (memheap_buddy.heap.max_order == 0)
 682         return OSHMEM_SUCCESS;
 683 
 684     /* Destruct hashtable supporting shfree of symmetric heap variables */
 685     if (memheap_buddy.heap.symmetric_heap_hashtable) {
 686         OBJ_RELEASE(memheap_buddy.heap.symmetric_heap_hashtable);
 687     }
 688     if (memheap_buddy.private_heap.symmetric_heap_hashtable) {
 689         OBJ_RELEASE(memheap_buddy.private_heap.symmetric_heap_hashtable);
 690     }
 691 
 692     buddy_cleanup(&memheap_buddy);
 693 
 694     return OSHMEM_SUCCESS;
 695 }
 696 

/* [<][>][^][v][top][bottom][index][help] */