XRootD
XrdBuffManager Class Reference

#include <XrdBuffer.hh>

+ Collaboration diagram for XrdBuffManager:

Public Member Functions

 XrdBuffManager (int minrst=20 *60)
 
 ~XrdBuffManager ()
 
void Init ()
 
int MaxSize ()
 
XrdBufferObtain (int bsz)
 
int Recalc (int bsz)
 
void Release (XrdBuffer *bp)
 
void Reshape ()
 
void Set (int maxmem=-1, int minw=-1)
 
int Stats (char *buff, int blen, int do_sync=0)
 

Detailed Description

Definition at line 71 of file XrdBuffer.hh.

Constructor & Destructor Documentation

◆ XrdBuffManager()

XrdBuffManager::XrdBuffManager ( int  minrst = 20*60)

Definition at line 78 of file XrdBuffer.cc.

78  :
79  slots(XRD_BUCKETS),
80  shift(XRD_BUSHIFT),
81  pagsz(getpagesize()),
82  maxsz(1<<(XRD_BUSHIFT+XRD_BUCKETS-1)),
83  Reshaper(0, "buff reshaper")
84 {
85 
86 // Clear everything to zero
87 //
88  totbuf = 0;
89  totreq = 0;
90  totalo = 0;
91  totadj = 0;
92 #ifdef _SC_PHYS_PAGES
93  maxalo = static_cast<long long>(pagsz)/8
94  * static_cast<long long>(sysconf(_SC_PHYS_PAGES));
95 #else
96  maxalo = 0x7ffffff;
97 #endif
98  rsinprog = 0;
99  minrsw = minrst;
100  memset(static_cast<void *>(bucket), 0, sizeof(bucket));
101 }
#define XRD_BUSHIFT
Definition: XrdBuffer.hh:67
#define XRD_BUCKETS
Definition: XrdBuffer.hh:66

◆ ~XrdBuffManager()

XrdBuffManager::~XrdBuffManager ( )

Definition at line 107 of file XrdBuffer.cc.

108 {
109  XrdBuffer *bP;
110 
111  for (int i = 0; i < XRD_BUCKETS; i++)
112  {while((bP = bucket[i].bnext))
113  {bucket[i].bnext = bP->next;
114  delete bP;
115  }
116  bucket[i].numbuf = 0;
117  }
118 }

References XRD_BUCKETS.

Member Function Documentation

◆ Init()

void XrdBuffManager::Init ( )

Definition at line 124 of file XrdBuffer.cc.

125 {
126  pthread_t tid;
127  int rc;
128 
129 // Start the reshaper thread
130 //
131  if ((rc = XrdSysThread::Run(&tid, XrdReshaper, static_cast<void *>(this), 0,
132  "Buffer Manager reshaper")))
133  Log.Emsg("BuffManager", rc, "create reshaper thread");
134 }
void * XrdReshaper(void *pp)
Definition: XrdBuffer.cc:48
int Emsg(const char *esfx, int ecode, const char *text1, const char *text2=0)
Definition: XrdSysError.cc:95
static int Run(pthread_t *, void *(*proc)(void *), void *arg, int opts=0, const char *desc=0)
XrdSysError Log
Definition: XrdConfig.cc:112

References XrdSysError::Emsg(), XrdGlobal::Log, XrdSysThread::Run(), and XrdReshaper().

+ Here is the call graph for this function:

◆ MaxSize()

int XrdBuffManager::MaxSize ( )
inline

Definition at line 83 of file XrdBuffer.hh.

83 {return maxsz;}

Referenced by XrdXrootdProtocol::Configure().

+ Here is the caller graph for this function:

◆ Obtain()

XrdBuffer * XrdBuffManager::Obtain ( int  bsz)

Definition at line 140 of file XrdBuffer.cc.

