MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vmem_xalloc_nextfit

Function vmem_xalloc_nextfit

freebsd/kern/subr_vmem.c:1112–1196  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1110}
1111
1112static int
1113vmem_xalloc_nextfit(vmem_t *vm, const vmem_size_t size, vmem_size_t align,
1114 const vmem_size_t phase, const vmem_size_t nocross, int flags,
1115 vmem_addr_t *addrp)
1116{
1117 struct vmem_btag *bt, *cursor, *next, *prev;
1118 int error;
1119
1120 error = ENOMEM;
1121 VMEM_LOCK(vm);
1122
1123 /*
1124 * Make sure we have enough tags to complete the operation.
1125 */
1126 if (bt_fill(vm, flags) != 0)
1127 goto out;
1128
1129retry:
1130 /*
1131 * Find the next free tag meeting our constraints. If one is found,
1132 * perform the allocation.
1133 */
1134 for (cursor = &vm->vm_cursor, bt = TAILQ_NEXT(cursor, bt_seglist);
1135 bt != cursor; bt = TAILQ_NEXT(bt, bt_seglist)) {
1136 if (bt == NULL)
1137 bt = TAILQ_FIRST(&vm->vm_seglist);
1138 if (bt->bt_type == BT_TYPE_FREE && bt->bt_size >= size &&
1139 (error = vmem_fit(bt, size, align, phase, nocross,
1140 VMEM_ADDR_MIN, VMEM_ADDR_MAX, addrp)) == 0) {
1141 vmem_clip(vm, bt, *addrp, size);
1142 break;
1143 }
1144 }
1145
1146 /*
1147 * Try to coalesce free segments around the cursor. If we succeed, and
1148 * have not yet satisfied the allocation request, try again with the
1149 * newly coalesced segment.
1150 */
1151 if ((next = TAILQ_NEXT(cursor, bt_seglist)) != NULL &&
1152 (prev = TAILQ_PREV(cursor, vmem_seglist, bt_seglist)) != NULL &&
1153 next->bt_type == BT_TYPE_FREE && prev->bt_type == BT_TYPE_FREE &&
1154 prev->bt_start + prev->bt_size == next->bt_start) {
1155 prev->bt_size += next->bt_size;
1156 bt_remfree(vm, next);
1157 bt_remseg(vm, next);
1158
1159 /*
1160 * The coalesced segment might be able to satisfy our request.
1161 * If not, we might need to release it from the arena.
1162 */
1163 if (error == ENOMEM && prev->bt_size >= size &&
1164 (error = vmem_fit(prev, size, align, phase, nocross,
1165 VMEM_ADDR_MIN, VMEM_ADDR_MAX, addrp)) == 0) {
1166 vmem_clip(vm, prev, *addrp, size);
1167 bt = prev;
1168 } else
1169 (void)vmem_try_release(vm, prev, true);

Callers 1

vmem_xallocFunction · 0.85

Calls 7

bt_fillFunction · 0.85
vmem_fitFunction · 0.85
vmem_clipFunction · 0.85
bt_remfreeFunction · 0.85
bt_remsegFunction · 0.85
vmem_try_releaseFunction · 0.85
vmem_try_fetchFunction · 0.85

Tested by

no test coverage detected