xref: /f-stack/app/micro_thread/mt_mbuf_pool.h (revision 35a81399)
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  **/
23 
24 #ifndef __MT_MBUF_POOL_H__
25 #define __MT_MBUF_POOL_H__
26 
27 #include <netinet/in.h>
28 #include <queue>
29 #include "hash_list.h"
30 
31 namespace NS_MICRO_THREAD {
32 
33 using std::queue;
34 
35 enum BUFF_TYPE
36 {
37     BUFF_UNDEF          =  0,
38     BUFF_RECV           =  1,
39     BUFF_SEND           =  2,
40 };
41 
42 typedef TAILQ_ENTRY(MtMsgBuf) MsgBufLink;
43 typedef TAILQ_HEAD(__MtbuffTailq, MtMsgBuf) MsgBufQueue;
44 class MtMsgBuf
45 {
46 private:
47     int   _max_len;
48     int   _msg_len;
49     int   _buf_type;
50     int   _recv_len;
51     int   _send_len;
52     void* _msg_buff;
53 
54 public:
55 
56     MsgBufLink _entry;
57 
MtMsgBuf(int max_len)58     MtMsgBuf(int max_len) {
59         _max_len  = max_len;
60         _msg_len  = 0;
61         _buf_type = BUFF_UNDEF;
62         _recv_len = 0;
63         _send_len = 0;
64         _msg_buff = malloc(max_len);
65     };
66 
~MtMsgBuf()67     ~MtMsgBuf() {
68         if (_msg_buff) {
69             free(_msg_buff);
70             _msg_buff = NULL;
71         }
72     };
73 
SetBuffType(BUFF_TYPE type)74     void SetBuffType(BUFF_TYPE type) {
75         _buf_type = (int)type;
76     };
GetBuffType()77     BUFF_TYPE GetBuffType() {
78         return (BUFF_TYPE)_buf_type;
79     };
80 
Reset()81     void Reset() {
82         _msg_len  = 0;
83         _recv_len = 0;
84         _send_len = 0;
85         _buf_type = BUFF_UNDEF;
86     };
87 
SetMsgLen(int msg_len)88     void SetMsgLen(int msg_len) {
89         _msg_len = msg_len;
90     };
GetMsgLen()91     int GetMsgLen() {
92         return _msg_len;
93     };
94 
GetMaxLen()95     int GetMaxLen() {
96         return _max_len;
97     };
GetMsgBuff()98     void* GetMsgBuff() {
99         return _msg_buff;
100     };
101 
GetHaveSndLen()102     int GetHaveSndLen() {
103         return _send_len;
104     };
SetHaveSndLen(int snd_len)105     void SetHaveSndLen(int snd_len) {
106         _send_len = snd_len;
107     };
108 
109 
GetHaveRcvLen()110     int GetHaveRcvLen() {
111         return _recv_len;
112     };
SetHaveRcvLen(int rcv_len)113     void SetHaveRcvLen(int rcv_len) {
114         _recv_len = rcv_len;
115     };
116 };
117 
118 class MsgBufMap : public HashKey
119 {
120 public:
121 
MsgBufMap(int buff_size,int max_free)122     MsgBufMap(int buff_size, int max_free) {
123         _max_buf_size = buff_size;
124         _max_free     = max_free;
125         this->SetDataPtr(this);
126         _queue_num    = 0;
127         TAILQ_INIT(&_msg_queue);
128     };
129 
MsgBufMap(int buff_size)130     explicit MsgBufMap(int buff_size) {
131         _max_buf_size = buff_size;
132         TAILQ_INIT(&_msg_queue);
133     };
134 
~MsgBufMap()135     ~MsgBufMap() {
136         MtMsgBuf* ptr = NULL;
137         MtMsgBuf* tmp = NULL;
138         TAILQ_FOREACH_SAFE(ptr, &_msg_queue, _entry, tmp)
139         {
140             TAILQ_REMOVE(&_msg_queue, ptr, _entry);
141             delete ptr;
142             _queue_num--;
143         }
144 
145         TAILQ_INIT(&_msg_queue);
146     };
147 
GetMsgBuf()148     MtMsgBuf* GetMsgBuf(){
149         MtMsgBuf* ptr = NULL;
150         if (!TAILQ_EMPTY(&_msg_queue)) {
151             ptr = TAILQ_FIRST(&_msg_queue);
152             TAILQ_REMOVE(&_msg_queue, ptr, _entry);
153             _queue_num--;
154         } else {
155             ptr = new MtMsgBuf(_max_buf_size);
156         }
157 
158         return ptr;
159     };
160 
FreeMsgBuf(MtMsgBuf * ptr)161     void FreeMsgBuf(MtMsgBuf* ptr){
162         if (_queue_num >= _max_free) {
163             delete ptr;
164         } else {
165             ptr->Reset();
166             TAILQ_INSERT_TAIL(&_msg_queue, ptr, _entry);
167             _queue_num++;
168         }
169     };
170 
HashValue()171     virtual uint32_t HashValue(){
172         return _max_buf_size;
173     };
174 
HashCmp(HashKey * rhs)175     virtual int HashCmp(HashKey* rhs){
176         return this->_max_buf_size - (int)rhs->HashValue();
177     };
178 
179 private:
180     int _max_free;
181     int _max_buf_size;
182     int _queue_num;
183     MsgBufQueue _msg_queue;
184 };
185 
186 class MsgBuffPool
187 {
188 public:
189 
190     static MsgBuffPool* Instance (void);
191 
192     static void Destroy(void);
193 
SetMaxFreeNum(int max_free)194     void SetMaxFreeNum(int max_free) {
195         _max_free = max_free;
196     };
197 
198     MtMsgBuf* GetMsgBuf(int max_size);
199 
200     void FreeMsgBuf(MtMsgBuf* msg_buf);
201 
202     ~MsgBuffPool();
203 
204 private:
205 
206     explicit MsgBuffPool(int max_free = 300);
207 
208     static MsgBuffPool * _instance;
209     int  _max_free;
210     HashList* _hash_map;
211 
212 };
213 
214 }
215 
216 #endif
217 
218 
219