* Allocate and initialize a new interval tree node. */
| 427 | * Allocate and initialize a new interval tree node. |
| 428 | */ |
| 429 | static Node *node(Node *parent, intptr_t lb, intptr_t ub, size_t size, |
| 430 | uint32_t flags) |
| 431 | { |
| 432 | bool alloc_left = ((flags & FLAG_RIGHT) != 0? false: |
| 433 | ((flags & FLAG_LB) != 0 || (flags & FLAG_UB) == 0)); |
| 434 | intptr_t LB, UB; |
| 435 | if (alloc_left) |
| 436 | { |
| 437 | LB = lb; |
| 438 | UB = lb + size; |
| 439 | } |
| 440 | else |
| 441 | { |
| 442 | LB = ub - size; |
| 443 | UB = ub; |
| 444 | } |
| 445 | |
| 446 | bool same_page = ((flags & FLAG_SAME_PAGE) != 0); |
| 447 | bool spans_pages = (LB / PAGE_SIZE != (UB-1) / PAGE_SIZE); |
| 448 | if (same_page && spans_pages) |
| 449 | { |
| 450 | off_t offset = (alloc_left? |
| 451 | (off_t)PAGE_SIZE - std::abs((intptr_t)(lb % PAGE_SIZE)): |
| 452 | -std::abs((intptr_t)(ub % PAGE_SIZE))); |
| 453 | LB += offset; |
| 454 | UB += offset; |
| 455 | assert(LB / PAGE_SIZE == (UB-1) / PAGE_SIZE); |
| 456 | if (LB < lb || UB > ub) |
| 457 | { |
| 458 | // Cannot fit into the current page == fail. |
| 459 | return nullptr; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | Node *n = alloc(); |
| 464 | n->alloc.lb = LB; |
| 465 | n->alloc.ub = UB; |
| 466 | n->lb = LB; |
| 467 | n->ub = UB; |
| 468 | n->entry.parent = parent; |
| 469 | n->entry.left = nullptr; |
| 470 | n->entry.right = nullptr; |
| 471 | n->color = RB_RED; |
| 472 | n->gap = 0; |
| 473 | return n; |
| 474 | } |
| 475 | |
| 476 | /* |
| 477 | * Insert left-child helper. |
no test coverage detected