1*5971e316Smrg /*
2*5971e316Smrg * Copyright 2008-2009 Katholieke Universiteit Leuven
3*5971e316Smrg *
4*5971e316Smrg * Use of this software is governed by the MIT license
5*5971e316Smrg *
6*5971e316Smrg * Written by Sven Verdoolaege, K.U.Leuven, Departement
7*5971e316Smrg * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8*5971e316Smrg */
9*5971e316Smrg
10*5971e316Smrg #include <isl_blk.h>
11*5971e316Smrg #include <isl_ctx_private.h>
12*5971e316Smrg
13*5971e316Smrg /* The maximal number of cache misses before first element is evicted */
14*5971e316Smrg #define ISL_BLK_MAX_MISS 100
15*5971e316Smrg
isl_blk_empty()16*5971e316Smrg struct isl_blk isl_blk_empty()
17*5971e316Smrg {
18*5971e316Smrg struct isl_blk block;
19*5971e316Smrg block.size = 0;
20*5971e316Smrg block.data = NULL;
21*5971e316Smrg return block;
22*5971e316Smrg }
23*5971e316Smrg
isl_blk_is_empty(struct isl_blk block)24*5971e316Smrg static int isl_blk_is_empty(struct isl_blk block)
25*5971e316Smrg {
26*5971e316Smrg return block.size == 0 && block.data == NULL;
27*5971e316Smrg }
28*5971e316Smrg
isl_blk_error()29*5971e316Smrg static struct isl_blk isl_blk_error()
30*5971e316Smrg {
31*5971e316Smrg struct isl_blk block;
32*5971e316Smrg block.size = -1;
33*5971e316Smrg block.data = NULL;
34*5971e316Smrg return block;
35*5971e316Smrg }
36*5971e316Smrg
isl_blk_is_error(struct isl_blk block)37*5971e316Smrg int isl_blk_is_error(struct isl_blk block)
38*5971e316Smrg {
39*5971e316Smrg return block.size == -1 && block.data == NULL;
40*5971e316Smrg }
41*5971e316Smrg
isl_blk_free_force(struct isl_ctx * ctx,struct isl_blk block)42*5971e316Smrg static void isl_blk_free_force(struct isl_ctx *ctx, struct isl_blk block)
43*5971e316Smrg {
44*5971e316Smrg int i;
45*5971e316Smrg
46*5971e316Smrg for (i = 0; i < block.size; ++i)
47*5971e316Smrg isl_int_clear(block.data[i]);
48*5971e316Smrg free(block.data);
49*5971e316Smrg }
50*5971e316Smrg
extend(struct isl_ctx * ctx,struct isl_blk block,size_t new_n)51*5971e316Smrg static struct isl_blk extend(struct isl_ctx *ctx, struct isl_blk block,
52*5971e316Smrg size_t new_n)
53*5971e316Smrg {
54*5971e316Smrg int i;
55*5971e316Smrg isl_int *p;
56*5971e316Smrg
57*5971e316Smrg if (block.size >= new_n)
58*5971e316Smrg return block;
59*5971e316Smrg
60*5971e316Smrg p = isl_realloc_array(ctx, block.data, isl_int, new_n);
61*5971e316Smrg if (!p) {
62*5971e316Smrg isl_blk_free_force(ctx, block);
63*5971e316Smrg return isl_blk_error();
64*5971e316Smrg }
65*5971e316Smrg block.data = p;
66*5971e316Smrg
67*5971e316Smrg for (i = block.size; i < new_n; ++i)
68*5971e316Smrg isl_int_init(block.data[i]);
69*5971e316Smrg block.size = new_n;
70*5971e316Smrg
71*5971e316Smrg return block;
72*5971e316Smrg }
73*5971e316Smrg
isl_blk_alloc(struct isl_ctx * ctx,size_t n)74*5971e316Smrg struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n)
75*5971e316Smrg {
76*5971e316Smrg int i;
77*5971e316Smrg struct isl_blk block;
78*5971e316Smrg
79*5971e316Smrg block = isl_blk_empty();
80*5971e316Smrg if (n && ctx->n_cached) {
81*5971e316Smrg int best = 0;
82*5971e316Smrg for (i = 1; ctx->cache[best].size != n && i < ctx->n_cached; ++i) {
83*5971e316Smrg if (ctx->cache[best].size < n) {
84*5971e316Smrg if (ctx->cache[i].size > ctx->cache[best].size)
85*5971e316Smrg best = i;
86*5971e316Smrg } else if (ctx->cache[i].size >= n &&
87*5971e316Smrg ctx->cache[i].size < ctx->cache[best].size)
88*5971e316Smrg best = i;
89*5971e316Smrg }
90*5971e316Smrg if (ctx->cache[best].size < 2 * n + 100) {
91*5971e316Smrg block = ctx->cache[best];
92*5971e316Smrg if (--ctx->n_cached != best)
93*5971e316Smrg ctx->cache[best] = ctx->cache[ctx->n_cached];
94*5971e316Smrg if (best == 0)
95*5971e316Smrg ctx->n_miss = 0;
96*5971e316Smrg } else if (ctx->n_miss++ >= ISL_BLK_MAX_MISS) {
97*5971e316Smrg isl_blk_free_force(ctx, ctx->cache[0]);
98*5971e316Smrg if (--ctx->n_cached != 0)
99*5971e316Smrg ctx->cache[0] = ctx->cache[ctx->n_cached];
100*5971e316Smrg ctx->n_miss = 0;
101*5971e316Smrg }
102*5971e316Smrg }
103*5971e316Smrg
104*5971e316Smrg return extend(ctx, block, n);
105*5971e316Smrg }
106*5971e316Smrg
isl_blk_extend(struct isl_ctx * ctx,struct isl_blk block,size_t new_n)107*5971e316Smrg struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block,
108*5971e316Smrg size_t new_n)
109*5971e316Smrg {
110*5971e316Smrg if (isl_blk_is_empty(block))
111*5971e316Smrg return isl_blk_alloc(ctx, new_n);
112*5971e316Smrg
113*5971e316Smrg return extend(ctx, block, new_n);
114*5971e316Smrg }
115*5971e316Smrg
isl_blk_free(struct isl_ctx * ctx,struct isl_blk block)116*5971e316Smrg void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block)
117*5971e316Smrg {
118*5971e316Smrg if (isl_blk_is_empty(block) || isl_blk_is_error(block))
119*5971e316Smrg return;
120*5971e316Smrg
121*5971e316Smrg if (ctx->n_cached < ISL_BLK_CACHE_SIZE)
122*5971e316Smrg ctx->cache[ctx->n_cached++] = block;
123*5971e316Smrg else
124*5971e316Smrg isl_blk_free_force(ctx, block);
125*5971e316Smrg }
126*5971e316Smrg
isl_blk_clear_cache(struct isl_ctx * ctx)127*5971e316Smrg void isl_blk_clear_cache(struct isl_ctx *ctx)
128*5971e316Smrg {
129*5971e316Smrg int i;
130*5971e316Smrg
131*5971e316Smrg for (i = 0; i < ctx->n_cached; ++i)
132*5971e316Smrg isl_blk_free_force(ctx, ctx->cache[i]);
133*5971e316Smrg ctx->n_cached = 0;
134*5971e316Smrg }
135