XRootD
XrdBwmPolicy1.cc
Go to the documentation of this file.
1 /******************************************************************************/
2 /* */
3 /* X r d B w m P o l i c y 1 . c c */
4 /* */
5 /* (c) 2008 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 #include <cstring>
32 
33 #include "XrdBwm/XrdBwmPolicy1.hh"
34 
35 /******************************************************************************/
36 /* C o n s t r u c t o r */
37 /******************************************************************************/
38 
39 XrdBwmPolicy1::XrdBwmPolicy1(int inslots, int outslots)
40 {
41 // Initialize values
42 //
43  theQ[In ].maxSlots = theQ[In ].curSlots = inslots;
44  theQ[Out].maxSlots = theQ[Out].curSlots = outslots;
45  theQ[Xeq].maxSlots = theQ[Xeq].curSlots = 0;
46  refID = 1;
47 }
48 
49 /******************************************************************************/
50 /* D i s p a t c h */
51 /******************************************************************************/
52 
53 int XrdBwmPolicy1::Dispatch(char *RespBuff, int RespSize)
54 {
55  refReq *rP;
56  int rID;
57 
58 // Obtain mutex and check if we have any queued requests
59 //
60  do {pMutex.Lock();
61  if ((rP = theQ[In].Next()) || (rP = theQ[Out].Next()))
62  {theQ[Xeq].Add(rP);
63  rID = rP->refID; *RespBuff = '\0';
64  pMutex.UnLock();
65  return rID;
66  }
67  pMutex.UnLock();
68  pSem.Wait();
69  } while(1);
70 
71 // Should never get here
72 //
73  strcpy(RespBuff, "Fatal logic error!");
74  return 0;
75 }
76 
77 /******************************************************************************/
78 /* D o n e */
79 /******************************************************************************/
80 
81 int XrdBwmPolicy1::Done(int rHandle)
82 {
83  refReq *rP;
84  int rc;
85 
86 // Make sure we have a positive value here
87 //
88  if (rHandle < 0) rHandle = -rHandle;
89 
90 // Remove the element from whichever queue it is in
91 //
92  pMutex.Lock();
93  if ((rP = theQ[Xeq].Yank(rHandle)))
94  {if (theQ[rP->Way].curSlots++ == 0) pSem.Post();
95  rc = 1;
96  } else {
97  if ((rP=theQ[In].Yank(rHandle)) || (rP=theQ[Out].Yank(rHandle))) rc = -1;
98  else rc = 0;
99  }
100  pMutex.UnLock();
101 
102 // delete the element and return
103 //
104  if (rP) delete rP;
105  return rc;
106 }
107 
108 /******************************************************************************/
109 /* S c h e d u l e */
110 /******************************************************************************/
111 
112 int XrdBwmPolicy1::Schedule(char *RespBuff, int RespSize, SchedParms &Parms)
113 {
114  static const char *theWay[] = {"Incoming", "Outgoing"};
115  refReq *rP;
116  int myID;
117 
118 // Get the global lock and generate a reference ID
119 //
120  *RespBuff = '\0';
121  pMutex.Lock();
122  myID = ++refID;
123  rP = new refReq(myID, Parms.Direction);
124 
125 // Check if we can immediately schedule this requestor must defer it
126 //
127  if (theQ[rP->Way].curSlots > 0)
128  {theQ[rP->Way].curSlots--;
129  theQ[Xeq].Add(rP);
130  }
131  else if (theQ[rP->Way].maxSlots)
132  {theQ[rP->Way].Add(rP); myID = -myID;}
133  else {strcpy(RespBuff, theWay[rP->Way]);
134  strcat(RespBuff, " requests are not allowed.");
135  delete rP;
136  myID = 0;
137  }
138 
139 // All done
140 //
141  pMutex.UnLock();
142  return myID;
143 }
144 
145 /******************************************************************************/
146 /* S t a t u s */
147 /******************************************************************************/
148 
149 void XrdBwmPolicy1::Status(int &numqIn, int &numqOut, int &numXeq)
150 {
151 
152 // Get the global lock and return the values
153 //
154  pMutex.Lock();
155  numqIn = theQ[In ].Num;
156  numqOut = theQ[Out].Num;
157  numXeq = theQ[Xeq].Num;
158  pMutex.UnLock();
159 }
XrdBwmPolicy1(int inslots, int outslots)
int Dispatch(char *RespBuff, int RespSize)
void Status(int &numqIn, int &numqOut, int &numXeq)
int Schedule(char *RespBuff, int RespSize, SchedParms &Parms)
int Done(int rHandle)