1 /* Copyright (C) 2014 InfiniDB, Inc.
2 
3    This program is free software; you can redistribute it and/or
4    modify it under the terms of the GNU General Public License
5    as published by the Free Software Foundation; version 2 of
6    the License.
7 
8    This program is distributed in the hope that it will be useful,
9    but WITHOUT ANY WARRANTY; without even the implied warranty of
10    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11    GNU General Public License for more details.
12 
13    You should have received a copy of the GNU General Public License
14    along with this program; if not, write to the Free Software
15    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
16    MA 02110-1301, USA. */
17 
18 /******************************************************************************************
19  * $Id: resourcemanager.h 4852 2009-02-09 14:21:34Z rdempsey $
20  *
21  ******************************************************************************************/
22 /**
23  * @file
24  */
25 #ifndef JOBLIST_RESOURCEDISTRIBUTER_H
26 #define JOBLIST_RESOURCEMANAGER_H
27 
28 #include <unistd.h>
29 #include <list>
30 #include <limits>
31 #include <boost/thread/condition.hpp>
32 
33 #include "logger.h"
34 
35 #undef min
36 #undef max
37 
38 namespace joblist
39 {
40 
41 /** @brief ResourceDistributor
42  *	Manages a resource.  Distributes up to fTotalResource on request.
43  * 	Expects the requester to return the resource when finished.
44  *	Blocks a requester when less than fResourceBlock of the resource is available.
45  *
46  *	Keeps a map of session id and ResourceBlock values so that the fResourceBlock can
47  *	be overriden for a session.
48  *
49  *	The aging logic is needed because exemgr gets a close message after every query, not
50  *	for a session, so it does not know when a session is ended.  Therefore LockedSessionMap
51  *	must keep all its sessions.  To prevent the map from becoming too large, after it reaches
52  *  	fMaxSessions, it removes the oldest used session.  fMaxSessions is defined in
53  *	resourcedistributor.cpp.  UpdateAging keeps the last accessed session at the end of the
54  *    aging list.  The oldest is at the front.
55  *
56  */
57 
58 extern const unsigned maxSessionsDefault;
59 
60 class LockedSessionMap
61 {
62 public:
fResourceBlock(resource)63     LockedSessionMap(uint64_t resource, unsigned maxSessions = maxSessionsDefault): fResourceBlock(resource), fMaxSessions(maxSessions) {}
64     typedef std::map <uint32_t, uint64_t> SessionMap;
65     typedef std::list <uint32_t> SessionList;
66     bool addSession(uint32_t sessionID, uint64_t resource, uint64_t limit = std::numeric_limits<uint64_t>::max());
67     void removeSession(uint32_t sessionID);
68     uint64_t  getSessionResource(uint32_t sessionID);
69     friend std::ostream& operator<<(std::ostream& os, const LockedSessionMap& lsm);
70 
71 private:
72     void updateAging(uint32_t sessionID);
73     boost::mutex 		fMapLock;
74     SessionMap 		fSessionMap;
75     uint64_t 		fResourceBlock;
76     boost::mutex 		fSessionLock;
77     SessionList	 	fSessionAgingList;
78     const unsigned  	fMaxSessions;
79 
80 
81 };
82 
83 
84 class ResourceDistributor
85 {
86 public:
87 
ResourceDistributor(const std::string & job,const std::string & identity,uint64_t totalResource,uint64_t resourceBlock,bool trace)88     ResourceDistributor(const std::string& job, const std::string& identity, uint64_t totalResource, uint64_t resourceBlock, bool trace) :
89         fJob(job), fIdentity(identity), fTotalResource(totalResource), fSessionMap(resourceBlock), fTraceOn(trace)
90     {}
91 
~ResourceDistributor()92     virtual ~ResourceDistributor() {}
93 
94     typedef std::map <uint32_t, uint64_t> SessionMap;
95 
96     uint64_t requestResource(uint32_t sessionID);
97     uint64_t requestResource(uint32_t sessionID, uint64_t resource);
98     void returnResource(uint64_t resource);
99 
100 
getSessionResource(uint32_t sessionID)101     uint64_t  getSessionResource(uint32_t sessionID)
102     {
103         return fSessionMap.getSessionResource(sessionID);
104     }
105 
getTotalResource()106     uint64_t  getTotalResource() const
107     {
108         return fTotalResource;
109     }
110 
111 
setTrace(bool trace)112     void setTrace(bool trace)
113     {
114         fTraceOn = trace;
115     }
116 
addSession(uint32_t sessionID,uint64_t resource)117     bool addSession(uint32_t sessionID, uint64_t resource)
118     {
119         return fSessionMap.addSession(sessionID, resource, fTotalResource);
120     }
removeSession(uint32_t sessionID)121     void removeSession(uint32_t sessionID)
122     {
123         fSessionMap.removeSession(sessionID);
124     }
125 
126 private:
127 
128     void logMessage(logging::LOG_TYPE logLevel, logging::Message::MessageID mid, uint64_t value = 0, uint32_t sessionId = 0);
129 
130     std::string 	fJob;
131     std::string	fIdentity;
132     uint64_t   	fTotalResource;
133     uint64_t   	fResourceBlock;
134     boost::mutex 	fResourceLock;
135     boost::condition fResourceAvailable;
136 
137     LockedSessionMap fSessionMap;
138     uint32_t 	fTraceOn;
139 
140 };
141 
142 }
143 
144 #endif
145