keep cache of blocks of isl_ints
[platform/upstream/isl.git] / isl_blk.c
1 #include "isl_blk.h"
2 #include "isl_ctx.h"
3
4 struct isl_blk isl_blk_empty()
5 {
6         struct isl_blk block;
7         block.size = 0;
8         block.data = NULL;
9         return block;
10 }
11
12 static int isl_blk_is_empty(struct isl_blk block)
13 {
14         return block.size == 0 && block.data == NULL;
15 }
16
17 static struct isl_blk isl_blk_error()
18 {
19         struct isl_blk block;
20         block.size = -1;
21         block.data = NULL;
22         return block;
23 }
24
25 int isl_blk_is_error(struct isl_blk block)
26 {
27         return block.size == -1 && block.data == NULL;
28 }
29
30 struct isl_blk isl_blk_alloc(struct isl_ctx *ctx, size_t n)
31 {
32         int i;
33         struct isl_blk block;
34
35         if (ctx->n_cached) {
36                 int best = 0;
37                 for (i = 1; ctx->cache[best].size != n && i < ctx->n_cached; ++i) {
38                         if (ctx->cache[best].size < n) {
39                                 if (ctx->cache[i].size > ctx->cache[best].size)
40                                         best = i;
41                         } else if (ctx->cache[i].size >= n &&
42                                    ctx->cache[i].size < ctx->cache[best].size)
43                                         best = i;
44                 }
45                 block = ctx->cache[best];
46                 if (--ctx->n_cached != best)
47                         ctx->cache[best] = ctx->cache[ctx->n_cached];
48         } else
49                 block = isl_blk_empty();
50
51         return isl_blk_extend(ctx, block, n);
52 }
53
54 struct isl_blk isl_blk_extend(struct isl_ctx *ctx, struct isl_blk block,
55                                 size_t new_n)
56 {
57         int i;
58         isl_int *p;
59
60         if (block.size >= new_n)
61                 return block;
62
63         p = block.data;
64         block.data = isl_realloc_array(ctx, block.data, isl_int, new_n);
65         if (!block.data) {
66                 free(p);
67                 return isl_blk_error();
68         }
69
70         for (i = block.size; i < new_n; ++i)
71                 isl_int_init(block.data[i]);
72         block.size = new_n;
73
74         return block;
75 }
76
77 static void isl_blk_free_force(struct isl_ctx *ctx, struct isl_blk block)
78 {
79         int i;
80
81         for (i = 0; i < block.size; ++i)
82                 isl_int_clear(block.data[i]);
83         free(block.data);
84 }
85
86 void isl_blk_free(struct isl_ctx *ctx, struct isl_blk block)
87 {
88         if (isl_blk_is_empty(block) || isl_blk_is_error(block))
89                 return;
90
91         if (ctx->n_cached < ISL_BLK_CACHE_SIZE)
92                 ctx->cache[ctx->n_cached++] = block;
93         else
94                 isl_blk_free_force(ctx, block);
95 }
96
97 void isl_blk_clear_cache(struct isl_ctx *ctx)
98 {
99         int i;
100
101         for (i = 0; i < ctx->n_cached; ++i)
102                 isl_blk_free_force(ctx, ctx->cache[i]);
103         ctx->n_cached = 0;
104 }