root/uniquepid.cpp
/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- dmtcp_UniquePid_EventHook
- theUniqueHostId
- nullProcess
- theProcess
- parentProcess
- ThisProcess
- ParentProcess
- incrementGeneration
- toString
- resetOnFork
- isNull
- serialize
1 /****************************************************************************
2 * Copyright (C) 2006-2013 by Jason Ansel, Kapil Arya, and Gene Cooperman *
3 * jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu *
4 * *
5 * This file is part of DMTCP. *
6 * *
7 * DMTCP is free software: you can redistribute it and/or *
8 * modify it under the terms of the GNU Lesser General Public License as *
9 * published by the Free Software Foundation, either version 3 of the *
10 * License, or (at your option) any later version. *
11 * *
12 * DMTCP is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU Lesser General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU Lesser General Public *
18 * License along with DMTCP:dmtcp/src. If not, see *
19 * <http://www.gnu.org/licenses/>. *
20 ****************************************************************************/
21
22 #include <stdlib.h>
23 #include "uniquepid.h"
24 #include "constants.h"
25 #include "../jalib/jconvert.h"
26 #include "../jalib/jfilesystem.h"
27 #include "../jalib/jserialize.h"
28 #include "syscallwrappers.h"
29 #include "protectedfds.h"
30 #include "shareddata.h"
31
32 using namespace dmtcp;
33
34 void dmtcp_UniquePid_EventHook(DmtcpEvent_t event, DmtcpEventData_t *data)
35 {
36 switch (event) {
37 case DMTCP_EVENT_RESTART:
38 break;
39
40 default:
41 break;
42 }
43 }
44
45 inline static long theUniqueHostId()
46 {
47 #ifdef USE_GETHOSTID
48 return ::gethostid()
49 #else
50 //gethostid() calls socket() on some systems, which we don't want
51 char buf[512];
52 JASSERT(::gethostname(buf, sizeof(buf))==0)(JASSERT_ERRNO);
53 //so return a bad hash of our hostname
54 long h = 0;
55 for(char* i=buf; *i!='\0'; ++i)
56 h = (*i) + (331*h);
57 //make it positive for good measure
58 return h>0 ? h : -1*h;
59 #endif
60 }
61
62 static UniquePid& nullProcess()
63 {
64 static char buf[sizeof(UniquePid)];
65 static UniquePid* t=NULL;
66 if(t==NULL) t = new (buf) UniquePid(0,0,0);
67 return *t;
68 }
69 static UniquePid& theProcess()
70 {
71 static char buf[sizeof(UniquePid)];
72 static UniquePid* t=NULL;
73 if(t==NULL) t = new (buf) UniquePid(0,0,0);
74 return *t;
75 }
76 static UniquePid& parentProcess()
77 {
78 static char buf[sizeof(UniquePid)];
79 static UniquePid* t=NULL;
80 if(t==NULL) t = new (buf) UniquePid(0,0,0);
81 return *t;
82 }
83
84 // _computation_generation field of return value may later have to be modified.
85 // So, it can't return a const UniquePid
86 UniquePid& UniquePid::ThisProcess(bool disableJTrace /*=false*/)
87 {
88 if ( theProcess() == nullProcess() )
89 {
90 theProcess() = UniquePid ( theUniqueHostId() ,
91 ::getpid(),
92 ::time(NULL) );
93 if (disableJTrace == false) {
94 JTRACE ( "recalculated process UniquePid..." ) ( theProcess() );
95 }
96 }
97
98 return theProcess();
99 }
100
101 UniquePid& UniquePid::ParentProcess()
102 {
103 return parentProcess();
104 }
105
106 /*!
107 \fn UniquePid::UniquePid()
108 */
109 UniquePid::UniquePid()
110 {
111 _pid = 0;
112 _hostid = 0;
113 memset(&_time, 0, sizeof(_time));
114 }
115
116 // This is called only by the DMTCP coordinator.
117 void UniquePid::incrementGeneration()
118 {
119 _computation_generation++;
120 }
121
122 /*!
123 \fn UniquePid::operator<() const
124 */
125 bool UniquePid::operator< ( const UniquePid& that ) const
126 {
127 #define TRY_LEQ(param) if(this->param != that.param) return this->param < that.param;
128 TRY_LEQ ( _hostid );
129 TRY_LEQ ( _pid );
130 TRY_LEQ ( _time );
131 return false;
132 }
133
134 bool UniquePid::operator== ( const UniquePid& that ) const
135 {
136 return _hostid==that.hostid()
137 && _pid==that.pid()
138 && _time==that.time();
139 }
140
141 ostream& dmtcp::operator<< ( dmtcp::ostream& o,const UniquePid& id )
142 {
143 o << std::hex << id.hostid() << '-' << std::dec << id.pid() << '-' << std::hex << id.time() << std::dec;
144 return o;
145 }
146
147 ostream& dmtcp::operator<< ( dmtcp::ostream& o,const DmtcpUniqueProcessId& id )
148 {
149 o << std::hex << id._hostid<< '-' << std::dec << id._pid << '-' << std::hex << id._time << std::dec;
150 return o;
151 }
152
153 bool dmtcp::operator==(const DmtcpUniqueProcessId& a,
154 const DmtcpUniqueProcessId& b)
155 {
156 return a._hostid == b._hostid &&
157 a._pid == b._pid &&
158 a._time == b._time &&
159 a._computation_generation == b._computation_generation;
160 }
161
162 bool dmtcp::operator!=(const DmtcpUniqueProcessId& a,
163 const DmtcpUniqueProcessId& b)
164 {
165 return !(a == b);
166 }
167
168 string UniquePid::toString() const{
169 ostringstream o;
170 o << *this;
171 return o.str();
172 }
173
174 void UniquePid::resetOnFork ( const UniquePid& newId )
175 {
176 // parentProcess() is for inspection tools
177 parentProcess() = ThisProcess();
178 JTRACE ( "Explicitly setting process UniquePid" ) ( newId );
179 theProcess() = newId;
180 }
181
182 bool UniquePid::isNull() const
183 {
184 return (*this == nullProcess());
185 }
186
187 void UniquePid::serialize ( jalib::JBinarySerializer& o )
188 {
189 // NOTE: Do not put JTRACE/JNOTE/JASSERT in here
190 UniquePid theCurrentProcess, theParentProcess;
191
192 if ( o.isWriter() )
193 {
194 theCurrentProcess = ThisProcess();
195 theParentProcess = ParentProcess();
196 }
197
198 o & theCurrentProcess & theParentProcess;
199
200 if ( o.isReader() )
201 {
202 theProcess() = theCurrentProcess;
203 parentProcess() = theParentProcess;
204 }
205 }