xref: /f-stack/app/micro_thread/mt_mbuf_pool.h (revision a9643ea8)
1 
2 /**
3  * Tencent is pleased to support the open source community by making MSEC available.
4  *
5  * Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
6  *
7  * Licensed under the GNU General Public License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License. You may
9  * obtain a copy of the License at
10  *
11  *     https://opensource.org/licenses/GPL-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software distributed under the
14  * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15  * either express or implied. See the License for the specific language governing permissions
16  * and limitations under the License.
17  */
18 
19 
20 /**
21  *  @file mt_mbuf_pool.h
22  *  @info ΢�߳�ͬ����Ϣbuf��
23  **/
24 
25 #ifndef __MT_MBUF_POOL_H__
26 #define __MT_MBUF_POOL_H__
27 
28 #include <netinet/in.h>
29 #include <queue>
30 #include "hash_list.h"
31 
32 namespace NS_MICRO_THREAD {
33 
34 using std::queue;
35 
36 enum BUFF_TYPE
37 {
38     BUFF_UNDEF          =  0,           ///< δ��������
39     BUFF_RECV           =  1,           ///< ����buff
40     BUFF_SEND           =  2,           ///< ����buff
41 };
42 
43 /**
44  * @brief ��ϢͶ�ݵ�buffer��
45  */
46 typedef TAILQ_ENTRY(MtMsgBuf) MsgBufLink;
47 typedef TAILQ_HEAD(__MtbuffTailq, MtMsgBuf) MsgBufQueue;
48 class MtMsgBuf
49 {
50 private:
51     int   _max_len;         // ���Ŀռ䳤��
52     int   _msg_len;         // ʵ�ʵ���Ϣ����
53     int   _buf_type;        // buff�Ƿ��ͻ��ǽ���
54     int   _recv_len;        // �ѽ��յ���Ϣ����
55     int   _send_len;        // �ѷ��͵���Ϣ����
56     void* _msg_buff;        // buffer ʵ��ͷָ��
57 
58 public:
59 
60     MsgBufLink _entry;
61 
62     /**
63      * @brief ���캯��, ָ�����buff����
64      */
65     MtMsgBuf(int max_len) {
66         _max_len  = max_len;
67         _msg_len  = 0;
68         _buf_type = BUFF_UNDEF;
69         _recv_len = 0;
70         _send_len = 0;
71         _msg_buff = malloc(max_len);
72     };
73 
74     ~MtMsgBuf() {
75         if (_msg_buff) {
76             free(_msg_buff);
77             _msg_buff = NULL;
78         }
79     };
80 
81     /**
82      * @brief ��Ϣ���͵��������ȡ
83      */
84     void SetBuffType(BUFF_TYPE type) {
85         _buf_type = (int)type;
86     };
87     BUFF_TYPE GetBuffType() {
88         return (BUFF_TYPE)_buf_type;
89     };
90 
91     /**
92      * @brief ���ýӿ�, �ָ���ʼ״̬
93      */
94     void Reset() {
95         _msg_len  = 0;
96         _recv_len = 0;
97         _send_len = 0;
98         _buf_type = BUFF_UNDEF;
99     };
100 
101     /**
102      * @brief ��Ϣ���ȵ��������ȡ
103      */
104     void SetMsgLen(int msg_len) {
105         _msg_len = msg_len;
106     };
107     int GetMsgLen() {
108         return _msg_len;
109     };
110 
111     /**
112      * @brief �������bufferָ���ȡ
113      */
114     int GetMaxLen() {
115         return _max_len;
116     };
117     void* GetMsgBuff() {
118         return _msg_buff;
119     };
120 
121     /**
122      * @brief �м�״̬��ȡ�����
123      */
124     int GetHaveSndLen() {
125         return _send_len;
126     };
127     void SetHaveSndLen(int snd_len) {
128         _send_len = snd_len;
129     };
130 
131     /**
132      * @brief �м�״̬��ȡ�����
133      */
134     int GetHaveRcvLen() {
135         return _recv_len;
136     };
137     void SetHaveRcvLen(int rcv_len) {
138         _recv_len = rcv_len;
139     };
140 };
141 
142 /**
143  * @brief ָ����С��buffer, �������ӳ��ɿ��ж���
144  */
145 class MsgBufMap : public HashKey
146 {
147 public:
148 
149     /**
150      *  @brief ��Ϣbuff����Ĺ���
151      *  @param buff_size ��mapԪ���ϵ�����buff, �����buff�ռ��Сֵ
152      *  @param max_free �ö��й���Ԫ��, ����ֵ�free��Ŀ
153      */
154     MsgBufMap(int buff_size, int max_free) {
155         _max_buf_size = buff_size;
156         _max_free     = max_free;
157         this->SetDataPtr(this);
158         _queue_num    = 0;
159         TAILQ_INIT(&_msg_queue);
160     };
161 
162     /**
163      *  @brief ��Ϣbuff����Ĺ���, ������, ������key��Ϣ
164      *  @param buff_size ��mapԪ���ϵ�����buff, �����buff�ռ��Сֵ
165      */
166     explicit MsgBufMap(int buff_size) {
167         _max_buf_size = buff_size;
168         TAILQ_INIT(&_msg_queue);
169     };
170 
171     /**
172      *  @brief ��Ϣbuff�������������
173      */
174     ~MsgBufMap() {
175         MtMsgBuf* ptr = NULL;
176         MtMsgBuf* tmp = NULL;
177         TAILQ_FOREACH_SAFE(ptr, &_msg_queue, _entry, tmp)
178         {
179             TAILQ_REMOVE(&_msg_queue, ptr, _entry);
180             delete ptr;
181             _queue_num--;
182         }
183 
184         TAILQ_INIT(&_msg_queue);
185     };
186 
187     /**
188      *  @brief ��ȡ��ϢbuffԪ��
189      *  @return msgbufָ��, ʧ��ΪNULL
190      */
191     MtMsgBuf* GetMsgBuf(){
192         MtMsgBuf* ptr = NULL;
193         if (!TAILQ_EMPTY(&_msg_queue)) {
194             ptr = TAILQ_FIRST(&_msg_queue);
195             TAILQ_REMOVE(&_msg_queue, ptr, _entry);
196             _queue_num--;
197         } else {
198             ptr = new MtMsgBuf(_max_buf_size);
199         }
200 
201         return ptr;
202     };
203 
204     /**
205      *  @brief �ͷ���ϢbuffԪ��
206      *  @param msgbufָ��
207      */
208     void FreeMsgBuf(MtMsgBuf* ptr){
209         if (_queue_num >= _max_free) {
210             delete ptr;
211         } else {
212             ptr->Reset();
213             TAILQ_INSERT_TAIL(&_msg_queue, ptr, _entry);
214             _queue_num++;
215         }
216     };
217 
218     /**
219      *  @brief �ڵ�Ԫ�ص�hash�㷨, ��ȡkey��hashֵ
220      *  @return �ڵ�Ԫ�ص�hashֵ
221      */
222     virtual uint32_t HashValue(){
223         return _max_buf_size;
224     };
225 
226     /**
227      *  @brief �ڵ�Ԫ�ص�cmp����, ͬһͰID��, ��key�Ƚ�
228      *  @return �ڵ�Ԫ�ص�hashֵ
229      */
230     virtual int HashCmp(HashKey* rhs){
231         return this->_max_buf_size - (int)rhs->HashValue();
232     };
233 
234 private:
235     int _max_free;              ///< �����б�������
236     int _max_buf_size;          ///< ����������buffsize
237     int _queue_num;             ///< ���ж��и���
238     MsgBufQueue _msg_queue;     ///< ʵ�ʵĿ��ж���
239 };
240 
241 
242 /**
243  * @brief ȫ�ֵ�buffer�ض���, ͳһ���������buffer
244  */
245 class MsgBuffPool
246 {
247 public:
248 
249     /**
250      * @brief ��Ϣbuff��ȫ�ֹ������ӿ�
251      * @return ȫ�־��ָ��
252      */
253     static MsgBuffPool* Instance (void);
254 
255     /**
256      * @brief ��Ϣ����ӿ�
257      */
258     static void Destroy(void);
259 
260     /**
261      * @brief ��Ϣbuff��ȫ�ֹ�������Ĭ�����Ŀ��и���
262      * @param max_free �����б�����Ŀ, ��Ҫ�ڷ���Ԫ��ǰ����
263      */
264     void SetMaxFreeNum(int max_free) {
265         _max_free = max_free;
266     };
267 
268     /**
269      *  @brief ��ȡ��ϢbuffԪ��
270      *  @return msgbufָ��, ʧ��ΪNULL
271      */
272     MtMsgBuf* GetMsgBuf(int max_size);
273 
274     /**
275      *  @brief �ͷ���ϢbuffԪ��
276      *  @param msgbufָ��
277      */
278     void FreeMsgBuf(MtMsgBuf* msg_buf);
279 
280     /**
281      * @brief ��Ϣbuff��ȫ������������
282      */
283     ~MsgBuffPool();
284 
285 private:
286 
287     /**
288      * @brief ��Ϣbuff�Ĺ��캯��
289      */
290     explicit MsgBuffPool(int max_free = 300);
291 
292     static MsgBuffPool * _instance;         ///<  ��������
293     int  _max_free;                         ///<  �����������Ŀ
294     HashList* _hash_map;                    ///<  ��size hashmap ������ж���
295 
296 };
297 
298 
299 
300 }
301 
302 #endif
303 
304 
305