2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
11 #include <isl_ctx_private.h>
13 /* The maximal number of cache misses before first element is evicted */
14 #define ISL_BLK_MAX_MISS 100
16 struct isl_blk
isl_blk_empty()
24 static int isl_blk_is_empty(struct isl_blk block
)
26 return block
.size
== 0 && block
.data
== NULL
;
29 static struct isl_blk
isl_blk_error()
37 int isl_blk_is_error(struct isl_blk block
)
39 return block
.size
== -1 && block
.data
== NULL
;
42 static struct isl_blk
extend(struct isl_ctx
*ctx
, struct isl_blk block
,
48 if (block
.size
>= new_n
)
52 block
.data
= isl_realloc_array(ctx
, block
.data
, isl_int
, new_n
);
55 return isl_blk_error();
58 for (i
= block
.size
; i
< new_n
; ++i
)
59 isl_int_init(block
.data
[i
]);
65 static void isl_blk_free_force(struct isl_ctx
*ctx
, struct isl_blk block
)
69 for (i
= 0; i
< block
.size
; ++i
)
70 isl_int_clear(block
.data
[i
]);
74 struct isl_blk
isl_blk_alloc(struct isl_ctx
*ctx
, size_t n
)
79 block
= isl_blk_empty();
80 if (n
&& ctx
->n_cached
) {
82 for (i
= 1; ctx
->cache
[best
].size
!= n
&& i
< ctx
->n_cached
; ++i
) {
83 if (ctx
->cache
[best
].size
< n
) {
84 if (ctx
->cache
[i
].size
> ctx
->cache
[best
].size
)
86 } else if (ctx
->cache
[i
].size
>= n
&&
87 ctx
->cache
[i
].size
< ctx
->cache
[best
].size
)
90 if (ctx
->cache
[best
].size
< 2 * n
+ 100) {
91 block
= ctx
->cache
[best
];
92 if (--ctx
->n_cached
!= best
)
93 ctx
->cache
[best
] = ctx
->cache
[ctx
->n_cached
];
96 } else if (ctx
->n_miss
++ >= ISL_BLK_MAX_MISS
) {
97 isl_blk_free_force(ctx
, ctx
->cache
[0]);
98 if (--ctx
->n_cached
!= 0)
99 ctx
->cache
[0] = ctx
->cache
[ctx
->n_cached
];
104 return extend(ctx
, block
, n
);
107 struct isl_blk
isl_blk_extend(struct isl_ctx
*ctx
, struct isl_blk block
,
110 if (isl_blk_is_empty(block
))
111 return isl_blk_alloc(ctx
, new_n
);
113 return extend(ctx
, block
, new_n
);
116 void isl_blk_free(struct isl_ctx
*ctx
, struct isl_blk block
)
118 if (isl_blk_is_empty(block
) || isl_blk_is_error(block
))
121 if (ctx
->n_cached
< ISL_BLK_CACHE_SIZE
)
122 ctx
->cache
[ctx
->n_cached
++] = block
;
124 isl_blk_free_force(ctx
, block
);
127 void isl_blk_clear_cache(struct isl_ctx
*ctx
)
131 for (i
= 0; i
< ctx
->n_cached
; ++i
)
132 isl_blk_free_force(ctx
, ctx
->cache
[i
]);