1
/* ========================================================================== */
2
/* === UMF_mem_free_tail_block ============================================== */
3
/* ========================================================================== */
5
/* -------------------------------------------------------------------------- */
6
/* UMFPACK Version 4.1 (Apr. 30, 2003), Copyright (c) 2003 by Timothy A. */
7
/* Davis. All Rights Reserved. See ../README for License. */
8
/* email: davis@cise.ufl.edu CISE Department, Univ. of Florida. */
9
/* web: http://www.cise.ufl.edu/research/sparse/umfpack */
10
/* -------------------------------------------------------------------------- */
12
/* The UMF_mem_* routines manage the Numeric->Memory memory space. */
14
/* free a block from the tail of Numeric->memory */
16
#include "umf_internal.h"
18
GLOBAL void UMF_mem_free_tail_block
24
Unit *pprev, *pnext, *p, *pbig ;
27
ASSERT (Numeric != (NumericType *) NULL) ;
28
ASSERT (Numeric->Memory != (Unit *) NULL) ;
29
if (i == EMPTY || i == 0) return ; /* already deallocated */
31
/* ---------------------------------------------------------------------- */
33
/* ---------------------------------------------------------------------- */
35
p = Numeric->Memory + i ;
37
p-- ; /* get the corresponding header */
38
DEBUG2 (("free block: p: "ID, (Int) (p-Numeric->Memory))) ;
39
ASSERT (p >= Numeric->Memory + Numeric->itail) ;
40
ASSERT (p < Numeric->Memory + Numeric->size) ;
41
ASSERT (p->header.size > 0) ; /* block not already free */
42
ASSERT (p->header.prevsize >= 0) ;
44
Numeric->tail_usage -= p->header.size + 1 ;
46
/* ---------------------------------------------------------------------- */
47
/* merge with next free block, if any */
48
/* ---------------------------------------------------------------------- */
50
pnext = p + 1 + p->header.size ;
51
DEBUG2 (("size: "ID" next: "ID" ", p->header.size,
52
(Int) (pnext-Numeric->Memory))) ;
53
ASSERT (pnext < Numeric->Memory + Numeric->size) ;
54
ASSERT (pnext->header.prevsize == p->header.size) ;
55
ASSERT (pnext->header.size != 0) ;
57
if (pnext->header.size < 0)
59
/* next block is also free - merge with current block */
60
p->header.size += (-(pnext->header.size)) + 1 ;
61
DEBUG2 ((" NEXT FREE ")) ;
64
/* ---------------------------------------------------------------------- */
65
/* merge with previous free block, if any */
66
/* ---------------------------------------------------------------------- */
69
if (p == Numeric->Memory + Numeric->itail)
71
DEBUG2 ((" at top of tail ")) ;
72
ASSERT (p->header.prevsize == 0) ;
76
if (p > Numeric->Memory + Numeric->itail)
78
ASSERT (p->header.prevsize > 0) ;
79
pprev = p - 1 - p->header.prevsize ;
80
DEBUG2 ((" prev: "ID" ", (Int) (pprev-Numeric->Memory))) ;
81
ASSERT (pprev >= Numeric->Memory + Numeric->itail) ;
82
sprev = pprev->header.size ;
85
/* previous block is also free - merge it with current block */
86
ASSERT (p->header.prevsize == -sprev) ;
87
pprev->header.size = p->header.size + (-sprev) + 1 ;
89
DEBUG2 ((" PREV FREE ")) ;
90
/* note that p may now point to Numeric->itail */
95
ASSERT (p->header.prevsize == sprev) ;
100
/* ---------------------------------------------------------------------- */
101
/* free the block, p */
102
/* ---------------------------------------------------------------------- */
104
pnext = p + 1 + p->header.size ;
105
ASSERT (pnext < Numeric->Memory + Numeric->size) ;
107
if (p == Numeric->Memory + Numeric->itail)
109
/* top block in list is freed */
110
Numeric->itail = pnext - Numeric->Memory ;
111
pnext->header.prevsize = 0 ;
112
DEBUG2 ((" NEW TAIL : "ID" ", Numeric->itail)) ;
113
ASSERT (pnext->header.size > 0) ;
114
if (Numeric->ibig != EMPTY && Numeric->ibig <= Numeric->itail)
116
/* the big free block is now above the tail */
117
Numeric->ibig = EMPTY ;
122
/* keep track of the biggest free block seen */
123
if (Numeric->ibig == EMPTY)
125
Numeric->ibig = p - Numeric->Memory ;
129
pbig = Numeric->Memory + Numeric->ibig ;
130
if (-(pbig->header.size) < p->header.size)
132
Numeric->ibig = p - Numeric->Memory ;
135
/* flag the block as free, somewhere in the middle of the tail */
136
pnext->header.prevsize = p->header.size ;
137
p->header.size = -(p->header.size) ;
140
DEBUG2 (("new p: "ID" freesize: "ID"\n", (Int) (p-Numeric->Memory),
141
-(p->header.size))) ;