- bdescr *first, *q, *result = NULL;
-
- /* Get first megablock descriptor */
- first = FIRST_BDESCR(MBLOCK_ROUND_DOWN(p->start));
-
- /* Attempt to coalesce with predecessor if not the first block */
- if (p != first) {
- q = p - 1;
- if (!q->blocks) { // not a block head?
- q = q->link; // find the head.
- }
- /* Predecessor is free? */
- if (q->flags & BF_FREE) {
- q->blocks += p->blocks;
- initGroupTail( p->blocks, q, p );
- p = result = q;
- }
- }
-
- /* Attempt to coalesce with successor if not the last block */
- q = p + p->blocks;
- if (q != first + BLOCKS_PER_MBLOCK) {
- /* Successor is free */
- if (q->flags & BF_FREE) {
- if (result) {
- /* p is on free_list, q is on free_list, unlink
- * q completely and patch up list
- */
- if (q->u.back) {
- q->u.back->link = q->link;
- }
- if (q->link) {
- q->link->u.back = q->u.back;
- }
- if (free_list == q) {
- free_list = q->link;
- }
- } else {
- /* p is not on free_list just assume q's links */
- p->u.back = q->u.back;
- if (p->u.back) {
- p->u.back->link = p;
- }
- p->link = q->link;
- if (p->link) {
- p->link->u.back = p;
- }
- if (q == free_list) {
- free_list = p;
- free_list->u.back = NULL;
- }
- }
-
- p->blocks += q->blocks;
- initGroupTail( q->blocks, p, q );
- result = p;
- }
+ bdescr *bd, *q;
+ nat i, blocks;
+
+ q = p->link;
+ if (q != NULL && p->start + p->blocks * BLOCK_SIZE_W == q->start) {
+ /* can coalesce */
+ p->blocks += q->blocks;
+ p->link = q->link;
+ blocks = q->blocks;
+ for (i = 0, bd = q; i < blocks; bd++, i++) {
+ bd->free = 0;
+ bd->blocks = 0;
+ bd->link = p;