def win_check_cpu_use(cpulim, pid): global winlastcpuinfo # get use information and time... now = getruntime() # Get the total cpu time usertime = windows_api.get_process_cpu_time(pid) useinfo = [usertime, now] # get the previous time and cpu so we can compute the percentage oldusertime = winlastcpuinfo[0] oldnow = winlastcpuinfo[1] if winlastcpuinfo == [0, 0]: winlastcpuinfo = useinfo # give them a free pass if it's their first time... return 0 # save this data for next time... winlastcpuinfo = useinfo # Get the elapsed time... elapsedtime = now - oldnow # This is a problem if elapsedtime == 0: return -1 # Error condition # percent used is the amount of change divided by the time... percentused = (usertime - oldusertime) / elapsedtime # Calculate amount of time to sleep for stoptime = nanny.calculate_cpu_sleep_interval(cpulim, percentused, elapsedtime) if stoptime > 0.0: # Try to timeout the process if windows_api.timeout_process(pid, stoptime): # Log the stoptime process_stopped_timeline.append((now, stoptime)) # Drop the first element if the length is greater than the maximum entries if len(process_stopped_timeline) > process_stopped_max_entries: process_stopped_timeline.pop(0) # Return how long we slept so parent knows whether it should sleep return stoptime else: # Process must have been making system call, try again next time return -1 # If the stop time is 0, then avoid calling timeout_process else: return 0.0
def win_check_cpu_use(cpulim, pid): global winlastcpuinfo # get use information and time... now = getruntime() # Get the total cpu time usertime = windows_api.get_process_cpu_time(pid) useinfo = [usertime, now] # get the previous time and cpu so we can compute the percentage oldusertime = winlastcpuinfo[0] oldnow = winlastcpuinfo[1] if winlastcpuinfo == [0,0]: winlastcpuinfo = useinfo # give them a free pass if it's their first time... return 0 # save this data for next time... winlastcpuinfo = useinfo # Get the elapsed time... elapsedtime = now - oldnow # This is a problem if elapsedtime == 0: return -1 # Error condition # percent used is the amount of change divided by the time... percentused = (usertime - oldusertime) / elapsedtime # Calculate amount of time to sleep for stoptime = nanny.calculate_cpu_sleep_interval(cpulim, percentused,elapsedtime) if stoptime > 0.0: # Try to timeout the process if windows_api.timeout_process(pid, stoptime): # Log the stoptime process_stopped_timeline.append((now, stoptime)) # Drop the first element if the length is greater than the maximum entries if len(process_stopped_timeline) > process_stopped_max_entries: process_stopped_timeline.pop(0) # Return how long we slept so parent knows whether it should sleep return stoptime else: # Process must have been making system call, try again next time return -1 # If the stop time is 0, then avoid calling timeout_process else: return 0.0
def calculate_sleeptimes(): ''' <Purpose> calculate amount of sleep time for each process ''' global pid_list global process_cpu_info ## calculate ecalapsed time of the last "period" global last_runtime global cpu_limit this_runtime = nonportable.getruntime() # print "Debug - this_runtime: ", this_runtime # if this_runtime == 0.0: # print "Debug - this_runtime == 0.0 " # return elapsedtime = this_runtime - last_runtime # print "Debug - last_runtime: ", last_runtime # print "Debug - this_runtime: ", this_runtime # print "\n" # print "Debug1 - elapsedtime: ", elapsedtime if elapsedtime < 0.0: print "Error: elapsed time < 0" last_runtime = this_runtime for pid in pid_list: last_user_time = process_cpu_info[pid][0] if ostype == 'Windows': this_user_time = windows_api.get_process_cpu_time(pid) elif ostype == 'Linux': this_user_time = linux_api.get_process_cpu_time(pid) else: raise UnsupportedSystemException, "Unsupported system type: '"+osrealtype+"' (alias: "+ostype+")" # percent used is the amount of change divided by the time... percentused = (this_user_time - last_user_time) / elapsedtime # print "Debug1 - pid:",pid, "percentused: ",percentused # Calculate amount of time to sleep for # print "Debug - cpu_limit: ",cpu_limit[pid] sleeptime = nanny.calculate_cpu_sleep_interval(cpu_limit[pid], percentused,elapsedtime) # print "Debug1 - pid:",pid,"sleeptime: ",sleeptime process_cpu_info[pid][1] = sleeptime process_cpu_info[pid][0] = this_user_time
def resource_monitor(childpid, pipe_handle): """ <Purpose> Function runs in a loop forever, checking resource usage and throttling CPU. Checks CPU, memory, and disk. <Arguments> childpid: The child pid, e.g. the pid of repy pipe_handle: A handle to the pipe to the repy process. Allows sending resource use information. """ # Get our pid ourpid = os.getpid() # Calculate how often disk should be checked disk_interval = int(repy_constants.RESOURCE_POLLING_FREQ_LINUX / repy_constants.CPU_POLLING_FREQ_LINUX) current_interval = -1 # What cycle are we on # Store time of the last interval last_time = getruntime() last_CPU_time = 0 resume_time = 0 # Run forever... while True: ########### Check CPU ########### # Get elapsed time currenttime = getruntime() elapsedtime1 = currenttime - last_time # Calculate against last run elapsedtime2 = currenttime - resume_time # Calculate since we last resumed repy elapsedtime = min(elapsedtime1, elapsedtime2) # Take the minimum interval last_time = currenttime # Save the current time # Safety check, prevent ZeroDivisionError if elapsedtime == 0.0: continue # Get the total cpu at this point totalCPU = os_api.get_process_cpu_time(ourpid) # Our own usage totalCPU += os_api.get_process_cpu_time(childpid) # Repy's usage # Calculate percentage of CPU used percentused = (totalCPU - last_CPU_time) / elapsedtime # Do not throttle for the first interval, wrap around # Store the totalCPU for the next cycle if last_CPU_time == 0: last_CPU_time = totalCPU continue else: last_CPU_time = totalCPU # Calculate stop time stoptime = nanny.calculate_cpu_sleep_interval(nanny.get_resource_limit("cpu"), percentused, elapsedtime) # If we are supposed to stop repy, then suspend, sleep and resume if stoptime > 0.0: # They must be punished by stopping os.kill(childpid, signal.SIGSTOP) # Sleep until time to resume time.sleep(stoptime) # And now they can start back up! os.kill(childpid, signal.SIGCONT) # Save the resume time resume_time = getruntime() # Send this information as a tuple containing the time repy was stopped and # for how long it was stopped write_message_to_pipe(pipe_handle, "repystopped", (currenttime, stoptime)) ########### End Check CPU ########### # ########### Check Memory ########### # Get how much memory repy is using memused = os_api.get_process_rss() # Check if it is using too much memory if memused > nanny.get_resource_limit("memory"): raise ResourceException, "Memory use '"+str(memused)+"' over limit '"+str(nanny.get_resource_limit("memory"))+"'." ########### End Check Memory ########### # ########### Check Disk Usage ########### # Increment our current cycle current_interval += 1; # Check if it is time to check the disk usage if (current_interval % disk_interval) == 0: # Reset the interval current_interval = 0 # Calculate disk used diskused = compute_disk_use(repy_constants.REPY_CURRENT_DIR) # Raise exception if we are over limit if diskused > nanny.get_resource_limit("diskused"): raise ResourceException, "Disk use '"+str(diskused)+"' over limit '"+str(nanny.get_resource_limit("diskused"))+"'." # Send the disk usage information, raw bytes used write_message_to_pipe(pipe_handle, "diskused", diskused) ########### End Check Disk ########### # Sleep before the next iteration time.sleep(repy_constants.CPU_POLLING_FREQ_LINUX)
def resource_monitor(repypid, pipe_handle): """ <Purpose> Function runs in a loop forever, checking resource usage and throttling CPU. Checks CPU, memory, and disk. <Arguments> repypid: The pid of repy pipe_handle: A handle to the pipe to the repy process. Allows sending resource use information. """ # Get our pid ourpid = os.getpid() # Calculate how often disk should be checked disk_interval = int(repy_constants.RESOURCE_POLLING_FREQ_LINUX / repy_constants.CPU_POLLING_FREQ_LINUX) current_interval = -1 # What cycle are we on # Store time of the last interval last_time = getruntime() last_CPU_time = 0 resume_time = 0 # Run forever... while True: ########### Check CPU ########### # Get elapsed time currenttime = getruntime() elapsedtime1 = currenttime - last_time # Calculate against last run elapsedtime2 = currenttime - resume_time # Calculate since we last resumed repy elapsedtime = min(elapsedtime1, elapsedtime2) # Take the minimum interval last_time = currenttime # Save the current time # Safety check, prevent ZeroDivisionError if elapsedtime == 0.0: continue # Get the total cpu at this point totalCPU = os_api.get_process_cpu_time(ourpid) # Our own usage totalCPU += os_api.get_process_cpu_time(repypid) # Repy's usage # Calculate percentage of CPU used percentused = (totalCPU - last_CPU_time) / elapsedtime # Do not throttle for the first interval, wrap around # Store the totalCPU for the next cycle if last_CPU_time == 0: last_CPU_time = totalCPU continue else: last_CPU_time = totalCPU # Calculate stop time stoptime = nanny.calculate_cpu_sleep_interval( nanny.get_resource_limit("cpu"), percentused, elapsedtime) # If we are supposed to stop repy, then suspend, sleep and resume if stoptime > 0.0: # They must be punished by stopping os.kill(repypid, signal.SIGSTOP) # Sleep until time to resume time.sleep(stoptime) # And now they can start back up! os.kill(repypid, signal.SIGCONT) # Save the resume time resume_time = getruntime() # Send this information as a tuple containing the time repy was stopped and # for how long it was stopped write_message_to_pipe(pipe_handle, "repystopped", (currenttime, stoptime)) ########### End Check CPU ########### # ########### Check Memory ########### # Get how much memory repy is using memused = os_api.get_process_rss() # Check if it is using too much memory if memused > nanny.get_resource_limit("memory"): raise ResourceException, "Memory use '" + str( memused) + "' over limit '" + str( nanny.get_resource_limit("memory")) + "'." ########### End Check Memory ########### # ########### Check Disk Usage ########### # Increment our current cycle current_interval += 1 # Check if it is time to check the disk usage if (current_interval % disk_interval) == 0: # Reset the interval current_interval = 0 # Calculate disk used diskused = compute_disk_use(repy_constants.REPY_CURRENT_DIR) # Raise exception if we are over limit if diskused > nanny.get_resource_limit("diskused"): raise ResourceException, "Disk use '" + str( diskused) + "' over limit '" + str( nanny.get_resource_limit("diskused")) + "'." # Send the disk usage information, raw bytes used write_message_to_pipe(pipe_handle, "diskused", diskused) ########### End Check Disk ########### # Sleep before the next iteration time.sleep(repy_constants.CPU_POLLING_FREQ_LINUX)