]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/l4util/lib/src/alloc.c
update
[l4.git] / l4 / pkg / l4util / lib / src / alloc.c
1 /*!
2  * \file   l4util/lib/src/alloc.c
3  * \brief  allocator using a bit-array
4  *
5  * \date   08/25/2004
6  * \author Jork Loeser <jork.loeser@inf.tu-dresden.de>
7  *
8  */
9 /*
10  * (c) 2004-2009 Author(s)
11  *     economic rights: Technische Universität Dresden (Germany)
12  * This file is part of TUD:OS and distributed under the terms of the
13  * GNU Lesser General Public License 2.1.
14  * Please see the COPYING-LGPL-2.1 file for details.
15  */
16
17 #include <stdlib.h>
18 #include <string.h>
19 #include <l4/util/alloc.h>
20
21
22 /*!\brief Initialize allocator array
23  */
24 L4_CV l4util_alloc_t *l4util_alloc_init(int count, int base){
25     l4util_alloc_t *alloc;
26     if((alloc=malloc(sizeof(l4util_alloc_t)))==0) return 0;
27     if((alloc->bits = malloc((count+(L4UTIL_ALLOC_BITS_SIZE-1))/8))==0){
28         free(alloc);
29         return 0;
30     }
31     memset(alloc->bits, 0, (count+(L4UTIL_ALLOC_BITS_SIZE-1))/8);
32     alloc->count = count;
33     alloc->base=base;
34     alloc->next_elem = base;
35     return alloc;
36 }
37
38 /*!\brief Return if an element is avail
39  *
40  * \retval 0    not avail
41  * \retval 1    avail
42  */
43 L4_CV int l4util_alloc_avail(l4util_alloc_t *alloc, int elem){
44     if(elem<alloc->base || elem >= alloc->base+alloc->count) return 0;
45     elem-=alloc->base;
46     return !l4util_test_bit(elem&(L4UTIL_ALLOC_BITS_SIZE-1),
47                             alloc->bits+(elem/L4UTIL_ALLOC_BITS_SIZE));
48 }
49
50 /*!\brief Set an element busy
51  *
52  * \param  elem         element
53  * \retval 0            OK
54  * \retval 1            was occupied already or out of bound
55  */
56 L4_CV int l4util_alloc_occupy(l4util_alloc_t *alloc, int elem){
57     if(elem<alloc->base || elem >= alloc->base+alloc->count) return 1;
58     elem-=alloc->base;
59     return l4util_test_and_set_bit(elem&(L4UTIL_ALLOC_BITS_SIZE-1),
60                                    alloc->bits+(elem/L4UTIL_ALLOC_BITS_SIZE))?1:0;
61 }
62
63 /*!\brief Allocate any element
64  *
65  * \retval >0           element
66  * \retval -1           Error, none free
67  */
68 L4_CV int l4util_alloc_alloc(l4util_alloc_t *alloc){
69     int elem=alloc->next_elem;
70
71     while(l4util_alloc_occupy(alloc, elem)){
72         if(++elem >= alloc->base + alloc->count) elem=0;
73         if(elem==alloc->next_elem) return -1;
74     }
75     alloc->next_elem = elem + 1;
76     if(alloc->next_elem == alloc->base + alloc->count){
77         alloc->next_elem = alloc->base;
78     }
79     return elem;
80 }
81
82 /*!\brief Free an element
83  * \param  elem         element to free
84  * \retval 0            OK
85  * \retval 1            was not occupied or out of bound
86  */
87 L4_CV int l4util_alloc_free(l4util_alloc_t *alloc, int elem){
88     if(elem < alloc->base || elem >= alloc->base+alloc->count){
89         return 1;
90     }
91     elem-=alloc->base;
92     return l4util_test_and_clear_bit(elem&(L4UTIL_ALLOC_BITS_SIZE-1),
93                                      alloc->bits+(elem/L4UTIL_ALLOC_BITS_SIZE))?0:1;
94 }