141 {
142  XrdBuffer *bp;
143  char *memp;
144  int mk, pk, bindex;
145 
146 // Make sure the request is within our limits
147 //
148  if (sz <= 0) return 0;
149  if (sz > maxsz) return xlBuff.Obtain(sz);
150 
151 // Calculate bucket index
152 //
153  mk = sz >> shift;
154  bindex = XrdOucUtils::Log2(mk);
155  mk = minBuffSz << bindex;
156  if (mk < sz) {bindex++; mk = mk << 1;}
157  if (bindex >= slots) return 0; // Should never happen!
158 
159 // Obtain a lock on the bucket array and try to give away an existing buffer
160 //
161  Reshaper.Lock();
162  totreq++;
163  bucket[bindex].numreq++;
164  if ((bp = bucket[bindex].bnext))
165  {bucket[bindex].bnext = bp->next; bucket[bindex].numbuf--;}
166  Reshaper.UnLock();
167 
168 // Check if we really allocated a buffer
169 //
170  if (bp) return bp;
171 
172 // Allocate a chunk of aligned memory
173 //
174  pk = (mk < pagsz ? mk : pagsz);
175  if (posix_memalign((void **)&memp, pk, mk)) return 0;
176 
177 // Wrap the memory with a buffer object
178 //
179  if (!(bp = new XrdBuffer(memp, mk, bindex))) {free(memp); return 0;}
180 
181 // Update statistics
182 //
183  Reshaper.Lock();
184  totbuf++;
185  if ((totalo += mk) > maxalo && !rsinprog)
186  {rsinprog = 1; Reshaper.Signal();}
187  Reshaper.UnLock();
188  return bp;
189 }
XrdBuffer * Obtain(int bsz)
Definition: XrdBuffXL.cc:99
static int Log2(unsigned long long n)
Definition: XrdOucUtils.cc:818
XrdBuffXL xlBuff
Definition: XrdBuffer.cc:68

References XrdSysCondVar::Lock(), XrdOucUtils::Log2(), XrdBuffXL::Obtain(), XrdSysCondVar::Signal(), XrdSysCondVar::UnLock(), and XrdGlobal::xlBuff.

Referenced by XrdXrootdAioBuff::Alloc(), XrdXrootdAioPgrw::Alloc(), XrdHttpProtocol::Match(), XrdXrootdProtocol::Process(), and XrdXrootdProtocol::Swap().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Recalc()

int XrdBuffManager::Recalc ( int  bsz)

Definition at line 195 of file XrdBuffer.cc.

196 {
197  int mk, bindex;
198 
199 // Make sure the request is within our limits
200 //
201  if (sz <= 0) return 0;
202  if (sz > maxsz) return xlBuff.Recalc(sz);
203 
204 // Calculate bucket index
205 //
206  mk = sz >> shift;
207  bindex = XrdOucUtils::Log2(mk);
208  mk = minBuffSz << bindex;
209  if (mk < sz) {bindex++; mk = mk << 1;}
210  if (bindex >= slots) return 0; // Should never happen!
211 
212 // All done, return the actual size we would have allocated
213 //
214  return mk;
215 }
int Recalc(int bsz)
Definition: XrdBuffXL.cc:155

References XrdOucUtils::Log2(), XrdBuffXL::Recalc(), and XrdGlobal::xlBuff.

+ Here is the call graph for this function:

◆ Release()

void XrdBuffManager::Release ( XrdBuffer bp)

Definition at line 221 of file XrdBuffer.cc.

222 {
223  int bindex = bp->bindex;
224 
225 // Check if we should release this via the big buffer object
226 //
227  if (bindex >= slots) {xlBuff.Release(bp); return;}
228 
229 // Obtain a lock on the bucket array and reclaim the buffer
230 //
231  Reshaper.Lock();
232  bp->next = bucket[bp->bindex].bnext;
233  bucket[bp->bindex].bnext = bp;
234  bucket[bindex].numbuf++;
235  Reshaper.UnLock();
236 }
void Release(XrdBuffer *bp)
Definition: XrdBuffXL.cc:182

References XrdSysCondVar::Lock(), XrdBuffXL::Release(), XrdSysCondVar::UnLock(), and XrdGlobal::xlBuff.

Referenced by XrdXrootdAioPgrw::~XrdXrootdAioPgrw(), XrdXrootdProtocol::Process(), XrdXrootdProtocol::Reclaim(), and XrdXrootdAioBuff::Recycle().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Reshape()

void XrdBuffManager::Reshape ( )

Definition at line 242 of file XrdBuffer.cc.

