Package PyFoam :: Package Execution :: Module FoamThread
[hide private]
[frames] | no frames]

Source Code for Module PyFoam.Execution.FoamThread

  1  #  ICE Revision: $Id: FoamThread.py 7832 2007-08-28 13:07:26Z bgschaid $  
  2  """Thread wrappers for OpenFOAM""" 
  3  from threading import Thread,Lock,Timer 
  4  from popen2 import Popen4 
  5  from time import time,sleep 
  6  from resource import getrusage,getpagesize,RUSAGE_CHILDREN 
  7  from os import uname,kill 
  8  import signal 
  9   
 10  from PyFoam.Basics.LineReader import LineReader 
 11  from PyFoam.Infrastructure.Logging import foamLogger 
 12   
13 -def getLinuxMem(thrd):
14 """Reads the Memory usage of a thread on a linux-System 15 16 @param thrd: the thread object in question""" 17 18 # print "Timer called" 19 20 if not thrd.isLinux or thrd.threadPid<0: 21 return 22 23 mem=0 24 25 try: 26 t=open('/proc/%d/status' % thrd.threadPid) 27 v=t.read() 28 t.close() 29 # f=open('/tmp/test%dstatus' % thrd.threadPid,'w') 30 # f.write(v) 31 # f.close() 32 33 i=v.index('VmRSS') 34 tmp=v[i:].split() 35 if len(tmp)>=3: 36 mem=long(tmp[1]) 37 if tmp[2].lower()=='kb': 38 mem*=1024 39 elif tmp[2].lower()=='mb': 40 mem*=1024*1024 41 else: 42 mem=-1 43 except Exception,e: 44 print "Getting LinuxMem:",e 45 mem=-1 46 47 if mem>thrd.linuxMaxMem: 48 # print "Setting Memory to: ",mem 49 thrd.linuxMaxMem=mem 50 51 # print "Restarting Timer" 52 53 thrd.timer=Timer(thrd.timerTime,getLinuxMem,args=[thrd]) 54 thrd.timer.start()
55
56 -class FoamThread(Thread):
57 """Thread running an OpenFOAM command 58 59 The output of the command can be accessed in a thread-safe manner, 60 line by line 61 62 Designed to be used by the BasicRunner-class""" 63
64 - def __init__(self,cmdline):
65 """cmdline - Command line of the OpenFOAM command""" 66 Thread.__init__(self) 67 self.cmdline=cmdline 68 self.output=None 69 self.reader=LineReader() 70 71 self.isLinux=False 72 self.isDarwin=False 73 self.threadPid=-1 74 self.who=RUSAGE_CHILDREN 75 76 if uname()[0]=="Linux": 77 self.isLinux=True 78 self.linuxMaxMem=0 79 elif uname()[0]=="Darwin": 80 self.isDarwin=True 81 82 self.resStart=None 83 self.resEnd=None 84 85 self.timeStart=None 86 self.timeEnd=None 87 88 self.timerTime=5. 89 90 self.stateLock=Lock() 91 self.setState(False) 92 93 self.status=None 94 95 self.lineLock=Lock() 96 self.line="" 97 98 self.stateLock.acquire()
99
100 - def run(self):
101 """start the command""" 102 # print "Starting ",self.cmdline 103 self.resStart=getrusage(self.who) 104 self.timeStart=time() 105 106 run=Popen4(self.cmdline) 107 self.output=run.fromchild 108 self.threadPid=run.pid 109 foamLogger().info("Started with PID %d" % self.threadPid) 110 if self.isLinux: 111 # print "Starting Timer" 112 self.timer=Timer(0.1*self.timerTime,getLinuxMem,args=[self]) 113 self.timer.start() 114 115 self.hasSomethingToSay=True 116 self.stateLock.release() 117 118 try: 119 # print "Waiting",time() 120 self.status=run.wait() 121 # Python 2.3 on Mac OS X never seems to reach this point 122 # print "After wait",time() 123 # print "Status:",self.status 124 125 # to give a chance to read the remaining output 126 if self.hasSomethingToSay: 127 sleep(2.) 128 129 while self.reader.read(self.output): 130 print "Unused output:",self.reader.line 131 except OSError,e: 132 print "Exeption caught:",e 133 134 self.stopTimer() 135 136 self.threadPid=-1 137 138 self.resEnd=getrusage(self.who) 139 self.timeEnd=time()
140 # print "End:",self.timeEnd 141 # print "Returned",self.status 142
143 - def stopTimer(self):
144 if self.isLinux: 145 self.timer.cancel()
146
147 - def read(self):
148 """read another line from the output""" 149 self.setState(self.reader.read(self.output)) 150 self.lineLock.acquire() 151 self.line=self.reader.line 152 self.lineLock.release()
153
154 - def getLine(self):
155 """gets the last line from the output""" 156 self.lineLock.acquire() 157 val=self.line 158 self.lineLock.release() 159 160 return val
161
162 - def interrupt(self):
163 """A keyboard-interrupt is reported""" 164 self.reader.wasInterupted=True 165 self.setState(False)
166
167 - def setState(self,state):
168 """sets the state of the thread (is there any more output)""" 169 self.stateLock.acquire() 170 self.hasSomethingToSay=state 171 if not self.hasSomethingToSay and self.timeStart and self.reader.wasInterupted: 172 if self.threadPid>0: 173 msg="Killing PID %d" % self.threadPid 174 print msg 175 foamLogger().warning(msg) 176 kill(self.threadPid,signal.SIGKILL) 177 # print "Set: ",state 178 self.stateLock.release()
179
180 - def check(self):
181 """@return: False if there is no more output of the command""" 182 self.stateLock.acquire() 183 state=self.hasSomethingToSay 184 # print "Get: ",state 185 self.stateLock.release() 186 187 return state
188
189 - def cpuTime(self):
190 """@return: number of seconds CPU-Time used""" 191 return self.cpuUserTime()+self.cpuSystemTime()
192
193 - def cpuUserTime(self):
194 """@return: number of seconds CPU-Time used in user mode""" 195 if self.resEnd==None: # and self.isDarwin: 196 # Mac OS X needs this (Ubuntu too?) 197 self.resEnd=getrusage(self.who) 198 if self.resStart==None or self.resEnd==None: 199 return 0 200 else: 201 return self.resEnd.ru_utime-self.resStart.ru_utime
202
203 - def cpuSystemTime(self):
204 """@return: number of seconds CPU-Time used in system mode""" 205 if self.resEnd==None: # and self.isDarwin: 206 # Mac OS X needs this (Ubuntu too?) 207 self.resEnd=getrusage(self.who) 208 if self.resStart==None or self.resEnd==None: 209 return 0 210 else: 211 return self.resEnd.ru_stime-self.resStart.ru_stime
212
213 - def usedMemory(self):
214 """@return: maximum resident set size in MegaByte""" 215 scale=1024.*1024. 216 if self.isLinux: 217 return self.linuxMaxMem/scale 218 219 if self.resStart==None or self.resEnd==None: 220 return 0. 221 else: 222 return getpagesize()*(self.resEnd.ru_maxrss-self.resStart.ru_maxrss)/scale
223
224 - def wallTime(self):
225 """@return: the wall-clock-time needed by the process""" 226 if self.timeEnd==None: # and self.isDarwin: 227 # Mac OS X needs this (Ubuntu too?) 228 self.timeEnd=time() 229 230 self.timeEnd=time() 231 232 # print "Wall:",self.timeEnd,self.timeStart 233 if self.timeStart==None or self.timeEnd==None: 234 return 0 235 else: 236 return self.timeEnd-self.timeStart
237