XRootD
Loading...
Searching...
No Matches
XrdOucBuffer.cc
Go to the documentation of this file.
1/******************************************************************************/
2/* */
3/* X r d O u c B u f f e r . c c */
4/* */
5/* (c) 2013 by the Board of Trustees of the Leland Stanford, Jr., University */
6/* All Rights Reserved */
7/* Produced by Andrew Hanushevsky for Stanford University under contract */
8/* DE-AC02-76-SFO0515 with the Department of Energy */
9/* */
10/* This file is part of the XRootD software suite. */
11/* */
12/* XRootD is free software: you can redistribute it and/or modify it under */
13/* the terms of the GNU Lesser General Public License as published by the */
14/* Free Software Foundation, either version 3 of the License, or (at your */
15/* option) any later version. */
16/* */
17/* XRootD is distributed in the hope that it will be useful, but WITHOUT */
18/* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or */
19/* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public */
20/* License for more details. */
21/* */
22/* You should have received a copy of the GNU Lesser General Public License */
23/* along with XRootD in a file called COPYING.LESSER (LGPL license) and file */
24/* COPYING (GPL license). If not, see <http://www.gnu.org/licenses/>. */
25/* */
26/* The copyright holder's institutional names and contributor's names may not */
27/* be used to endorse or promote products derived from this software without */
28/* specific prior written permission of the institution or contributor. */
29/******************************************************************************/
30
31#ifndef WIN32
32#include <unistd.h>
33#endif
34#include <sys/types.h>
35#include <cstdlib>
36
39
40/******************************************************************************/
41/* S t a t i c M e m b e r s */
42/******************************************************************************/
43
44int XrdOucBuffPool::alignit = sysconf(_SC_PAGESIZE);
45
46/******************************************************************************/
47/* X r d O u c B u f f P o o l M e t h o d s */
48/******************************************************************************/
49/******************************************************************************/
50/* C o n s t r u c t o r */
51/******************************************************************************/
52
53XrdOucBuffPool::XrdOucBuffPool(int minsz, int maxsz,
54 int minh, int maxh, int rate)
55{
56 int keep, pct, i, n = 0;
57
58// Adjust the minsz
59//
60 while(minsz > 1024*(1<<n)) n++;
61 if (n > 14) n = 14;
62 else if (n && minsz < 1024*(1<<n)) n--;
63 incBsz = 1024*(1<<n);
64 shfBsz = 10 + n;
65 rndBsz = incBsz - 1;
66 if (maxh < 0) maxh = 0;
67 if (minh < 0) minh = 0;
68 if (maxh < minh) maxh = minh;
69 if (rate < 0) rate = 0;
70
71// Round up the maxsz and make it a multiple of 4k
72//
73 if (!(slots = maxsz / incBsz)) slots = 1;
74 else if (maxsz % incBsz) slots++;
75 maxBsz = slots << shfBsz;
76
77// Allocate a slot vector for this
78//
79 bSlot = new BuffSlot[(unsigned int)slots];
80
81// Complete initializing the slot vector
82//
83 n = incBsz;
84 for (i = 0; i < slots; i++)
85 {bSlot[i].size = n; n += incBsz;
86 pct = (slots - i + 1)*100/slots;
87 if (pct >= 100) keep = maxh;
88 else {keep = ((maxh * pct) + 55)/100 - i*rate;
89 if (keep > maxh) keep = maxh;
90 else if (keep < minh) keep = minh;
91 }
92 bSlot[i].maxbuff = keep;
93 }
94}
95
96/******************************************************************************/
97/* A l l o c */
98/******************************************************************************/
99
101{
102 XrdOucBuffPool::BuffSlot *sP;
103 XrdOucBuffer *bP;
104 int snum;
105
106// Compute buffer slot
107//
108 snum = (bsz <= incBsz ? 0 : (bsz + rndBsz) >> shfBsz);
109 if (snum >= slots) return 0;
110 sP = &bSlot[snum];
111
112// Lock the data area
113//
114 sP->SlotMutex.Lock();
115
116// Either return a new buffer or an old one
117//
118 if ((bP = sP->buffFree))
119 {sP->buffFree = bP->buffNext;
120 bP->buffPool = this;
121 sP->numbuff--;
122 } else {
123 if ((bP = new XrdOucBuffer(this, snum)))
124 {int mema;
125 if (sP->size >= alignit) mema = alignit;
126 else if (sP->size > 2048) mema = 4096;
127 else if (sP->size > 1024) mema = 2048;
128 else mema = 1024;
129 if (posix_memalign((void **)&(bP->data), mema, sP->size))
130 {delete bP; bP = 0;}
131 }
132 }
133
134// Unlock the data area
135//
136 sP->SlotMutex.UnLock();
137
138// Return the buffer
139//
140 return bP;
141}
142
143/******************************************************************************/
144/* X r d O u c B u f f P o o l : : B u f f S l o t M e t h o d s */
145/******************************************************************************/
146/******************************************************************************/
147/* D e s t r u c t o r */
148/******************************************************************************/
149
150XrdOucBuffPool::BuffSlot::~BuffSlot()
151{
152 XrdOucBuffer *bP;
153
154 while((bP = buffFree)) {buffFree = buffFree->buffNext; delete bP;}
155}
156
157/******************************************************************************/
158/* R e c y c l e */
159/******************************************************************************/
160
161void XrdOucBuffPool::BuffSlot::Recycle(XrdOucBuffer *bP)
162{
163
164// Check if we have enough objects, if so, delete ourselves and return
165//
166 if (numbuff >= maxbuff) {delete bP; return;}
167 bP->dlen = 0;
168 bP->doff = 0;
169
170// Add the buffer to the recycle list
171//
172 SlotMutex.Lock();
173 bP->buffNext = buffFree;
174 buffFree = bP;
175 numbuff++;
176 SlotMutex.UnLock();
177 return;
178}
179
180/******************************************************************************/
181/* X r d O u c B u f f e r M e t h o d s */
182/******************************************************************************/
183/******************************************************************************/
184/* P u b l i c C o n s t r u c t o r */
185/******************************************************************************/
186
187XrdOucBuffer::XrdOucBuffer(char *buff, int blen)
188{
189 static XrdOucBuffPool nullPool(0, 0, 0, 0, 0);
190
191// Initialize the one time buffer
192//
193 data = buff;
194 dlen = blen;
195 doff = 0;
196 size = blen;
197 slot = 0;
198 buffPool = &nullPool;
199};
200
201/******************************************************************************/
202/* C l o n e */
203/******************************************************************************/
204
206{
207 XrdOucBuffer *newbP;
208 int newsz;
209
210// Compute the size of the new buffer
211//
212 newsz = (trim ? doff+dlen : size);
213
214// Allocate a new buffer
215//
216 if (!(newbP = buffPool->Alloc(newsz))) return 0;
217
218// Copy the data and the information
219//
220 newbP->dlen = dlen;
221 newbP->doff = doff;
222 memcpy(newbP->data, data, dlen+doff);
223 return newbP;
224}
225
226/******************************************************************************/
227/* H i g h j a c k */
228/******************************************************************************/
229
231{
232 XrdOucBuffer tempBuff, *newbP;
233
234// Adjust the size to revert highjacked buffer
235//
236 if (xsz <= 0) xsz = size;
237
238// Allocate a new buffer
239//
240 if (!(newbP = buffPool->Alloc(xsz))) return 0;
241
242// Swap information
243//
244 tempBuff = *this;
245 *this = *newbP;
246 *newbP = tempBuff;
247 tempBuff.data = 0;
248 return newbP;
249}
250
251/******************************************************************************/
252/* R e s i z e */
253/******************************************************************************/
254
255bool XrdOucBuffer::Resize(int newsz)
256{
257
258// If the new size differs from the old size, reallocate by simply highjacking
259// the buffer and releasing the newly acquired one.
260//
261 if (newsz != size)
262 {XrdOucBuffer *newbP;
263 if (!(newbP = Highjack(newsz))) return false;
264 newbP->Recycle();
265 }
266 return true;
267}
void trim(std::string &str)
Definition XrdHttpReq.cc:76
XrdOucBuffer * Alloc(int sz)
XrdOucBuffPool(int minsz=4096, int maxsz=65536, int minh=1, int maxh=16, int rate=1)
friend class XrdOucBuffer
bool Resize(int newsz)
XrdOucBuffer(char *buff, int blen)
friend class XrdOucBuffPool
XrdOucBuffer * Clone(bool trim=true)
void Recycle()
Recycle the buffer. The buffer may be reused in the future.
XrdOucBuffer * Highjack(int bPsz=0)