243 {
244 int i, bufprof[XRD_BUCKETS], numfreed;
245 time_t delta, lastshape = time(0);
246 long long memslot, memhave, memtarget = (long long)(.80*(float)maxalo);
247 XrdSysTimer Timer;
248 float requests, buffers;
249 XrdBuffer *bp;
250 
251 // This is an endless loop to periodically reshape the buffer pool
252 //
253 while(1)
254  {Reshaper.Lock();
255  while(Reshaper.Wait(minrsw) && totalo <= maxalo)
256  {TRACE(MEM, "Reshaper has " <<(totalo>>10) <<"K; target " <<(memtarget>>10) <<"K");}
257  if ((delta = (time(0) - lastshape)) < minrsw)
258  {Reshaper.UnLock();
259  Timer.Wait((minrsw-delta)*1000);
260  Reshaper.Lock();
261  }
262 
263  // We have the lock so compute the request profile
264  //
265  if (totreq > slots)
266  {requests = (float)totreq;
267  buffers = (float)totbuf;
268  for (i = 0; i < slots; i++)
269  {bufprof[i] = (int)(buffers*(((float)bucket[i].numreq)/requests));
270  bucket[i].numreq = 0;
271  }
272  totreq = 0; memhave = totalo;
273  } else memhave = 0;
274  Reshaper.UnLock();
275 
276  // Reshape the buffer pool to agree with the request profile
277  //
278  memslot = maxsz; numfreed = 0;
279  for (i = slots-1; i >= 0 && memhave > memtarget; i--)
280  {Reshaper.Lock();
281  while(bucket[i].numbuf > bufprof[i])
282  if ((bp = bucket[i].bnext))
283  {bucket[i].bnext = bp->next;
284  delete bp;
285  bucket[i].numbuf--; numfreed++;
286  memhave -= memslot; totalo -= memslot;
287  totbuf--;
288  } else {bucket[i].numbuf = 0; break;}
289  Reshaper.UnLock();
290  memslot = memslot>>1;
291  }
292 
293  // All done
294  //
295  totadj += numfreed;
296  TRACE(MEM, "Pool reshaped; " <<numfreed <<" freed; have " <<(memhave>>10) <<"K; target " <<(memtarget>>10) <<"K");
297  lastshape = time(0);
298  rsinprog = 0; // No need to lock, we're the only ones now setting it
299 
300  xlBuff.Trim(); // Trim big buffers
301  }
302 }
#define TRACE(act, x)
Definition: XrdTrace.hh:63
void Trim()
Definition: XrdBuffXL.cc:221
static void Wait(int milliseconds)
Definition: XrdSysTimer.cc:227

References XrdSysCondVar::Lock(), TRACE, XrdBuffXL::Trim(), XrdSysCondVar::UnLock(), XrdSysCondVar::Wait(), XrdSysTimer::Wait(), XrdGlobal::xlBuff, and XRD_BUCKETS.

Referenced by XrdReshaper().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ Set()

void XrdBuffManager::Set ( int  maxmem = -1,
int  minw = -1 
)

Definition at line 308 of file XrdBuffer.cc.

309 {
310 
311 // Obtain a lock and set the values
312 //
313  Reshaper.Lock();
314  if (maxmem > 0) maxalo = (long long)maxmem;
315  if (minw > 0) minrsw = minw;
316  Reshaper.UnLock();
317 }

References XrdSysCondVar::Lock(), and XrdSysCondVar::UnLock().

+ Here is the call graph for this function:

◆ Stats()

int XrdBuffManager::Stats ( char *  buff,
int  blen,
int  do_sync = 0 
)

Definition at line 323 of file XrdBuffer.cc.

324 {
325  static char statfmt[] = "<stats id=\"buff\"><reqs>%d</reqs>"
326  "<mem>%lld</mem><buffs>%d</buffs><adj>%d</adj>%s</stats>";
327  char xlStats[1024];
328  int nlen;
329 
330 // If only size wanted, return it
331 //
332  if (!buff) return sizeof(statfmt) + 16*4 + xlBuff.Stats(0,0);
333 
334 // Return formatted stats
335 //
336  if (do_sync) Reshaper.Lock();
337  xlBuff.Stats(xlStats, sizeof(xlStats), do_sync);
338  nlen = snprintf(buff,blen,statfmt,totreq,totalo,totbuf,totadj,xlStats);
339  if (do_sync) Reshaper.UnLock();
340  return nlen;
341 }
int Stats(char *buff, int blen, int do_sync=0)
Definition: XrdBuffXL.cc:199

References XrdSysCondVar::Lock(), XrdBuffXL::Stats(), XrdSysCondVar::UnLock(), and XrdGlobal::xlBuff.

+ Here is the call graph for this function:

The documentation for this class was generated from the following files: