1 /*
2  * Copyright (C) 2015-2017 Alibaba Group Holding Limited
3  */
4 
5 #ifndef K_MM_BLK_H
6 #define K_MM_BLK_H
7 
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
11 
12 /** @addtogroup aos_rhino mm
13  *  Pool memory management. Pool memory can be part of heap.
14  *  Pool is used to manage the little fixed-size block
15  *
16  *  @{
17  */
18 
19 #define MM_BLK_SLICE_BIT            10
20 #define MM_BLK_SLICE_SIZE           (1<<MM_BLK_SLICE_BIT)
21 #define MM_BLK_SLICE_NUM            (RHINO_CONFIG_MM_TLF_BLK_SIZE/MM_BLK_SLICE_SIZE)
22 
23 #define MM_BLK_SIZE2TYPE(size)      (32 - krhino_clz32((uint32_t)(size) - 1))
24 #define MM_BLK_TYPE2SIZE(type)      (1 << (type))
25 
26 /**
27  * memory pool info
28  */
29 typedef struct {
30     size_t        blk_size;
31     uint32_t      fail_cnt;     /* alloc fail */
32     uint32_t      freelist_cnt;
33     uint32_t      nofree_cnt;   /* alloc but not free yet */
34     uintptr_t     slice_cnt;
35     uintptr_t     slice_addr;
36     size_t        slice_offset;
37     uintptr_t     free_head;
38 } mblk_list_t;
39 
40 typedef struct {
41     kspinlock_t   blk_lock;
42     const name_t *pool_name;
43     uintptr_t     pool_start;
44     uintptr_t     pool_end;
45     uint32_t      slice_cnt;  /* slice have bean used */
46     char          slice_type[MM_BLK_SLICE_NUM];
47     mblk_list_t   blk_list[MM_BLK_SLICE_BIT];
48 } mblk_pool_t;
49 
50 typedef struct {
51     const name_t *pool_name;
52     size_t        pool_size;
53     size_t        used_size;
54     size_t        max_used_size;
55     size_t        max_blk_size;
56 } mblk_info_t;
57 
58 /**
59  * Init a pool.
60  *
61  * @param[in]  pool        pointer to the pool
62  * @param[in]  name        name of the pool
63  * @param[in]  pool_start  start addr of the pool
64  * @param[in]  pool_size   size of the pool
65  *
66  * @return  the operation status, RHINO_SUCCESS is OK, others is error
67  */
68 kstat_t krhino_mblk_pool_init(mblk_pool_t *pool, const name_t *name,
69                               void *pool_start, size_t pool_size);
70 
71 /**
72  * Memory block alloc from the pool.
73  *
74  * @param[in]  pool  pointer to a pool
75  * @param[in]  blk_size    need size, and alloced size
76  *
77  * @return  the operation status, RHINO_SUCCESS is OK, others is error
78  */
79 void *krhino_mblk_alloc(mblk_pool_t *pool, uint32_t size);
80 void *krhino_mblk_alloc_nolock(mblk_pool_t *pool, uint32_t size);
81 
82 /**
83  * Memory block free to the pool.
84  *
85  * @param[in]  pool  pointer to the pool
86  * @param[in]  blk   pointer to the blk
87  *
88  * @return  the operation status, RHINO_SUCCESS is OK, others is error
89  */
90 kstat_t krhino_mblk_free(mblk_pool_t *pool, void *blk);
91 kstat_t krhino_mblk_free_nolock(mblk_pool_t *pool, void *blk);
92 
93 /**
94  * This function will get information of the pool
95  * @param[in]  pool  pointer to the pool
96  * @param[out] info  info of pool
97  * @return  the operation status, RHINO_SUCCESS is OK, others is error
98  */
99 kstat_t krhino_mblk_info(mblk_pool_t *pool, mblk_info_t *info);
100 kstat_t krhino_mblk_info_nolock(mblk_pool_t *pool, mblk_info_t *info);
101 
102 /**
103  * Check if this a pool block.
104  *
105  * @param[in]  pool  pointer to the pool
106  * @param[in]  blk   pointer to the blk
107  *
108  * @return  yes return 1, no reture 0
109  */
110 #define krhino_mblk_check(pool, blk)                             \
111         ((pool) != NULL                                          \
112         && ((uintptr_t)(blk) >= ((mblk_pool_t*)(pool))->pool_start) \
113         && ((uintptr_t)(blk) <  ((mblk_pool_t*)(pool))->pool_end))
114 
115 /**
116  * get blk size, should followed by krhino_mblk_check
117  * @param[in]  pool  pointer to the pool
118  * @param[in]  blk   pointer to the blk
119  * @return  the len of blk
120  */
krhino_mblk_get_size(mblk_pool_t * pool,void * blk)121 RHINO_INLINE size_t krhino_mblk_get_size(mblk_pool_t *pool, void *blk)
122 {
123     uint32_t     slice_idx;
124     uint32_t     blk_type;
125     mblk_list_t *blk_list;
126 
127     slice_idx = ((uintptr_t)blk - pool->pool_start) >> MM_BLK_SLICE_BIT;
128     blk_type = pool->slice_type[slice_idx];
129     blk_list = &(pool->blk_list[blk_type]);
130 
131     return blk_list->blk_size;
132 }
133 
134 /** @} */
135 
136 #ifdef __cplusplus
137 }
138 #endif
139 
140 #endif /* K_MM_BLK_H */
141 
142