1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-12-07     Shell        First version
9  */
10 
11 #include "rid_bitmap.h"
12 #include <bitmap.h>
13 #include <rtdef.h>
14 
rid_bitmap_init(rid_bitmap_t mgr,int min_id,int total_id_count,rt_bitmap_t * set,struct rt_mutex * id_lock)15 void rid_bitmap_init(rid_bitmap_t mgr, int min_id, int total_id_count,
16                      rt_bitmap_t *set, struct rt_mutex *id_lock)
17 {
18     mgr->min_id = min_id;
19     mgr->total_id_count = total_id_count;
20     mgr->bitset = set;
21     mgr->id_lock = id_lock;
22 
23     return;
24 }
25 
rid_bitmap_get(rid_bitmap_t mgr)26 long rid_bitmap_get(rid_bitmap_t mgr)
27 {
28     long id;
29     long overflow;
30     if (mgr->id_lock)
31     {
32         rt_mutex_take(mgr->id_lock, RT_WAITING_FOREVER);
33     }
34 
35     overflow = mgr->total_id_count;
36     id = rt_bitmap_next_clear_bit(mgr->bitset, 0, overflow);
37     if (id == overflow)
38     {
39         id = -1;
40     }
41     else
42     {
43         rt_bitmap_set_bit(mgr->bitset, id);
44         id += mgr->min_id;
45     }
46 
47     if (mgr->id_lock)
48     {
49         rt_mutex_release(mgr->id_lock);
50     }
51     return id;
52 }
53 
rid_bitmap_get_named(rid_bitmap_t mgr,long no)54 long rid_bitmap_get_named(rid_bitmap_t mgr, long no)
55 {
56     long id_relative;
57     long overflow;
58     long min;
59 
60     if (mgr->id_lock)
61     {
62         rt_mutex_take(mgr->id_lock, RT_WAITING_FOREVER);
63     }
64 
65     min = mgr->min_id;
66     id_relative = no - min;
67     overflow = mgr->total_id_count;
68     if (id_relative >= min && id_relative < overflow)
69     {
70         if (rt_bitmap_test_bit(mgr->bitset, id_relative))
71         {
72             id_relative = -RT_EBUSY;
73         }
74         else
75         {
76             rt_bitmap_set_bit(mgr->bitset, id_relative);
77             id_relative += min;
78         }
79     }
80     else
81     {
82         id_relative = -1;
83     }
84 
85     if (mgr->id_lock)
86     {
87         rt_mutex_release(mgr->id_lock);
88     }
89     return id_relative;
90 }
91 
rid_bitmap_put(rid_bitmap_t mgr,long no)92 void rid_bitmap_put(rid_bitmap_t mgr, long no)
93 {
94     long id_relative;
95     long overflow;
96     long min;
97 
98     if (mgr->id_lock)
99     {
100         rt_mutex_take(mgr->id_lock, RT_WAITING_FOREVER);
101     }
102 
103     min = mgr->min_id;
104     id_relative = no - min;
105     overflow = mgr->total_id_count;
106     if (id_relative >= min && id_relative < overflow &&
107         rt_bitmap_test_bit(mgr->bitset, id_relative))
108     {
109         rt_bitmap_clear_bit(mgr->bitset, id_relative);
110     }
111 
112     if (mgr->id_lock)
113     {
114         rt_mutex_release(mgr->id_lock);
115     }
116 }
117