# Schedulability analysis of tasks with co-runner dependent execution time and also parameter extraction # License: # Copyright 2021 Carnegie Mellon University. # MIT (SEI) # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: # The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. # This material is based upon work funded and supported by the Department of Defense under Contract No. FA8702-15-D-0002 with Carnegie Mellon University for the operation of the Software Engineering Institute, a federally funded research and development center. # The view, opinions, and/or findings contained in this material are those of the author(s) and should not be construed as an official Government position, policy, or decision, unless designated by other documentation. # NO WARRANTY. THIS CARNEGIE MELLON UNIVERSITY AND SOFTWARE ENGINEERING INSTITUTE MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT. # [DISTRIBUTION STATEMENT A] This material has been approved for public release and unlimited distribution. Please see Copyright notice for non-US Government use and distribution. # DM21-0305 # # Q: What does this program do? # A: It implements the schedulability analysis in the article: # [AND18] B. Andersson, H. Kim, D. de Niz, M. Klein, R. (Raj) Rajkumar, and J. Lehoczky, # ``Schedulability Analysis of Tasks with Co-Runner-Dependent Execution Times,'' # ACM Transactions on Embedded Computing Systems, Vol. 17, No. 3, Article 71. May 2018. # It also performs parameter extraction of other programs. This include execution time # and lower bound on speed as a function of co-runner. Once these parameters have # been extracted, one can plug these into this schedulability analysis tool # # Q: How do I install it and how do I run it? # A: Assuming that you use Ubuntu, do the following: # First, install python 3 and make sure scipy is installed. Also install the bitmap package (sudo pip install bitmap). # Choose a directory where you want to run the program and then put the file pyschedanalysiscorunner.py # there. Then open a console and go to this directory. Then enter: # python3 pyschedanalysiscorunner.py # Now you will see a grid with parameters that describe the taskset. You can click the # button "Do schedulability analysis" to perform the schedulability analysis. You can # also modify the taskset parameters so that it models the system that you are interested in. # If you use some other Linux distribution or use Windows, follow approximately the same steps. # # Q: What makes this program different from other schedulability analyses? # A: Consider previous work on schedulability analysis on multicores considering contention for # shared resources in the memory system. It typically models resources and memory accesses # explictly. Such an approach has three drawbacks: # 1. It assumes that one can model the hardware; this is problematic when hardware is # undocumented. # 2. It is very labor intensive to model the hardware and the requests that software # makes on the hardware; typically such work is also specific to a chip and hence with # every new chip, there is additional work that needs to be done. # 3. Even if one has documentation of the hardware and one is willing to model the # hardware and the software, there are often errors in documentation. # For these reasons, it is desirable to use a scheduling theory that avoids these drawbacks. # One way is to use an abstraction; instead of modeling the hardware resources and their # sharing, one models the effect of this sharing. [AND18] presents such an approach and this # code implements this schedulability analysis. There has been a previous implementation of this # schedulability test (schedanalysiscorunner.c); it was used to run experiments in [AND18] # and it had the advantage of being fast because it used a state-of-the-art solver (Gurobi). # Unfortunately, non-academic users have to pay in order to use Gurobi and this is an obstacle # for adoption. Also, this tool did not have any Graphical User Interface (GUI). This tool # (pyschedanalysiscorunner.py) addresses these two issues by (i) using an open source solver # and (ii) providing a GUI. # # Q: How is this program structured internally? # A: Part 1 of the code performs schedulability analysis. Part 2 of the code creates the GUI, # obtains the parameters from the GUI, and calls the schedulability analysis. Part 3 # consists of C source code: measureexecutiontime.c. It is part of parameter extraction. # In order to use it, you need to copy it to a separate file measureexecutiontime.c # and comment out the python comments. Then you need to compile it and put it in # the current directory. Part 4 cosists of experimental data. # # Q: If I want to use this with Gurobi, how do I do it? # A: Change the line # GUROBIFLAG = False # to # GUROBIFLAG = True # You also need to make sure that Gurobi is installed. You can do it as follows: # 1. Go to https://www.gurobi.com/. Then login (and create a acount if you don't have one) # 2. Download Gurobi; i.e., download the file gurobi8.1.1_linux64.tar.gz (or some later version) # Put it in some directory, e.g., /home/ba/gurobi # 3. unzip the file using gunzip gurobi8.1.1_linux64.tar.gz # 4. now you have Gurobi in gurobi8.1.1_linux64.tar.gz # 5. Enter the following in .bashrc # OLD # export GUROBI_HOME="/home/ba/gurobi/gurobi811/linux64" # export PATH="${PATH}:${GUROBI_HOME}/bin" # export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib" # export PYTHONPATH="${PYTHONPATH}:/home/ba/gurobi/gurobi811/linux64/lib/python2.7" # NEW # export GUROBI_HOME="/home/ba/gurobi/gurobi900/linux64" # export PATH="${PATH}:${GUROBI_HOME}/bin" # export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${GUROBI_HOME}/lib" # export PYTHONPATH="${PYTHONPATH}:/home/ba/gurobi/gurobi900/linux64/lib/python2.7_utf32" # or something similar (you directories may be different). # 6. Get license file. You do it as follows: # On Gurobi's website, click "Downloads & Licences" then click "Academic license" under "Request a license" # This will give you a webpage. At the bottom of this page, there is a text # grbgetkey b7624046-eea3-11e9-9369-0a7c4f30bdbe # or something similar. # Run that command. # # Q: Are there any bugs in 3rd party sofware that you have dealt with? # A: Yes, there are two: # 1. spaceex has an option "INTV" that makes it possible to get the maximum value # of a variable in a location. Unfortunately, I have found that is suffers from # an error. It crashes with a seg-fault with the following message: # ../../spaceex/spaceex_exe/spaceex: line 54: 19894 Segmentation fault (core dumped) # LD_LIBRARY_PATH=$script_dir/lib:$LD_LIBRARY_PATH $script_dir/bin/sspaceex "$@" # For this reason, I have not use this feature of spaceex. Instead, # I compute this max in another way (by invoking an external solver). # 2. When addressing the issue 1. above, I invoke an LP solver. # When using scipy on tasksets with many decimals, I get a numerical problem. # I have solved this using Gurobi (and this works fine). # # # Before doing this, run "sudo -i" This is necessary because the parameter extraction # relies on execution-time measurements and this requires that priorities and # processor affinities are set and this requires super user. # # How to setup the target system properly. # 1. Set the clock frequency of CPUs so that it is low and does not # vary too much. Do it as follows: # cpufreq-set -c 7 -d 1700000 -u 1800000 # 2. Check that the frequency has been set properly # more /proc/cpuinfo # 3. Make sure that the runtime monitoring of RT processes are disabled # Do it as follows: # echo -1 > /proc/sys/kernel/sched_rt_runtime_us # echo 0 > /proc/sys/kernel/hung_task_timeout_secs # echo 0 > /proc/sys/kernel/timer_migration # # 4. Set clock frequency: # echo 1700000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu1/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu2/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu3/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu5/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu6/cpufreq/scaling_max_freq # echo 1700000 > /sys/devices/system/cpu/cpu7/cpufreq/scaling_max_freq # # How to run it? # chrt --rr 98 python3 pyschedanalysiscorunner_including_ga_based_parameter_extraction.py # These imports are needed for the schedulability analysis import math from scipy.optimize import linprog # These imports are needed for the GUI import tkinter from tkinter import * import ast import subprocess from itertools import chain, combinations import copy from tkinter import messagebox import os import signal import subprocess import datetime import matplotlib.pyplot as plt # GUROBIFLAG = True GUROBIFLAG = False if GUROBIFLAG: from gurobipy import * # this is used when we periodically check if spaceex has reached an error state import time import shlex, subprocess from bitmap import BitMap import random import statistics from operator import itemgetter, attrgetter import multiprocessing ############################################### # The code below is for schedulability analysis ############################################### def isinhp(iprime,i,priorities,proc): return ((proc[iprime-1]==proc[i-1]) and (priorities[iprime-1]>priorities[i-1])) def listofhptasks(i,ntasks,priorities,proc): return [iprime for iprime in range(1,ntasks+1) if isinhp(iprime,i,priorities,proc)] def isinhep(iprime,i,priorities,proc): return ((proc[iprime-1]==proc[i-1]) and (priorities[iprime-1]>=priorities[i-1])) def listofheptasks(i,ntasks,priorities,proc): return [iprime for iprime in range(1,ntasks+1) if isinhep(iprime,i,priorities,proc)] def isintop(iprime,i,priorities,proc): return (proc[iprime-1]!=proc[i-1]) def listoftoptasks(i,ntasks,priorities,proc): return [iprime for iprime in range(1,ntasks+1) if isintop(iprime,i,priorities,proc)] def listofhepandtoptasks(i,ntasks,priorities,proc): return listofheptasks(i,ntasks,priorities,proc) + listoftoptasks(i,ntasks,priorities,proc) def listofhpandtoptasks(i,ntasks,priorities,proc): return listofhptasks(i,ntasks,priorities,proc) + listoftoptasks(i,ntasks,priorities,proc) def gettaskidfromsegment(seg): return seg[0] def getsegidfromsegment(seg): return seg[1] def segmentsetincludesaheptask(segmentset,i,ntasks,priorities,proc): for iprimeprime in listofheptasks(i,ntasks,priorities,proc): for seg in segmentset: if (gettaskidfromsegment(seg)==iprimeprime): return True return False def segmentsetincludesgivensegment(segmentset,i,k): for seg in segmentset: if ((gettaskidfromsegment(seg)==i) and (getsegidfromsegment(seg)==k)): return True return False def getsegmentsonprocessor(i,p,ntasks,priorities,proc,V): temp = [] for iprime in range(1,ntasks+1): if ((proc[iprime-1]==p) and ((isinhep(iprime,i,priorities,proc)) or (isintop(iprime,i,priorities,proc)))): temp = temp + V[iprime-1] return temp def generate_setofsegmentsets(i,p,ntasks,nprocessors,priorities,proc,V): resultlist = [] segmentsonprocessorlist = getsegmentsonprocessor(i,p,ntasks,priorities,proc,V) if (p==nprocessors): for seg in segmentsonprocessorlist: resultlist.append( [seg] ) else: higherindexprocessorssegmentsetlist = generate_setofsegmentsets( i, p+1, ntasks, nprocessors, priorities, proc, V) for seg in segmentsonprocessorlist: for l in higherindexprocessorssegmentsetlist: resultlist.append( [seg]+l ) for seg in segmentsonprocessorlist: resultlist.append( [seg] ) resultlist = resultlist + higherindexprocessorssegmentsetlist return resultlist def getsegmentsonprocessor_regardless_of_victimtask(p,ntasks,priorities,proc,V): temp = [] for iprime in range(1,ntasks+1): if (proc[iprime-1]==p): temp = temp + V[iprime-1] return temp def generate_setofsegmentsets_regardless_of_victimtask(p,ntasks,nprocessors,priorities,proc,V): resultlist = [] segmentsonprocessorlist = getsegmentsonprocessor_regardless_of_victimtask(p,ntasks,priorities,proc,V) if (p==nprocessors): for seg in segmentsonprocessorlist: resultlist.append( [seg] ) else: higherindexprocessorssegmentsetlist = generate_setofsegmentsets_regardless_of_victimtask( p+1, ntasks, nprocessors, priorities, proc, V) for seg in segmentsonprocessorlist: for l in higherindexprocessorssegmentsetlist: resultlist.append( [seg]+l ) for seg in segmentsonprocessorlist: resultlist.append( [seg] ) resultlist = resultlist + higherindexprocessorssegmentsetlist return resultlist # a corunnerinfo is a pair where the 1st element is a segmentset and the 2nd element is a real number def getcorunnerlistfromcorunnerinfo(corunnerinfo): return corunnerinfo[0] def getspeedfromcorunnerinfo(corunnerinfo): return corunnerinfo[1] def getcoefficient(iprime,kprime,cor,pd,CO): if (len(cor)==0): return 1.0 for corunnerinfo in CO[iprime-1][kprime-1]: if (sorted(getcorunnerlistfromcorunnerinfo(corunnerinfo))==sorted(cor)): return getspeedfromcorunnerinfo(corunnerinfo) return pd[iprime-1][kprime-1] def obtaincorunnerset(iprime,kprime,segmentset): return [segment for segment in segmentset if (segment!=[iprime,kprime])] def getminpw(iprime,kprime,relevantsegmentsets,pd,CO): return min([getcoefficient(iprime,kprime,obtaincorunnerset(iprime,kprime,segmentset),pd,CO) for segmentset in relevantsegmentsets if ([iprime,kprime] in segmentset)]) def computeLST(iprime,kprime,executiontimes,relevantsegmentsets,V,pd,CO): return sum([executiontimes[iprime-1][getsegidfromsegment(seg)-1]/getminpw(iprime,getsegidfromsegment(seg),relevantsegmentsets,pd,CO) for seg in V[iprime-1] if (getsegidfromsegment(seg)0) for kprimeprime in range(1,len(V[iprime-1])+1) if (kprimeprime= beq[rowindex-1] ) m.update m.optimize() m.update return -m.objVal,m.getVars(),'' def solveLPwithscipy( c, A, b): optres = linprog( c, A_ub=A, b_ub=b) return -optres.fun,optres.x,optres.message def solveLPeqwithscipy( c, A, b, Aeq, beq): optres = linprog( c, A_ub=A, b_ub=b, A_eq=Aeq, b_eq=beq) return -optres.fun,optres.x,optres.message def computereqlp(i,t,ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): relevantsegmentsets = [ segmentset for segmentset in generate_setofsegmentsets(i,1,ntasks,nprocessors,priorities,proc,V) if segmentsetincludesaheptask(segmentset,i,ntasks,priorities,proc) ] c = [-1] * len(relevantsegmentsets) A = [] b = [] for iprime in listofheptasks(i,ntasks,priorities,proc): for kprime in [getsegidfromsegment(seg) for seg in V[iprime-1]]: Arow = [ getcoefficient(iprime,kprime,obtaincorunnerset(iprime,kprime,segmentset),pd,CO) if ([iprime,kprime] in segmentset) else 0.0 for segmentset in relevantsegmentsets ] belement = math.ceil(t/periods[iprime-1])*executiontimes[iprime-1][kprime-1] A.append( Arow) b.append( belement ) for iprime in listoftoptasks(i,ntasks,priorities,proc): for kprime in [getsegidfromsegment(seg) for seg in V[iprime-1]]: Arow = [ getcoefficient(iprime,kprime,obtaincorunnerset(iprime,kprime,segmentset),pd,CO) if (([iprime,kprime] in segmentset) and (segmentsetincludesaheptask(segmentset,i,ntasks,priorities,proc))) else 0.0 for segmentset in relevantsegmentsets ] belement = xUB(iprime,kprime,i,t,relevantsegmentsets,ntasks,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) A.append( Arow) b.append( belement ) if GUROBIFLAG: objectiveval,solutionval,msg = solveLPwithgurobi( c, A, b) else: objectiveval,solutionval,msg = solveLPwithscipy( c, A, b) print ("Solving optimization problem for computing upper bound on the response time for task " + str(i) + " with t = " + str(t) + "." ) print (" " + str(relevantsegmentsets) + "\n " + str(objectiveval) + "\n " + str(solutionval) + "\n " + str(msg) ) return objectiveval def doschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): t = [None] * ntasks newt = [None] * ntasks success = True i = 1 while ((i<=ntasks) and (success)): t[i-1] = 0.0 newt[i-1] = sum(executiontimes[i-1]) while ((newt[i-1]>t[i-1]) and (newt[i-1]<=deadlines[i-1])): t[i-1] = newt[i-1] newt[i-1] = computereqlp(i,t[i-1],ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) success = success and (newt[i-1]<=t[i-1]) and (newt[i-1]<=deadlines[i-1]) i = i + 1 if (success): return True, newt else: return False, [] def getallsegments(ntasks,V): temp = [] for iprime in range(1,ntasks+1): temp = temp + V[iprime-1] return temp def powerset(seq): resultlist = [] if len(seq)>=1: if len(seq)==1: resultlist.append([]) resultlist.append(seq) else: for item in powerset(seq[1:]): resultlist.append([seq[0]]+item) resultlist.append(item) return resultlist def thereistaskofhigherpriorityinsegmentset(i,asegmentset,priorities,proc): found = False for seg in asegmentset: iprime = gettaskidfromsegment(seg) if isinhp(iprime,i,priorities,proc): found = True return found def existtwosegmentsofsametask(ntasks,V,asegmentset): found = False for i in range(1,ntasks+1): nsegments = len(V[i-1]) for k in range(1,nsegments+1): for kprime in range(k+1,nsegments+1): if ([i,k] in asegmentset) and ([i,kprime] in asegmentset): found = True return found def getreadysegmentsets(ntasks,V,allsegments): alistofsegmentsets = powerset(allsegments) resultlist = [] for asegmentset in alistofsegmentsets: if not existtwosegmentsofsametask(ntasks,V,asegmentset): resultlist.append( asegmentset) return resultlist def getsegmentidoftaskinsegmentset(asegmentset,V,i): found = False k = -1 for seg in asegmentset: if (seg in V[i-1]): found = True k = getsegidfromsegment(seg) return found,k def segmentsetshavethesamesegments(segmentset1,segmentset2): if len(segmentset1)!=len(segmentset2): return False for seg1 in segmentset1: found = False for seg2 in segmentset2: if ( (gettaskidfromsegment(seg1)==gettaskidfromsegment(seg2)) and (getsegidfromsegment(seg1)==getsegidfromsegment(seg2)) ): found = True if not found: return False return True def findreadysegmentsetinreadysegmentsets(alistofsegmentsets,asegmentset): found = False foundindex = -1 for index in range(0,len(alistofsegmentsets)): if segmentsetshavethesamesegments(alistofsegmentsets[index],asegmentset): found = True foundindex = index return found, foundindex # if exist k s.t. (v_i^k in s) and (not (exist (v_{iprime}^{kprime} in s) and (iprime in hp(i))): def existsasegmentoftaskinsegmentsetandnosegmentofhigherpriorityinsegmentset(i,V,readysegmentset,priorities,proc): for seg in readysegmentset: if gettaskidfromsegment(seg)==i: for seg2 in readysegmentset: if isinhp(gettaskidfromsegment(seg2),i,priorities,proc): return False return True return False # return k s.t. (v_i^k in s) def getcurrentsegmentindexinsegmentset(i,V,readysegmentset): for seg in readysegmentset: if gettaskidfromsegment(seg)==i: return getsegidfromsegment(seg) print ( "Error in getcurrentsegmentindexinsegmentset" ) exit(-1) def getrunningsegmentsetfromreadysegmentset(readysegmentset,priorities,proc): resultlist = [] for seg in readysegmentset: if not thereistaskofhigherpriorityinsegmentset(gettaskidfromsegment(seg),readysegmentset,priorities,proc): resultlist.append(seg) return resultlist def writexmlfile(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): allsegments = getallsegments(ntasks,V) readysegmentsets = getreadysegmentsets(ntasks,V,allsegments) f = open("exact_corunners.xml","w+") f.write("\n") f.write("\n") f.write("\n") for i in range(1,ntasks+1): f.write(" \n") f.write(" \n") # adding location with ready segmentsets for index in range(0,len(readysegmentsets)): readysegmentset = readysegmentsets[index] f.write(" \n") f.write(" ") firstflag = True for i in range(1,ntasks+1): if existsasegmentoftaskinsegmentsetandnosegmentofhigherpriorityinsegmentset(i,V,readysegmentset,priorities,proc): if not firstflag: f.write(" & ") f.write(" a"+str(i)+" <= "+str(deadlines[i-1])+" &" + " c"+str(i)+" <= "+str(executiontimes[i-1][getcurrentsegmentindexinsegmentset(i,V,readysegmentset)-1])+" ") firstflag = False f.write(" \n") f.write(" ") firstflag = True for i in range(1,ntasks+1): if existsasegmentoftaskinsegmentsetandnosegmentofhigherpriorityinsegmentset(i,V,readysegmentset,priorities,proc): if not firstflag: f.write(" & ") k = getcurrentsegmentindexinsegmentset(i,V,readysegmentset) runningsegmentset = getrunningsegmentsetfromreadysegmentset(readysegmentset,priorities,proc) cor = obtaincorunnerset(i,k,runningsegmentset) lbspeed =getcoefficient(i,k,cor,pd,CO) f.write("a"+str(i)+"' == "+str(1)+" & c"+str(i)+"' >= "+ str(lbspeed)+ " & c"+str(i)+"' <= 1") firstflag = False else: if not firstflag: f.write(" & ") f.write("a"+str(i)+"' == "+str(1)+" & c"+str(i)+"' == 0") firstflag = False f.write(" \n") f.write(" \n") # adding error locations for index in range(0,len(readysegmentsets)): for i in range(1,ntasks+1): f.write(" \n") f.write(" \n") # adding edges from locations for each readysegmentset to error for index in range(0,len(readysegmentsets)): readysegmentset = readysegmentsets[index] for i in range(1,ntasks+1): found,k = getsegmentidoftaskinsegmentset(readysegmentset,V,i) if found: f.write(" \n") f.write(" a" + str(i) + " >= " + str(deadlines[i-1]) + " \n") f.write(" \n") # adding edges related to new job arrivals for index in range(0,len(readysegmentsets)): readysegmentset = readysegmentsets[index] for i in range(1,ntasks+1): found,k = getsegmentidoftaskinsegmentset(readysegmentset,V,i) if not found: anotherreadysegmentset = readysegmentset + [[i,1]] found,anotherindex = findreadysegmentsetinreadysegmentsets(readysegmentsets,anotherreadysegmentset) if found: f.write(" \n") f.write(" a" + str(i) + " >= " + str(periods[i-1]) + " \n") f.write(" a" + str(i) + " := 0 & c" + str(i) + " := 0 \n") f.write(" \n") else: print(" Error. Did not find anotherreadysegmentset\n") print(" Searching for\n") print(anotherreadysegmentset) print(" in the list\n") print(readysegmentsets) exit(-1) # adding edges related to a segment finishing for index in range(0,len(readysegmentsets)): readysegmentset = readysegmentsets[index] for i in range(1,ntasks+1): for k in range(1,len(V[i-1])+1): if ([i,k] in readysegmentset) and (not thereistaskofhigherpriorityinsegmentset(i,readysegmentset,priorities,proc)): if k<=len(V[i-1])-1: anotherreadysegmentset = readysegmentset[:] anotherreadysegmentset.remove([i,k]) anotherreadysegmentset.append([i,k+1]) found,anotherindex = findreadysegmentsetinreadysegmentsets(readysegmentsets,anotherreadysegmentset) if found: f.write(" \n") f.write(" c" + str(i) + " := 0 \n") f.write(" \n") else: print(" Error. Did not find anotherreadysegmentset\n") print(" Searching for\n") print(anotherreadysegmentset) print(" in the list\n") print(readysegmentsets) exit(-1) else: anotherreadysegmentset = readysegmentset[:] anotherreadysegmentset.remove([i,k]) found,anotherindex = findreadysegmentsetinreadysegmentsets(readysegmentsets,anotherreadysegmentset) if found: f.write(" \n") f.write(" c" + str(i) + " := 0 \n") # this is not strictly necessary but it helps to cut down the search space. It makes a big difference with resetting c to zero, there is a case when it takes 17 seconds to do reachability but otherwise it would take 189 seconds. f.write(" \n") else: print(" Error. Did not find anotherreadysegmentset\n") print(" Searching for\n") print(anotherreadysegmentset) print(" in the list\n") print(readysegmentsets) exit(-1) f.write("\n") f.write("\n") f.close() def writecfgfile_write_initially(f,ntasks,V): f.write("initially = \"") for i in range(1,ntasks+1): f.write("a"+str(i)+"==0 & c"+str(i)+"==0") if i < ntasks: f.write(" & ") allsegments = getallsegments(ntasks,V) readysegmentsets = getreadysegmentsets(ntasks,V,allsegments) foundindex = -1 for index in range(0,len(readysegmentsets)): readysegmentset = readysegmentsets[index] if readysegmentset==[]: foundindex = index if foundindex==-1: print(" Error. Did not find index with element of zero-length in the list\n") print(readysegmentsets) exit(-1) f.write(" & ") f.write("loc()==segrdy"+str(1+foundindex)) f.write("\"\n") def writecfgfile_write_forbidden(f,ntasks,V): allsegments = getallsegments(ntasks,V) readysegmentsets = getreadysegmentsets(ntasks,V,allsegments) f.write("forbidden = \"") firstwriting = True for index in range(0,len(readysegmentsets)): for i in range(1,ntasks+1): locationname = "errorloc" + str(1+index) + "_" + str(i) if firstwriting: firstwriting = False else: f.write(" | ") f.write(" loc()=="+locationname) f.write("\"\n") def writecfgfile_write_initially_and_forbidden(f,ntasks,V,flag1,flag2): if flag1: writecfgfile_write_initially(f,ntasks,V) if flag2: writecfgfile_write_forbidden(f,ntasks,V) def writecfgfile(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): f = open("exact_corunners.cfg","w+") f.write("system = system\n") writecfgfile_write_initially_and_forbidden(f,ntasks,V,True,False) f.write("scenario = phaver\n") f.write("output-variables = ") for i in range(1,ntasks+1): f.write("a"+str(i)+",c"+str(i)) if i < ntasks: f.write(",") f.write("\n") f.write("output-error = 0\n") f.write("rel-err = 0\n") f.write("abs-err = 0\n") f.close() def islocationreachable(filenameoutputfromspaceex,locationame): f = open(filenameoutputfromspaceex,"r") s = f.read() found = False for word in s.split("|"): searchstr = 'loc()==' + locationame + ' ' res = word.find(searchstr) if res!=-1: found = True f.close() return found def geterrorlocationsreachable(filenameoutputfromspaceex,ntasks,V): allsegments = getallsegments(ntasks,V) readysegmentsets = getreadysegmentsets(ntasks,V,allsegments) listofreachableerrorlocations = [] for index in range(0,len(readysegmentsets)): for i in range(1,ntasks+1): locationame = "errorloc" + str(1+index) + "_" + str(i) if islocationreachable(filenameoutputfromspaceex,locationame): listofreachableerrorlocations.append(locationame) return listofreachableerrorlocations def getlistoftaskswithdeadlinemissfromerrorlocationsreachable(filenameoutputfromspaceex,listofreachableerrorlocations,ntasks,V): allsegments = getallsegments(ntasks,V) readysegmentsets = getreadysegmentsets(ntasks,V,allsegments) resultlist = [] for i in range(1,ntasks+1): for index in range(0,len(readysegmentsets)): locationame = "errorloc" + str(1+index) + "_" + str(i) if islocationreachable(filenameoutputfromspaceex,locationame): if not (i in resultlist): resultlist.append(i) return resultlist def findtaskindexoferrorreachedinfile(): errortaskindex = -1 try: fp = open("log_file_from_spaceex.txt","r") s = fp.read().strip().strip() finally: fp.close() mylistofstrings = s.split("\n") for i in range(0,len(mylistofstrings)): mystring = mylistofstrings[i] searchstr = 'time elapse in loc()==errorloc' res = mystring.find(searchstr) if res!=-1: tempstr = mystring[len(searchstr):] temp_mylistofstrings = tempstr.split("_") if len(temp_mylistofstrings)!=2: print ( 'Error in finderrorreachedinfile. Expecting two strings' ) exit(-1) errorlocationindex = temp_mylistofstrings[0] errortaskindex = temp_mylistofstrings[1] return errortaskindex def doexactschedulabilitytesting_using_SpaceEx(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,flagforterminateonfirsterrorstatereached_localparam): # starttime = datetime.datetime.now() writexmlfile(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) writecfgfile(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) errortaskindex = -1 myoutput = open("log_file_from_spaceex.txt","w+") args = ["../spaceex/spaceex_exe/spaceex","-g","exact_corunners.cfg","-m","exact_corunners.xml","-v","D7","-f","TXT","-o","exact_corunners_output.txt"] p = subprocess.Popen(args, stdout=myoutput, preexec_fn=os.setsid) if flagforterminateonfirsterrorstatereached_localparam: mycontinueflag = True while (mycontinueflag): time.sleep(5) errortaskindex = findtaskindexoferrorreachedinfile() if errortaskindex!=-1: mycontinueflag = False time.sleep(1) os.killpg(os.getpgid(p.pid), signal.SIGTERM) time.sleep(1) if not (p.poll() is None): mycontinueflag = False else: p.wait() errortaskindex = findtaskindexoferrorreachedinfile() myoutput.close() if flagforterminateonfirsterrorstatereached_localparam: if errortaskindex==-1: return True, [] else: return False, [errortaskindex] else: filenameoutputfromspaceex = "exact_corunners_output.txt" listofreachableerrorlocations = geterrorlocationsreachable(filenameoutputfromspaceex,ntasks,V) if len(listofreachableerrorlocations)==0: return True, [] else: for mystr in listofreachableerrorlocations: print("The following error location is reachable: " + mystr) listoftaskswithdeadlinemiss = getlistoftaskswithdeadlinemissfromerrorlocationsreachable(filenameoutputfromspaceex,listofreachableerrorlocations,ntasks,V) return False, listoftaskswithdeadlinemiss def doexactschedulabilitytesting_using_Z3(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,flagforterminateonfirsterrorstatereached_localparam): print ( "Feature not implemented. doexactschedulabilitytesting_using_Z3" ) return True, [] def doexactschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,methodforexactanalysis_localparam,flagforterminateonfirsterrorstatereached_localparam): if methodforexactanalysis_localparam==1: return doexactschedulabilitytesting_using_SpaceEx(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,flagforterminateonfirsterrorstatereached_localparam) else: if methodforexactanalysis_localparam==2: return doexactschedulabilitytesting_using_Z3( ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,flagforterminateonfirsterrorstatereached_localparam) else: print ( "Error in doexactschedulabilitytesting" ) exit(-1) def multiplyexecutiontimes( executiontimes, mul): return [[execvalue * mul for execvalue in executiontimeelement] for executiontimeelement in executiontimes] def multiplyperiods( periods, mul): return [periodelement * mul for periodelement in periods] def multiplydeadlines( deadlines, mul): return [deadlineelement * mul for deadlineelement in deadlines] def getdefaulttaskset1(execmultiplier,allmultiplier): ntasks = 3 nprocessors = 2 priorities = [ 3 , 1 , 2 ] proc = [ 2 , 2 , 1 ] periods = [ 508.827494 , 2873.485391 , 231.911587 ] deadlines = [ 51.58222 , 1414.746314 , 123.257014 ] V = [ [ [1,1] ] , [ [2,1] ] , [ [3,1] ] ] executiontimes = [ [ 0.508827 ] , [ 4.000429 ] , [ 4.074487 ] ] pd = [ [ 0.05 ] , [ 0.05 ] , [ 0.05 ] ] COtask1seg1 = [ [[[3,1]],0.727217] ] COtask2seg1 = [ [[[3,1]],0.616589] ] COtask3seg1 = [ [[[1,1]],0.965866] , [[[2,1]],0.915646] ] CO = [ [ COtask1seg1 ] , [ COtask2seg1 ] , [ COtask3seg1 ] ] executiontimes = multiplyexecutiontimes( executiontimes, execmultiplier) periods = multiplyperiods( periods, allmultiplier) deadlines = multiplydeadlines( deadlines, allmultiplier) executiontimes = multiplyexecutiontimes( executiontimes, allmultiplier) executablecodefilename = [ ["bubblesort"], ["bubblesort"], ["bubblesort"] ] inputsizeinbits = [ [262144], [262144], [262144] ] return ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits def getdefaulttaskset2(execmultiplier,allmultiplier): ntasks = 5 nprocessors = 2 priorities = [ 3 , 2 , 3 , 2 , 1 ] proc = [ 1 , 1 , 2 , 2 , 2 ] periods = [ 1.500 , 2.000 , 2.000 , 2.000 , 2.250 ] deadlines = [ 1.500 , 2.000 , 2.000 , 2.000 , 2.250 ] V = [ [ [1,1] ] , [ [2,1] ] , [ [3,1] ] , [ [4,1] ] , [ [5,1] , [5,2] ] ] executiontimes = [ [ 0.250 ] , [ 0.250 ] , [ 0.250 ] , [ 0.250 ] , [ 0.500 , 0.125 ] ] pd = [ [ 0.500 ] , [ 0.500 ] , [ 0.500 ] , [ 0.500 ] , [ 1.000 , 0.500 ] ] COtask1seg1 = [ [[[3,1]],1.000] , [[[4,1]],0.500] , [[[5,1]],1.000] , [[[5,2]],1.000] ] COtask2seg1 = [ [[[3,1]],0.500] , [[[4,1]],1.000] , [[[5,1]],1.000] , [[[5,2]],1.000] ] COtask3seg1 = [ [[[1,1]],1.000] , [[[2,1]],0.500] ] COtask4seg1 = [ [[[1,1]],0.500] , [[[2,1]],1.000] ] COtask5seg1 = [ [[[1,1]],1.000] , [[[2,1]],1.000] ] COtask5seg2 = [ [[[1,1]],0.500] , [[[2,1]],1.000] ] CO = [ [ COtask1seg1 ] , [ COtask2seg1 ] , [ COtask3seg1 ] , [ COtask4seg1 ] , [ COtask5seg1 , COtask5seg2 ] ] executiontimes = multiplyexecutiontimes( executiontimes, execmultiplier) periods = multiplyperiods( periods, allmultiplier) deadlines = multiplydeadlines( deadlines, allmultiplier) executiontimes = multiplyexecutiontimes( executiontimes, allmultiplier) executablecodefilename = [ ["bubblesort"], ["bubblesort"], ["bubblesort"], ["bubblesort"], ["bubblesort","bubblesort"] ] inputsizeinbits = [ [60000], [60000], [60000], [60000], [85000,38000] ] return ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits ############################################### # The code below is for the GUI ############################################### MAXNTASKS = 10 MAXNSEGMENTSPERTASK = 3 window=Tk() methodforexactanalysis = 0 flagforterminateonfirsterrorstatereached = True window.title("Schedulability analysis of tasks with co-runner dependent execution times") bigframe=Frame(window) bigframe.pack(fill=BOTH,expand=True) topframe=Frame(bigframe) topframe.pack(side=TOP) bottomframe=Frame(bigframe) bottomframe.pack(side=BOTTOM) middleframe=Frame(bigframe) middleframe.pack(fill=BOTH,expand=True) topframe1=Frame(topframe) topframe1.pack(side=TOP) topframe2=Frame(topframe) topframe2.pack(side=BOTTOM) topframe1a=Frame(topframe1) topframe1a.pack(side=TOP) topframe1b=Frame(topframe1) topframe1b.pack(side=BOTTOM) topframe2a=Frame(topframe2) topframe2a.pack(side=TOP) topframe2b=Frame(topframe2) topframe2b.pack(side=BOTTOM) Label(topframe1a, text='This program implements the schedulability test in B. Andersson et al., "Schedulability Analysis of Tasks with Co-Runner-Dependent Execution Times," ACM TECS, 2018.', justify=LEFT).pack(side=TOP) Label(topframe1a, text="It also implements other schedulability tests.", justify=LEFT).pack(side=BOTTOM) Label(topframe1b, text=" ", justify=LEFT).pack(side=TOP) Label(topframe2a, text="Number of tasks").pack(side=LEFT) textentryNumberoftasks = Entry(topframe2a, width=8) textentryNumberoftasks.pack(side=LEFT) Label(topframe2a, text=" ").pack(side=LEFT) Label(topframe2a, text="Number of processors").pack(side=LEFT) textentryNumberofprocessors = Entry(topframe2a, width=8) textentryNumberofprocessors.pack(side=LEFT) Label(topframe2b, text=" ", justify=LEFT).pack(side=TOP) canvas=Canvas(middleframe) vbar=Scrollbar(middleframe,orient=VERTICAL) vbar.pack(side=RIGHT,fill=Y) vbar.config(command=canvas.yview) canvas.config(width=1000,height=1000) canvas.config(yscrollcommand=vbar.set) canvas.pack(side=LEFT, fill=BOTH, expand=True) framewithalllabelsandentryfields=Frame(canvas) framewithalllabelsandentryfields.pack(fill=BOTH, expand=True) def onFrameConfigure(canvas): canvas.configure(scrollregion=canvas.bbox("all")) # canvas.create_window((9,9), window=framewithalllabelsandentryfields, anchor="nw") canvas.create_window((11,11), window=framewithalllabelsandentryfields, anchor="nw") framewithalllabelsandentryfields.bind("", lambda event, canvas=canvas: onFrameConfigure(canvas)) Label(framewithalllabelsandentryfields, text="Minimum" ).grid(row= 5,column= 1) Label(framewithalllabelsandentryfields, text="Deadline" ).grid(row= 5,column= 2) Label(framewithalllabelsandentryfields, text="Number" ).grid(row= 5,column= 3) Label(framewithalllabelsandentryfields, text="Priority" ).grid(row= 5,column= 4) Label(framewithalllabelsandentryfields, text="Processor" ).grid(row= 5,column= 5) Label(framewithalllabelsandentryfields, text="Execution" ).grid(row= 5,column= 6) Label(framewithalllabelsandentryfields, text="Default" ).grid(row= 5,column= 7) Label(framewithalllabelsandentryfields, text="Co-runner" ).grid(row= 5,column= 8) Label(framewithalllabelsandentryfields, text="Executable" ).grid(row= 5,column= 9) Label(framewithalllabelsandentryfields, text="Input" ).grid(row= 5,column=10) Label(framewithalllabelsandentryfields, text="" ).grid(row= 6,column= 0) Label(framewithalllabelsandentryfields, text="inter-arrival" ).grid(row= 6,column= 1) Label(framewithalllabelsandentryfields, text="" ).grid(row= 6,column= 2) Label(framewithalllabelsandentryfields, text="of" ).grid(row= 6,column= 3) Label(framewithalllabelsandentryfields, text="" ).grid(row= 6,column= 4) Label(framewithalllabelsandentryfields, text="" ).grid(row= 6,column= 5) Label(framewithalllabelsandentryfields, text="requirement" ).grid(row= 6,column= 6) Label(framewithalllabelsandentryfields, text="speed" ).grid(row= 6,column= 7) Label(framewithalllabelsandentryfields, text="specification" ).grid(row= 6,column= 8) Label(framewithalllabelsandentryfields, text="code" ).grid(row= 6,column= 9) Label(framewithalllabelsandentryfields, text="size" ).grid(row= 6,column=10) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 0) Label(framewithalllabelsandentryfields, text="time" ).grid(row= 7,column= 1) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 2) Label(framewithalllabelsandentryfields, text="segments" ).grid(row= 7,column= 3) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 4) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 5) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 6) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 7) Label(framewithalllabelsandentryfields, text="" ).grid(row= 7,column= 8) Label(framewithalllabelsandentryfields, text="(filename)" ).grid(row= 7,column= 9) Label(framewithalllabelsandentryfields, text="(bits)" ).grid(row= 7,column=10) textentryPeriod = [] textentryDeadline = [] textentryNumberofsegments = [] textentryPriority = [] textentryProc = [] textentryExecutiontime = [] textentryDefaultprogress = [] textentryCorunnerspecification = [] textentryExecutablecodefilename = [] textentryInputsizeinbits = [] for i in range(1,MAXNTASKS+1): textentryExecutiontime.insert( i-1, [None] * MAXNSEGMENTSPERTASK ) textentryDefaultprogress.insert( i-1, [None] * MAXNSEGMENTSPERTASK ) textentryCorunnerspecification.insert( i-1, [None] * MAXNSEGMENTSPERTASK ) textentryExecutablecodefilename.insert( i-1, [None] * MAXNSEGMENTSPERTASK ) textentryInputsizeinbits.insert( i-1, [None] * MAXNSEGMENTSPERTASK ) for i in range(1,MAXNTASKS+1): tempstr = 'Task ' + str(i) currentrow = 8 + (i-1)*(MAXNSEGMENTSPERTASK+2) Label(framewithalllabelsandentryfields,text=tempstr).grid(row=currentrow,column= 0) textentryPeriod.insert( i-1,Entry(framewithalllabelsandentryfields,width=8) ) textentryPeriod[i-1].grid( row=currentrow,column= 1) textentryDeadline.insert( i-1,Entry(framewithalllabelsandentryfields,width=8) ) textentryDeadline[i-1].grid( row=currentrow,column= 2) textentryNumberofsegments.insert(i-1,Entry(framewithalllabelsandentryfields,width=8) ) textentryNumberofsegments[i-1].grid( row=currentrow,column= 3) textentryPriority.insert( i-1,Entry(framewithalllabelsandentryfields,width=8) ) textentryPriority[i-1].grid( row=currentrow,column= 4) textentryProc.insert( i-1,Entry(framewithalllabelsandentryfields,width=8) ) textentryProc[i-1].grid( row=currentrow,column= 5) for k in range(1,MAXNSEGMENTSPERTASK+1): tempstr = ' Segment ' + str(k) currentrow = 8 + (i-1)*(MAXNSEGMENTSPERTASK+2) + k Label(framewithalllabelsandentryfields, text=tempstr).grid(row=currentrow,column= 0) for k in range(1,MAXNSEGMENTSPERTASK+1): currentrow = 8 + (i-1)*(MAXNSEGMENTSPERTASK+2) + k textentryExecutiontime[i-1].insert( k-1,Entry(framewithalllabelsandentryfields,width=8 )) textentryExecutiontime[i-1][k-1].grid( row=currentrow, column= 6) textentryDefaultprogress[i-1].insert( k-1,Entry(framewithalllabelsandentryfields,width=8 )) textentryDefaultprogress[i-1][k-1].grid( row=currentrow, column= 7) textentryCorunnerspecification[i-1].insert(k-1,Entry(framewithalllabelsandentryfields,width=50)) textentryCorunnerspecification[i-1][k-1].grid(row=currentrow, column= 8) textentryExecutablecodefilename[i-1].insert(k-1,Entry(framewithalllabelsandentryfields,width=20)) textentryExecutablecodefilename[i-1][k-1].grid(row=currentrow, column= 9) textentryInputsizeinbits[i-1].insert(k-1,Entry(framewithalllabelsandentryfields,width=8)) textentryInputsizeinbits[i-1][k-1].grid(row=currentrow, column= 10) currentrow = 8 + (i-1)*(MAXNSEGMENTSPERTASK+2) + (MAXNSEGMENTSPERTASK+1) Label(framewithalllabelsandentryfields, text="").grid(row=currentrow,column=0) def gettasksetfromGUIcomponent(): ntasks = int(textentryNumberoftasks.get()) nprocessors = int(textentryNumberofprocessors.get()) priorities = [None] * ntasks proc = [None] * ntasks periods = [None] * ntasks deadlines = [None] * ntasks V = [None] * ntasks executiontimes = [None] * ntasks pd = [None] * ntasks CO = [None] * ntasks for i in range(1,ntasks+1): executiontimes[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) pd[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) CO[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) for i in range(1,ntasks+1): priorities[i-1] = int(textentryPriority[i-1].get()) proc[i-1] = int(textentryProc[i-1].get()) periods[i-1] = float(textentryPeriod[i-1].get()) deadlines[i-1] = float(textentryDeadline[i-1].get()) V[i-1] = [] for k in range(1,int(textentryNumberofsegments[i-1].get())+1): V[i-1].append( [i,k] ) for k in range(1,int(textentryNumberofsegments[i-1].get())+1): executiontimes[i-1][k-1] = float(textentryExecutiontime[i-1][k-1].get()) pd[i-1][k-1] = float(textentryDefaultprogress[i-1][k-1].get()) CO[i-1][k-1] = ast.literal_eval(textentryCorunnerspecification[i-1][k-1].get()) executablecodefilename[i-1][k-1] = textentryExecutablecodefilename[i-1][k-1].get() inputsizeinbits[i-1][k-1] = int(textentryInputsizeinbits[i-1][k-1].get()) return ntasks, nprocessors, priorities, proc, periods, deadlines, V, executiontimes, pd, CO, executablecodefilename, inputsizeinbits def set_input(GUIelement,value): GUIelement.delete(0, 'end') GUIelement.insert('end', value) def setGUIcomponentsbasedontaskset(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits): set_input(textentryNumberoftasks, str(ntasks)) set_input(textentryNumberofprocessors,str(nprocessors)) for i in range(1,ntasks+1): set_input(textentryPriority[i-1],str(priorities[i-1])) set_input(textentryProc[i-1], str(proc[i-1])) set_input(textentryPeriod[i-1], str(periods[i-1])) set_input(textentryDeadline[i-1],str(deadlines[i-1])) set_input(textentryNumberofsegments[i-1],len(V[i-1])) for k in range(1,len(V[i-1])+1): set_input(textentryExecutiontime[i-1][k-1], str(executiontimes[i-1][k-1])) set_input(textentryDefaultprogress[i-1][k-1], str(pd[i-1][k-1])) set_input(textentryCorunnerspecification[i-1][k-1], str(CO[i-1][k-1])) set_input(textentryExecutablecodefilename[i-1][k-1], str(executablecodefilename[i-1][k-1])) set_input(textentryInputsizeinbits[i-1][k-1], str(inputsizeinbits[i-1][k-1])) def doschedulabilityanalysis(): starttime = datetime.datetime.now() ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO = gettasksetfromGUIcomponent() flag,resp = doschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) if flag: if len(resp)>=1: temps = "Upper bounds on the response times of task are as follows:\n" for i in range(1,ntasks+1): temps = temps + " For task " + str(i) + ": " + str(resp[i-1]) + "\n" else: temps = "" # some schedulability analysis methods may declare schedulable without outputting response times. outputstr1 = str("Taskset is schedulable") outputstr2 = str(temps) finishtime = datetime.datetime.now() outputstr3 = str(finishtime - starttime) print( outputstr1, outputstr2, outputstr3 ) tkinter.messagebox.showinfo(outputstr1, outputstr2) else: outputstr1 = str("Cannot guarantee schedulability") outputstr2 = str(" ") finishtime = datetime.datetime.now() outputstr3 = str(finishtime - starttime) print( outputstr1, outputstr2, outputstr3 ) tkinter.messagebox.showinfo(outputstr1, outputstr2) # The code below is written to deal with the "INTV" bug in Spaceex. def getmaximum_ai_in_location_getindex_a( i): return 2*(i-1) def getmaximum_ai_in_location_getindex_c( i): return 2*(i-1)+1 def obtainArowfromlhsconstraintstring_coefficient_for_variablecharstring( i, variablecharstring, currentstrleftstr,ntasks): searchstr = variablecharstring + str(i) if currentstrleftstr.find(searchstr)!=-1: index = currentstrleftstr.find(searchstr) tempstr = currentstrleftstr[0:index] # now at the end of tempstr, we will find the coefficient (which may be just + or -) # In order to get the coefficient, we will identify the preceding variable name in tempstr FoundPredecessorIndex = -1 FoundPredecessorString = -1 FoundPredecessor = False for j in range(1,ntasks+1): for searchstr in ["a" + str(j),"c" + str(j)]: if tempstr.find(searchstr)!=-1: if FoundPredecessor: if tempstr.find(searchstr)>FoundPredecessorIndex: FoundPredecessorIndex = tempstr.find(searchstr) FoundPredecessorString = searchstr else: FoundPredecessorIndex = tempstr.find(searchstr) FoundPredecessorString = searchstr FoundPredecessor = True if FoundPredecessor: tempstr2 = tempstr[FoundPredecessorIndex+len(FoundPredecessorString):len(tempstr)] else: tempstr2 = tempstr[0:len(tempstr)] tempstr3 = tempstr2.strip() if len(tempstr3)>=1: if tempstr3[len(tempstr3)-1]=="+": return True,1.0 else: if tempstr3[len(tempstr3)-1]=="-": return True,-1.0 else: if tempstr3[len(tempstr3)-1]=="*": tempstr4 = tempstr3[0:len(tempstr3)-1] return True, float(tempstr4) else: print("Error in X") exit(-1) else: return True,1.0 else: return False, -1 def obtainArowfromlhsconstraintstring( currentstrleftstr, ntasks): Arow = [0] * 2 * ntasks for i in range(1,ntasks+1): valuefound,thevalue = obtainArowfromlhsconstraintstring_coefficient_for_variablecharstring(i,"a",currentstrleftstr,ntasks) if valuefound: index = getmaximum_ai_in_location_getindex_a( i) Arow[index] = thevalue valuefound,thevalue = obtainArowfromlhsconstraintstring_coefficient_for_variablecharstring(i,"c",currentstrleftstr,ntasks) if valuefound: index = getmaximum_ai_in_location_getindex_c( i) Arow[index] = thevalue return Arow def getmaximum_ai_in_location(i,locationname,ntasks): try: fp = open("exact_corunners_output.txt","r") s = fp.read().strip("{").strip("}") finally: fp.close() maxsofar_exists = False maxsofar = -1 mylistofstrings = s.split("|") for mystring in mylistofstrings: mystring2 = mystring.strip("(").strip(")") searchstr = "loc()==" + locationname + " " if mystring2.find(searchstr)!=-1: index = mystring2.find("&") if index!=-1: mystring3 = mystring2[index+1:len(mystring2)+1] mylistofconstraints = mystring3.split("&") c = [0] * 2 * ntasks A = [] b = [] Aeq = [] beq = [] index = getmaximum_ai_in_location_getindex_a( i) c[index] = -1 for myconstraint in mylistofconstraints: if myconstraint.find("==")!=-1: index = myconstraint.find("==") currentstr = myconstraint[0:index] Arow = obtainArowfromlhsconstraintstring( currentstr, ntasks) currentstr2 = myconstraint[index+2:len(myconstraint)] belement = float(currentstr2) Aeq.append( Arow) beq.append( belement ) else: if myconstraint.find("<=")!=-1: index = myconstraint.find("<=") currentstr = myconstraint[0:index] Arow = obtainArowfromlhsconstraintstring( currentstr, ntasks) currentstr2 = myconstraint[index+2:len(myconstraint)] belement = float(currentstr2) A.append( Arow) b.append( belement ) else: if myconstraint.find(">=")!=-1: index = myconstraint.find(">=") currentstr = myconstraint[0:index] Arow = obtainArowfromlhsconstraintstring( currentstr, ntasks) currentstr2 = myconstraint[index+2:len(myconstraint)] belement = float(currentstr2) A.append( [x*(-1) for x in Arow] ) b.append( (-1)*belement ) else: print("Error in getmaximum_ai_in_location. This is not an equality and it is not an inequality.") exit(-1) if GUROBIFLAG: if len(Aeq)==0: objectiveval,solutionval,msg = solveLPwithgurobi( c, A, b) else: objectiveval,solutionval,msg = solveLPeqwithgurobi( c, A, b, Aeq, beq) else: if len(Aeq)==0: objectiveval,solutionval,msg = solveLPwithscipy( c, A, b) else: objectiveval,solutionval,msg = solveLPeqwithscipy( c, A, b, Aeq, beq) if objectiveval<0: print( "Error in getmaximum_ai_in_location" ) print( "i = " + str(i) ) print( "objectiveval = " + str(objectiveval) ) exit(-1) if maxsofar_exists: if maxsofar0: outputstr2 = outputstr2 + ", " outputstr2 = outputstr2 + "Task " + str(listoftaskswithdeadlinemiss[index]) finishtime = datetime.datetime.now() outputstr3 = str(finishtime - starttime) print( outputstr1, outputstr2, outputstr3 ) tkinter.messagebox.showinfo(outputstr1, outputstr2) def doalmostexactschedulabilitytesting_init(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): newvector = [0.0] * ntasks for j in range(1,ntasks+1): newvector[j-1] = sum(executiontimes[j-1]) return newvector def doalmostexactschedulabilitytesting_choosei(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,found,t,oldi): for j in range(oldi+1,ntasks+1): if (not found[j-1]): return j for j in range(1,oldi+1): if (not found[j-1]): return j print( "Error. Could not select an i." ) exit(-1) def getdurationoftask(iprime,executiontimes,relevantsegmentsets,V,pd,CO): return sum([executiontimes[iprime-1][getsegidfromsegment(seg)-1]/getminpw(iprime,getsegidfromsegment(seg),relevantsegmentsets,pd,CO) for seg in V[iprime-1] ]) def doalmostexactschedulabilitytesting_getBIGM(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,relevantsegmentsets,i): tempsum = 0 temp = getdurationoftask(i,executiontimes,relevantsegmentsets,V,pd,CO); tempsum = tempsum + temp for iprime in listofhptasks(i,ntasks,priorities,proc): temp = getdurationoftask(iprime,executiontimes,relevantsegmentsets,V,pd,CO)*math.ceil(t[i-1]/periods[iprime-1]); tempsum = tempsum + temp for iprime in listoftoptasks(i,ntasks,priorities,proc): temp = getdurationoftask(iprime,executiontimes,relevantsegmentsets,V,pd,CO)*(1+math.ceil(t[i-1]/periods[iprime-1])); tempsum = tempsum + temp return tempsum def doalmostexactschedulabilitytesting_getnpos(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i): njobs = 0 njobs = njobs + 1 # adding the single job of task i for iprime in listofhptasks(i,ntasks,priorities,proc): njobs = njobs + int(math.ceil(t[i-1]/periods[iprime-1])) for iprime in listoftoptasks(i,ntasks,priorities,proc): njobs = njobs + int(1+math.ceil(t[i-1]/periods[iprime-1])) npos = 2*njobs-1 return npos def getvarnamefor_t(p): return 'tU' + str(p) def getvarnamefor_a(iprime,p): return 'a_' + str(iprime) + 'U' + str(p) def getvarnamefor_c(iprime,vprime,p): return 'c_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_elig(iprime,vprime,p): return 'elig_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_x(iprime,vprime,p): return 'x_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_nelig(iprime,vprime,p): return 'nelig_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_nhpelig(iprime,p): return 'nhpelig_' + str(iprime) + 'U' + str(p) def getvarnamefor_arrives(iprime,vprime,p): return 'arrives_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_finishes(iprime,vprime,p): return 'finishes_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_exec(iprime,vprime,p): return 'exec_' + str(iprime) + '_' + str(vprime) + 'U' + str(p) def getvarnamefor_r(): return 'r' def doalmostexactschedulabilitytesting_req(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i): npos = doalmostexactschedulabilitytesting_getnpos(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i) m = Model("corunners") m.Params.NumericFocus = 3 m.Params.Quad = 1 # now we add the essential variables for p in range(1,npos+2): m.addVar(vtype=GRB.CONTINUOUS,name=getvarnamefor_t(p)) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(1,npos+2): m.addVar(vtype=GRB.CONTINUOUS,name=getvarnamefor_a(iprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.CONTINUOUS,name=getvarnamefor_c(iprime,vprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_elig(iprime,vprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_x(iprime,vprime,p) ) # now we add shorthand variables relevantsegmentsets = [ segmentset for segmentset in generate_setofsegmentsets(i,1,ntasks,nprocessors,priorities,proc,V) if segmentsetincludesaheptask(segmentset,i,ntasks,priorities,proc) ] BIGM = doalmostexactschedulabilitytesting_getBIGM(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,relevantsegmentsets,i) print( 'BIGM' ) print( BIGM ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_nelig(iprime,vprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_nhpelig(iprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_arrives(iprime,vprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addVar(vtype=GRB.BINARY,name=getvarnamefor_finishes(iprime,vprime,p) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+1): m.addVar(vtype=GRB.CONTINUOUS,name=getvarnamefor_exec(iprime,vprime,p) ) # now we add variable for objective m.addVar( vtype=GRB.CONTINUOUS,name=getvarnamefor_r() ) m.update() m.setObjective( m.getVarByName(getvarnamefor_r()), GRB.MAXIMIZE) m.update() # Let us add constraints about representation and invariants m.addConstr( m.getVarByName( getvarnamefor_t(1)) == 0 ) for p in range(1,npos+1): m.addConstr( m.getVarByName( getvarnamefor_t(p)) <= m.getVarByName( getvarnamefor_t(p+1)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(1,npos+2): m.addConstr( 0 <= m.getVarByName(getvarnamefor_a(iprime,p)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addConstr( 0 <= m.getVarByName(getvarnamefor_c(iprime,vprime,p)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addConstr( m.getVarByName(getvarnamefor_c(iprime,vprime,p)) <= executiontimes[iprime-1][vprime-1] ) # Let us add constraints about start for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): templist = [] for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist.append( m.getVarByName( getvarnamefor_elig(iprime,vprime,1))) m.addConstr( sum(templist) <= 1 ) m.addConstr( m.getVarByName( getvarnamefor_elig(i,1,1)) == 1 ) for seg in V[i-1]: v = getsegidfromsegment(seg) if (v>=2): m.addConstr( m.getVarByName( getvarnamefor_elig(i,v,1)) == 0 ) m.addConstr( m.getVarByName( getvarnamefor_a(i,1)) == 0 ) for seg in V[i-1]: v = getsegidfromsegment(seg) m.addConstr( m.getVarByName( getvarnamefor_c(i,v,1)) == 0 ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) if (vprime>=2): m.addConstr( m.getVarByName( getvarnamefor_elig(iprime,vprime,1)) == 0 ) for iprime in listofhptasks(i,ntasks,priorities,proc): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_elig(iprime,1,1)), True, m.getVarByName( getvarnamefor_a(iprime,1)) == 0 ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) m.addConstr( m.getVarByName( getvarnamefor_c(iprime,vprime,1)) == 0 ) enablerespecttconstraints = 1 if enablerespecttconstraints==1: for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) m.addGenConstrIndicator( m.getVarByName( getvarnamefor_elig(iprime,vprime,1)), True, m.getVarByName( getvarnamefor_a(iprime,1)) <= t[iprime-1] ) # Let us add constraints about finish for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) m.addConstr( m.getVarByName( getvarnamefor_elig(iprime,vprime,npos+1)) == 0 ) # Let us add constraints short-hand for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): m.addConstr( m.getVarByName( getvarnamefor_elig(iprime,vprime,p)) + m.getVarByName( getvarnamefor_nelig(iprime,vprime,p)) == 1) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(1,npos+2): templist = [] for iprimeprime in listofhptasks(iprime,ntasks,priorities,proc): for seg2 in V[iprimeprime-1]: vprimeprime = getsegidfromsegment(seg2) tempitem = m.getVarByName( getvarnamefor_nelig(iprimeprime,vprimeprime,p)) templist.append( tempitem) if len(templist)==0: m.addConstr( m.getVarByName( getvarnamefor_nhpelig(iprime,p)) == 1 ) else: if len(templist)==1: m.addConstr( m.getVarByName( getvarnamefor_nhpelig(iprime,p)) == templist[0] ) else: m.addGenConstrAnd( m.getVarByName( getvarnamefor_nhpelig(iprime,p)), templist ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): templist = [] tempitem = m.getVarByName( getvarnamefor_elig(iprime,vprime,p)) templist.append( tempitem) tempitem = m.getVarByName( getvarnamefor_nelig(iprime,vprime,p-1)) templist.append( tempitem) m.addGenConstrAnd( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p)), templist ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): templist = [] tempitem = m.getVarByName( getvarnamefor_nelig(iprime,vprime,p)) templist.append( tempitem) tempitem = m.getVarByName( getvarnamefor_elig(iprime,vprime,p-1)) templist.append( tempitem) m.addGenConstrAnd( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p)), templist ) # Let us add constraints about dispatch for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(1,npos+2): templist = [] templist.append( m.getVarByName(getvarnamefor_elig(iprime,vprime,p)) ) templist.append( m.getVarByName(getvarnamefor_nhpelig(iprime,p)) ) m.addGenConstrAnd( m.getVarByName(getvarnamefor_x(iprime,vprime,p)), templist ) # Let us add constraints about arrivals for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,1,p)), True, m.getVarByName( getvarnamefor_a(iprime,p-1)) + m.getVarByName( getvarnamefor_t(p)) - m.getVarByName( getvarnamefor_t(p-1)) >= periods[iprime-1] ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) if vprime>=2: for p in range(1,npos+2): m.addConstr( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p)) == m.getVarByName( getvarnamefor_finishes(iprime,vprime-1,p)) ) # Let us add constraints about updating state a for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,1,p)), True, m.getVarByName( getvarnamefor_a(iprime,p)) == 0 ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,1,p)), False, m.getVarByName( getvarnamefor_a(iprime,p)) == m.getVarByName( getvarnamefor_a(iprime,p-1)) + m.getVarByName( getvarnamefor_t(p)) - m.getVarByName( getvarnamefor_t(p-1)) ) # Let us add constraints about constrain exec for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addConstr( 0 <= m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addConstr( m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) <= m.getVarByName( getvarnamefor_t(p)) - m.getVarByName( getvarnamefor_t(p-1)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): for segmentsetindex in range(0,len(relevantsegmentsets)): if seg in relevantsegmentsets[segmentsetindex]: cor = obtaincorunnerset(iprime,vprime,relevantsegmentsets[segmentsetindex]) lbspeed =getcoefficient(iprime,vprime,cor,pd,CO) templist1 = [] templist2 = [] for iprimeprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg2 in V[iprimeprime-1]: if seg2 in relevantsegmentsets[segmentsetindex]: vprimeprime = getsegidfromsegment(seg2) templist1.append( m.getVarByName( getvarnamefor_x(iprimeprime,vprimeprime,p-1))) else: vprimeprime = getsegidfromsegment(seg2) templist2.append( m.getVarByName( getvarnamefor_x(iprimeprime,vprimeprime,p-1))) m.addConstr( m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) >= lbspeed * (m.getVarByName( getvarnamefor_t(p)) - m.getVarByName( getvarnamefor_t(p-1))) + (sum(templist1) - sum(templist2) - len(relevantsegmentsets[segmentsetindex]))*BIGM ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_x(iprime,vprime,p-1)), False, m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) == 0 ) # Let us add constraints about updating state c for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p)), True, m.getVarByName( getvarnamefor_c(iprime,vprime,p)) == 0 ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p)), False, m.getVarByName( getvarnamefor_c(iprime,vprime,p)) == m.getVarByName( getvarnamefor_c(iprime,vprime,p-1)) + m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) ) if enablerespecttconstraints==1: # Let us add constraints about respect t for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): if (iprime!=i): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p)), True, m.getVarByName( getvarnamefor_a(iprime,p)) <= t[iprime-1] ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p)), True, m.getVarByName( getvarnamefor_t(p)) <= t[i-1] ) # Let us add constraints about single job of task i for p in range(2,npos+2): m.addConstr( m.getVarByName( getvarnamefor_arrives(i,1,p)) == 0 ) # Let us add constraints expressing response time of task i for p in range(2,npos+2): m.addGenConstrIndicator( m.getVarByName( getvarnamefor_finishes(i,len(V[i-1]),p)), True, m.getVarByName(getvarnamefor_r()) == m.getVarByName( getvarnamefor_t(p)) ) enableredundantconstraints = 0 if enableredundantconstraints==1: # Let us add constraints that are redundant but may help to solve the optimization faster for p in range(1,npos+2): m.addConstr( m.getVarByName( getvarnamefor_t(p)) <= BIGM ) for p in range(1,npos+2): m.addConstr( 0 <= m.getVarByName( getvarnamefor_t(p)) ) for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for p in range(1,npos+2): templist = [] for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist.append( m.getVarByName( getvarnamefor_elig(iprime,vprime,p))) m.addConstr( sum(templist) <= 1 ) for p in range(2,npos+2): templist1 = [] for seg in V[i-1]: v = getsegidfromsegment(seg) templist1.append( m.getVarByName( getvarnamefor_elig(i,v,p-1))) templist2 = [] for seg in V[i-1]: v = getsegidfromsegment(seg) templist2.append( m.getVarByName( getvarnamefor_elig(i,v,p))) m.addConstr( sum(templist1) >= sum(templist2) ) for seg in V[i-1]: v = getsegidfromsegment(seg) templist = [] for p in range(1,npos+1): templist.append( m.getVarByName( getvarnamefor_exec(i,v,p))) m.addConstr( sum(templist) <= executiontimes[i-1][v-1] ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(1,npos+1): templist.append( m.getVarByName( getvarnamefor_exec(iprime,vprime,p))) m.addConstr( sum(templist) <= math.ceil(t[i-1]/periods[iprime-1])*executiontimes[iprime-1][vprime-1] ) for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(1,npos+1): templist.append( m.getVarByName( getvarnamefor_exec(iprime,vprime,p))) m.addConstr( sum(templist) <= (1+math.ceil(t[i-1]/periods[iprime-1]))*executiontimes[iprime-1][vprime-1] ) for p in range(2,npos+2): m.addConstr( m.getVarByName( getvarnamefor_arrives(i,1,p)) == 0 ) templist = [] for p in range(2,npos+2): templist.append( m.getVarByName( getvarnamefor_finishes(i,1,p))) m.addConstr( sum(templist) == 1 ) for seg in V[i-1]: v = getsegidfromsegment(seg) if v>=2: templist = [] for p in range(1,npos+2): templist.append( m.getVarByName( getvarnamefor_arrives(i,v,p))) m.addConstr( sum(templist) == 1 ) for seg in V[i-1]: v = getsegidfromsegment(seg) if v>=2: templist = [] for p in range(1,npos+2): templist.append( m.getVarByName( getvarnamefor_finishes(i,v,p))) m.addConstr( sum(templist) == 1 ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(2,npos+2): templist.append( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p))) m.addConstr( m.getVarByName( getvarnamefor_elig(iprime,vprime,1)) + sum(templist) <= math.ceil(t[i-1]/periods[iprime-1]) ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(2,npos+2): templist.append( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p))) m.addConstr( sum(templist) <= math.ceil(t[i-1]/periods[iprime-1]) ) for iprime in listofhptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist1 = [] for p in range(2,npos+2): templist1.append( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p))) templist2 = [] for p in range(2,npos+2): templist2.append( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p))) m.addConstr( m.getVarByName( getvarnamefor_elig(iprime,vprime,1)) + sum(templist1) == sum(templist2) ) for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(2,npos+2): templist.append( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p))) m.addConstr( sum(templist) <= math.ceil(1+t[i-1]/periods[iprime-1]) ) for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist = [] for p in range(2,npos+2): templist.append( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p))) m.addConstr( sum(templist) <= math.ceil(1+t[i-1]/periods[iprime-1]) ) for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist1 = [] for p in range(2,npos+2): templist1.append( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p))) templist2 = [] for p in range(2,npos+2): templist2.append( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p))) m.addConstr( 0 <= sum(templist2) - sum(templist1) ) m.addConstr( sum(templist2) - sum(templist1) <= 1) for iprime in listoftoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) templist1 = [] for p in range(2,npos+2): templist1.append( m.getVarByName( getvarnamefor_arrives(iprime,vprime,p))) templist2 = [] for p in range(2,npos+2): templist2.append( m.getVarByName( getvarnamefor_finishes(iprime,vprime,p))) templist3 = [] for seg3 in V[iprime-1]: vprimeprime = getsegidfromsegment(seg3) if vprimeprime<=vprime: templist3.append( m.getVarByName( getvarnamefor_elig(iprime,vprimeprime,1))) m.addConstr( sum(templist2) - sum(templist1) == sum(templist3) ) enableredundantlowerboundspeedconstraints = 1 if enableredundantlowerboundspeedconstraints==1: for iprime in listofhepandtoptasks(i,ntasks,priorities,proc): for seg in V[iprime-1]: vprime = getsegidfromsegment(seg) for p in range(2,npos+2): lbspeedindependentofcorunners = getminpw(iprime,vprime,relevantsegmentsets,pd,CO) m.addGenConstrIndicator( m.getVarByName( getvarnamefor_x(iprime,vprime,p-1)), True, m.getVarByName( getvarnamefor_exec(iprime,vprime,p-1)) >= lbspeedindependentofcorunners * (m.getVarByName( getvarnamefor_t(p)) - m.getVarByName( getvarnamefor_t(p-1))) ) enableredundantusereqlpboundconstraints = 1 if enableredundantusereqlpboundconstraints==1: temp = computereqlp(i,t[i-1],ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) m.addConstr( m.getVarByName(getvarnamefor_r()) <= temp ) for p in range(1,npos+1): m.addConstr( m.getVarByName( getvarnamefor_t(p)) <= temp ) m.update() m.write('out.lp') # this is not strictly necessary but it is sometimes useful to see what the LP instance looks like m.update() m.optimize() m.update() m.write('out.sol') # this is not strictly necessary but it is sometimes useful to see what the solution looks like m.update() print( m.objVal,m.getVars() ) # this is not strictly necessary but it is sometimes useful to see what the solution looks like return m.objVal def doalmostexactschedulabilitytesting_next(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i): newvector = [0.0] * ntasks for j in range(1,ntasks+1): newvector[j-1] = t[j-1] newvector[i-1] = doalmostexactschedulabilitytesting_req(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i) return newvector def doalmostexactschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO): found= [False] * ntasks t = doalmostexactschedulabilitytesting_init(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) if (not all([ ((0 <= t[j-1]) and (t[j-1] <= deadlines[j-1])) for j in range(1,ntasks+1) ])): print( "Schedulability test failed because t was not in DSET" ) return False, [] i = doalmostexactschedulabilitytesting_choosei(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,found,t, ntasks) print ( 'i, t' ) print ( i, t ) newt = doalmostexactschedulabilitytesting_next(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i) print ( 'i, newt' ) print ( i, newt ) if (newt[i-1]<=t[i-1]): found[i-1] = True else: found= [False] * ntasks while ( (all([ ((0<=newt[j-1]) and (newt[j-1]<=deadlines[j-1])) for j in range(1,ntasks+1) ])) and (not (all(found))) ): for j in range(1,ntasks+1): t[j-1] = newt[j-1] i = doalmostexactschedulabilitytesting_choosei(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,found,t, i) print ( 'i, t' ) print ( i, t ) newt = doalmostexactschedulabilitytesting_next(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,t,i) print ( 'i, newt' ) print ( i, newt ) if (newt[i-1]<=t[i-1]): found[i-1] = True else: found= [False] * ntasks if (all([ ((0<=newt[j-1]) and (newt[j-1]<=deadlines[j-1])) for j in range(1,ntasks+1) ])): return True, t else: return False, [] def doalmostexactschedulabilityanalysis(): starttime = datetime.datetime.now() ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO = gettasksetfromGUIcomponent() flag,resp = doalmostexactschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) if flag: if len(resp)>=1: temps = "Upper bounds on the response times of task are as follows:\n" for i in range(1,ntasks+1): temps = temps + " For task " + str(i) + ": " + str(resp[i-1]) + "\n" else: temps = "" # some schedulability analysis methods may declare schedulable without outputting response times. outputstr1 = str("Taskset is schedulable") outputstr2 = str(temps) finishtime = datetime.datetime.now() outputstr3 = str(finishtime - starttime) print ( outputstr1, outputstr2, outputstr3 ) tkinter.messagebox.showinfo(outputstr1, outputstr2) else: outputstr1 = str("Cannot guarantee schedulability") outputstr2 = str(" ") finishtime = datetime.datetime.now() outputstr3 = str(finishtime - starttime) print ( outputstr1, outputstr2, outputstr3 ) tkinter.messagebox.showinfo(outputstr1, outputstr2) def genericdoschedulabilityanalysis(): if methodforexactanalysis==0: doschedulabilityanalysis() else: if methodforexactanalysis==1: doexactschedulabilityanalysis() else: if methodforexactanalysis==2: doalmostexactschedulabilityanalysis() else: print ( "Error. The schedulability analysis was not implemented" ) class MyDialogOptions: def __init__(self, parent): top = self.top = Toplevel(parent) self.methodforexactanalysis_radiobutton_variable = IntVar() self.methodforexactanalysis_radiobutton_variable.set(methodforexactanalysis) self.flagforterminateonfirsterrorstatereached_checkbox_variable = BooleanVar() self.flagforterminateonfirsterrorstatereached_checkbox_variable.set(flagforterminateonfirsterrorstatereached) self.mylabempty = Label( top, text=""" """, justify = LEFT, padx = 20) self.mylabempty.pack() self.mylab = Label( top, text="""Method used for schedulability analysis: """, justify = LEFT, padx = 20) self.mylab.pack() self.radiobutton1 = Radiobutton(top, text="Sufficient Schedulability Analysis (TECS article)", padx = 20, variable=self.methodforexactanalysis_radiobutton_variable, value=0) self.radiobutton1.pack(anchor=W) self.radiobutton2 = Radiobutton(top, text="Exact Schedulability Analysis (SpaceEx)", padx = 20, variable=self.methodforexactanalysis_radiobutton_variable, value=1) self.radiobutton2.pack(anchor=W) self.radiobutton3 = Radiobutton(top, text="Almost Exact Schedulability Analysis", padx = 20, variable=self.methodforexactanalysis_radiobutton_variable, value=2) self.radiobutton3.pack(anchor=W) self.mylabempty2 = Label( top, text=""" """, justify = LEFT, padx = 20) self.mylabempty2.pack() self.mylab2 = Label( top, text="""Options for Exact Schedulability Analysis (SpaceEx)""", justify = LEFT, padx = 20) self.mylab2.pack() self.checkbutton = Checkbutton(top, text="Terminate on first error state reached", padx = 20, variable=self.flagforterminateonfirsterrorstatereached_checkbox_variable) self.checkbutton.pack(anchor=W) self.mySubmitButton = Button(top, text='Submit', command=self.send) self.mySubmitButton.pack() def send(self): global methodforexactanalysis global flagforterminateonfirsterrorstatereached methodforexactanalysis = self.methodforexactanalysis_radiobutton_variable.get() flagforterminateonfirsterrorstatereached = self.flagforterminateonfirsterrorstatereached_checkbox_variable.get() self.top.destroy() def options(): inputDialog = MyDialogOptions(bottomframe) bottomframe.wait_window(inputDialog.top) def getintfromlist( mylist, index_of_list): resultA = mylist[index_of_list] resultB = index_of_list + 1 return int(resultA), resultB def get2intfromlist( mylist, index_of_list): resultA = mylist[index_of_list] resultB = mylist[index_of_list+1] resultC = index_of_list + 2 return int(resultA), int(resultB), resultC def get3intfromlist( mylist, index_of_list): resultA = mylist[index_of_list] resultB = mylist[index_of_list+1] resultC = mylist[index_of_list+2] resultD = index_of_list + 3 return int(resultA), int(resultB), int(resultC), resultD def getfloatfromlist( mylist, index_of_list): resultA = mylist[index_of_list] resultB = index_of_list + 1 return float(resultA), resultB def get2floatfromlist( mylist, index_of_list): resultA = mylist[index_of_list] resultB = mylist[index_of_list+1] resultC = index_of_list + 2 return float(resultA), float(resultB), resultC def loadtasksetfromfile(): fn = tkFileDialog.askopenfilename(initialdir = os.getcwd(),title="Select file",filetypes = (("text files","*.txt"),("all files","*.*"))) if len(fn)>=1: ntasks = -1 nprocessors = -1 priorities = [] proc = [] periods = [] deadlines = [] V = [] executiontimes = [] pd = [] CO = [] f=open(fn,"r") if f.mode=='r': filecontents = f.read().split() index_of_filecontents = 0 method, index_of_filecontents = getintfromlist( filecontents, index_of_filecontents) if method==1: nprocessors, ntasks, index_of_filecontents = get2intfromlist( filecontents, index_of_filecontents) for i in range(1,ntasks+1): temp_id, temp_priority, temp_proc, index_of_filecontents = get3intfromlist( filecontents, index_of_filecontents) temp_period, temp_deadline, index_of_filecontents = get2floatfromlist( filecontents, index_of_filecontents) if temp_id==i: priorities.append( temp_priority) proc.append( temp_proc) periods.append( temp_period) deadlines.append( temp_deadline) Vsforthistask = [] executiontimesforthistask = [] pdforthistask = [] COforthistask = [] temp_nsegments, index_of_filecontents = getintfromlist( filecontents, index_of_filecontents) for k in range(1,temp_nsegments+1): temp_segmentid, index_of_filecontents = getintfromlist( filecontents, index_of_filecontents) temp_executiontime, temp_pd, index_of_filecontents = get2floatfromlist( filecontents, index_of_filecontents) if temp_segmentid==k: Vsforthistask.append([i,k]) executiontimesforthistask.append( temp_executiontime) pdforthistask.append( temp_pd) temp_cardinality_of_CO, index_of_filecontents = getintfromlist( filecontents, index_of_filecontents) COforthissegment = [] for iterator in range(0,temp_cardinality_of_CO): temp_corunnersetcount, index_of_filecontents = getintfromlist( filecontents, index_of_filecontents) cor = [] for iterator2 in range(0,temp_corunnersetcount): temp_taskindexincorunnerset, temp_segindexincorunnerset, index_of_filecontents = get2intfromlist( filecontents, index_of_filecontents) cor.append( [temp_taskindexincorunnerset,temp_segindexincorunnerset] ) temp_speedincorunnerset, index_of_filecontents = getfloatfromlist( filecontents, index_of_filecontents) COforthissegment.append([cor,temp_speedincorunnerset]) COforthistask.append( COforthissegment) else: print ( "Error when reading file. Expected another segmentid." ) exit(-1) V.append( Vsforthistask) executiontimes.append( executiontimesforthistask) pd.append( pdforthistask) CO.append( COforthistask) else: print ( "Error when reading file. Expected another taskid." ) exit(-1) else: print ( "Error when reading file. The method is incorrect." ) exit(-1) else: print ( "Error when reading file. Could not open file in read mode." ) exit(-1) f.close() setGUIcomponentsbasedontaskset(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) else: print ( "No file selected. Hence, no taskset is loaded." ) os.getcwd() def savetasksettofile(): fn = tkFileDialog.asksaveasfilename(initialdir = os.getcwd(),title="Select file",filetypes = (("text files","*.txt"),("all files","*.*"))) if len(fn)>=1: ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO = gettasksetfromGUIcomponent() f= open(fn,"w+") if f.mode=='w+': f.write(str(1)+"\n") f.write(str(nprocessors)+"\n") f.write(str(ntasks)+"\n") for i in range(1,ntasks+1): f.write(str(i)+"\n") f.write(str(priorities[i-1])+"\n") f.write(str(proc[i-1])+"\n") f.write(str(periods[i-1])+" "+str(deadlines[i-1])+"\n") f.write(str(len(V[i-1]))+"\n") for k in range(1,len(V[i-1])+1): f.write(str(k)+"\n") f.write(str(executiontimes[i-1][k-1])+"\n") f.write(str(pd[i-1][k-1])+"\n") f.write(str(len(CO[i-1][k-1]))+"\n") for iterator in range(0,len(CO[i-1][k-1])): cor = CO[i-1][k-1][iterator][0] speed = CO[i-1][k-1][iterator][1] f.write(str(len(cor)) + " ") for iterator2 in range(0,len(cor)): f.write(str(cor[iterator2][0])) f.write(" ") f.write(str(cor[iterator2][1])) f.write(" ") f.write(str(speed)) f.write("\n") else: print ( "Error when reading file. Could not open file in read mode." ) exit(-1) f.close() setGUIcomponentsbasedontaskset(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) else: print ( "No file selected. Hence, the taskset is not saved." ) def setGUIcomponentstodefaulttaskset(): ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits = getdefaulttaskset2(1.0,1.0) setGUIcomponentsbasedontaskset(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits) def getlistsfromcolumnsinfile(fn,columnindex_firstone,columnindex_secondone): inF = open(fn,"r") l = inF.readlines() inF.close() list1 = [] list2 = [] for index in range(0,len(l)): aline = l[index] currentlist = aline.split(' ') list1.append( currentlist[columnindex_firstone] ) list2.append( currentlist[columnindex_secondone] ) return list1, list2 def obtainaverage(list1,list2): resultlist1 = [] resultlist2 = [] unq = set(list1) unqlist = list(unq) for indexunqlist in range(0,len(unqlist)): templist = [] for indexlist1 in range(0,len(list1)): if list1[indexlist1]==unqlist[indexunqlist]: templist.append( list2[indexlist1]) resultlist1.append( list1[indexlist1] ) resultlist2.append( sum(templist)/len(templist) ) return resultlist1, resultlist2 def obtainmax(list1,list2): resultlist1 = [] resultlist2 = [] unq = set(list1) unqlist = list(unq) for indexunqlist in range(0,len(unqlist)): templist = [] for indexlist1 in range(0,len(list1)): if list1[indexlist1]==unqlist[indexunqlist]: templist.append( list2[indexlist1]) resultlist1.append( list1[indexlist1] ) resultlist2.append( max(templist) ) return resultlist1, resultlist2 def getlistsfromcolumnsinfile(fn,columnindex_firstone,columnindex_secondone): inF = open(fn,"r") l = inF.readlines() inF.close() list1 = [] list2 = [] for index in range(0,len(l)): aline = l[index] currentlist = aline.split(' ') list1.append( currentlist[columnindex_firstone] ) list2.append( currentlist[columnindex_secondone] ) return list1, list2 def obtainaverage(list1,list2): resultlist1 = [] resultlist2 = [] unq = set(list1) unqlist = list(unq) unqlist.sort() for indexunqlist in range(0,len(unqlist)): currentelement = unqlist[indexunqlist] templist = [] for index in range(0,len(list1)): if list1[index]==currentelement: templist.append( list2[index]) resultlist1.append( currentelement ) resultlist2.append( sum(templist)/len(templist) ) return resultlist1, resultlist2 def convertintstringlisttofloatlist(anintegerstringlist): afloatlist = [] for index in range(0,len(anintegerstringlist)): afloatlist.append( float(anintegerstringlist[index])) return afloatlist def convertbooleanstringlisttofloatlist(abooleanstringlist): afloatlist = [] for index in range(0,len(abooleanstringlist)): if abooleanstringlist[index]=='True': afloatlist.append( 1.0) else: if abooleanstringlist[index]=='False': afloatlist.append( 0.0) else: print('Failure in convertbooleanlisttofloatlist.') exit(-1) return afloatlist def convertfloatstringlisttofloatlist(afloatstringlist): afloatlist = [] for index in range(0,len(afloatstringlist)): afloatlist.append( float(afloatstringlist[index])) return afloatlist def doexperiments(): outF = open("first_part_of_experiments.txt","w") for tempindex1 in range(0,11): for tempindex2 in range(0,7): param1 = 1.0 + float(tempindex1)*5 param2 = 10**tempindex2 ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO = getdefaulttaskset1(param1,param2) starttime = datetime.datetime.now() flag,resp = doalmostexactschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) finishtime = datetime.datetime.now() timeittakes = finishtime - starttime line = str(param1) + ' ' + str(param2) + ' ' + str(flag) + ' ' + str(timeittakes.total_seconds()) print ( line ) outF.write( line) outF.write("\n") outF.flush() outF.close() list1,list2 = getlistsfromcolumnsinfile("first_part_of_experiments.txt",0,2) list1 = convertintstringlisttofloatlist( list1) list2 = convertbooleanstringlisttofloatlist( list2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('success') plt.xlabel('exec mult') plt.show() plt.savefig('first_part_of_experiments_success_exec_mult.pdf') list1,list2 = getlistsfromcolumnsinfile("first_part_of_experiments.txt",1,2) list1 = convertintstringlisttofloatlist( list1) list2 = convertbooleanstringlisttofloatlist( list2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('success') plt.xlabel('all mult') plt.show() plt.savefig('first_part_of_experiments_success_all_mult.pdf') list1,list2 = getlistsfromcolumnsinfile("first_part_of_experiments.txt",0,3) list1 = convertintstringlisttofloatlist( list1) list2 = convertfloatstringlisttofloatlist( list2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('time required') plt.xlabel('exec mult') plt.show() plt.savefig('first_part_of_experiments_timerequired_exec_mult.pdf') list1,list2 = getlistsfromcolumnsinfile("first_part_of_experiments.txt",1,3) list1 = convertintstringlisttofloatlist( list1) list2 = convertfloatstringlisttofloatlist( list2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('time required') plt.xlabel('all mult') plt.show() plt.savefig('first_part_of_experiments_timerequired_all_mult.pdf') outF.close() outF = open("second_part_of_experiments.txt","w") for tempindex1 in range(0,11): for tempindex2 in range(0,7): param1 = 1.0 + float(tempindex1)*0.1 param2 = 10**tempindex2 ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO = getdefaulttaskset2(param1,param2) starttime = datetime.datetime.now() flag,resp = doalmostexactschedulabilitytesting(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO) finishtime = datetime.datetime.now() timeittakes = finishtime - starttime line = str(param1) + ' ' + str(param2) + ' ' + str(flag) + ' ' + str(timeittakes) print ( line ) outF.write( line) outF.write("\n") outF.flush() outF.close() list1,list2 = getlistsfromcolumnsinfile("second_part_of_experiments.txt",0,2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('success') plt.ylabel('exec mult') plt.show() plt.savefig("second_part_of_experiments_success_exec_mult.txt") list1,list2 = getlistsfromcolumnsinfile("second_part_of_experiments.txt",1,2) list1,list2 = obtainaverage(list1,list2) plt.plot( list1,list2) plt.ylabel('success') plt.ylabel('all mult') plt.show() plt.savefig("second_part_of_experiments_success_all_mult.txt") list1,list2 = getlistsfromcolumnsinfile("second_part_of_experiments.txt",0,3) list1,list2 = obtainmax(list1,list2) plt.plot( list1,list2) plt.ylabel('time required') plt.ylabel('exec mult') plt.show() plt.savefig("second_part_of_experiments_time_required_exec_mult.txt") list1,list2 = getlistsfromcolumnsinfile("second_part_of_experiments.txt",1,3) list1,list2 = obtainmax(list1,list2) plt.plot( list1,list2) plt.ylabel('time required') plt.ylabel('all mult') plt.show() plt.savefig("second_part_of_experiments_time_required_all_mult.txt") def gettasksetfromGUIcomponent(): ntasks = int(textentryNumberoftasks.get()) nprocessors = int(textentryNumberofprocessors.get()) priorities = [None] * ntasks proc = [None] * ntasks periods = [None] * ntasks deadlines = [None] * ntasks V = [None] * ntasks executiontimes = [None] * ntasks pd = [None] * ntasks CO = [None] * ntasks executablecodefilename = [None] * ntasks inputsizeinbits = [None] * ntasks for i in range(1,ntasks+1): executiontimes[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) pd[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) CO[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) executablecodefilename[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) inputsizeinbits[i-1] = [None] * int(textentryNumberofsegments[i-1].get()) for i in range(1,ntasks+1): priorities[i-1] = int(textentryPriority[i-1].get()) proc[i-1] = int(textentryProc[i-1].get()) periods[i-1] = float(textentryPeriod[i-1].get()) deadlines[i-1] = float(textentryDeadline[i-1].get()) V[i-1] = [] for k in range(1,int(textentryNumberofsegments[i-1].get())+1): V[i-1].append( [i,k] ) for k in range(1,int(textentryNumberofsegments[i-1].get())+1): executiontimes[i-1][k-1] = float(textentryExecutiontime[i-1][k-1].get()) pd[i-1][k-1] = float(textentryDefaultprogress[i-1][k-1].get()) CO[i-1][k-1] = ast.literal_eval(textentryCorunnerspecification[i-1][k-1].get()) executablecodefilename[i-1][k-1] = textentryExecutablecodefilename[i-1][k-1].get() inputsizeinbits[i-1][k-1] = int(textentryInputsizeinbits[i-1][k-1].get()) return ntasks, nprocessors, priorities, proc, periods, deadlines, V, executiontimes, pd, CO, executablecodefilename, inputsizeinbits # type_of_creation = 0 means entirely new; 1 means through mutation; 2 means through crossover def create_bytearray_through_single_bitflip(arr,bitindex): newarr = bytearray( arr) byteindex = bitindex // 8 local_bit_index = bitindex % 8 newarr[byteindex] = newarr[byteindex] ^ (1 << local_bit_index) return newarr def create_bytearray_through_crossover(arr1,arr2,crossover_bitindex): if (len(arr1)!=len(arr2)): print("Error in do_cross_over_on_bytearray") exit(-1) newarr = bytearray( arr1) byteindex_of_crossover = crossover_bitindex // 8 local_bit_index_of_crossover = crossover_bitindex % 8 mask_lower_bits = (1 << (local_bit_index_of_crossover+1))-1 mask_upper_bits = ~mask_lower_bits newarr[byteindex_of_crossover] = (newarr[byteindex_of_crossover] & mask_upper_bits) | (mask_lower_bits & arr2[byteindex_of_crossover]) for byi in range(byteindex_of_crossover+1,len(arr2)): newarr[byi] = arr2[byi] return newarr def create_randomize_list_of_bytes(nbits_for_input): list_of_bytes = [0] * (nbits_for_input//8) for byteindex in range(0,nbits_for_input//8): for local_bit_index in range(0,8): if (random.random()<=0.5): list_of_bytes[byteindex] = list_of_bytes[byteindex] | (1 << local_bit_index) return list_of_bytes def get_fn(iprime,kprime,index_of_input_to_single_segment): fn = "inp_" + str(iprime) + "_" + str(kprime) + "_" + str(index_of_input_to_single_segment) + ".dat" return fn def write_bytearray_to_file(iprime,kprime,index_of_input_to_single_segment,arr): fn = get_fn(iprime,kprime,index_of_input_to_single_segment) f = open(fn, "wb") f.write(arr) f.close() def read_bytearray_from_file(iprime,kprime,index_of_input_to_single_segment): fn = get_fn(iprime,kprime,index_of_input_to_single_segment) f = open(fn, "rb") arr = f.read() f.close() return arr def generate_input_file_for_specific_segment_from_nothing(iprime,kprime,nbits_for_input,index_tocreate): list_of_bytes = create_randomize_list_of_bytes(nbits_for_input) arr = bytearray(list_of_bytes) write_bytearray_to_file(iprime,kprime,index_tocreate,arr) def generate_input_file_for_specific_segment_through_mutation(iprime,kprime,nbits_for_input,lb_exists,ub_exists,index_tocreate): exists_index = random.randint(lb_exists,ub_exists) oldarr = read_bytearray_from_file(iprime,kprime,exists_index) bitindex = random.randint(0,nbits_for_input-1) arr = create_bytearray_through_single_bitflip(oldarr,bitindex) write_bytearray_to_file(iprime,kprime,index_tocreate,arr) def generate_input_file_for_segment_through_crossover(iprime,kprime,nbits_for_input,lb_exists,ub_exists,index_tocreate): exists_index1 = random.randint(lb_exists,ub_exists) exists_index2 = random.randint(lb_exists,ub_exists) while (exists_index1==exists_index2): exists_index2 = random.randint(lb_exists,ub_exists) oldarr1 = read_bytearray_from_file(iprime,kprime,exists_index1) oldarr2 = read_bytearray_from_file(iprime,kprime,exists_index2) crossover_bitindex = random.randint(0,nbits_for_input-1) arr = create_bytearray_through_crossover(oldarr1,oldarr2,crossover_bitindex) write_bytearray_to_file(iprime,kprime,index_tocreate,arr) def generate_input_file_for_specific_segment(iprime,kprime,nbits_for_input,index_tocreate,type_of_creation,lb_exists,ub_exists): if (type_of_creation in [0,1,2]): if type_of_creation==0: generate_input_file_for_specific_segment_from_nothing( iprime,kprime,nbits_for_input,index_tocreate) if type_of_creation==1: generate_input_file_for_specific_segment_through_mutation(iprime,kprime,nbits_for_input,lb_exists,ub_exists,index_tocreate) if type_of_creation==2: generate_input_file_for_segment_through_crossover( iprime,kprime,nbits_for_input,lb_exists,ub_exists,index_tocreate) else: print("Error in generate_input_file_for_specific_segment") exit(-1) def generate_input_files_for_each_segment_separately(segmentset,lb_tocreate,ub_tocreate,inputsizeinbits,type_of_creation,lb_exists,ub_exists): for seg in segmentset: for index_tocreate in range(lb_tocreate,ub_tocreate+1): generate_input_file_for_specific_segment(gettaskidfromsegment(seg),getsegidfromsegment(seg),inputsizeinbits[gettaskidfromsegment(seg)-1][getsegidfromsegment(seg)-1],index_tocreate,type_of_creation,lb_exists,ub_exists) def read_floatingpoint_from_file(measurementfn): f = open(measurementfn, "r") s = f.read() myfloat = float(s) f.close() return myfloat def fill_executiontime_for_population_list(i,k,cor,priorities,proc,executablecodefilename,population_list, counter): n_replication = 3 for replication_index in range(0,n_replication): for index_within_population in range(0,len(population_list)): commandstr = "./measureexecutiontime " for corindex in range(0,len(cor)): seg = cor[corindex] iprime = gettaskidfromsegment(seg) kprime = getsegidfromsegment(seg) execfn = executablecodefilename[iprime-1][kprime-1] inpfn = get_fn(iprime,kprime,population_list[index_within_population][corindex]) commandstr = commandstr + " " + execfn + " " + inpfn + " " + str(priorities[iprime-1]) + " " + str(proc[iprime-1]) + " " execfn = executablecodefilename[i-1][k-1] corindex = len(cor) inpfn = get_fn(i,k,population_list[index_within_population][corindex]) commandstr = commandstr + " " + execfn + " " + inpfn + " " + str(priorities[i-1]) + " " + str(proc[i-1]) + " " print(" " + commandstr) counter = counter + 1 measurementfn = "measuredtime_" + str(counter) + ".txt" commandstr = commandstr + " > " + measurementfn os.system(commandstr) # time.sleep(0.1) temp_measured_execution_time = read_floatingpoint_from_file(measurementfn) population_list[index_within_population][len(cor)+2].append(temp_measured_execution_time) for index_within_population in range(0,len(population_list)): population_list[index_within_population][len(cor)+1] = statistics.median(population_list[index_within_population][len(cor)+2]) population_list = sorted(population_list,key=itemgetter(len(cor)+1),reverse=True) return counter def generate_an_individual_in_population_list_from_nothing(population_list,i,k,cor,n_inp_for_each_segment): new_individual = [] for corindex in range(0,len(cor)+1): new_individual.append( random.randint(0,n_inp_for_each_segment-1) ) new_individual.append( -1.0 ) new_individual.append( [] ) population_list.append(new_individual) def generate_an_individual_in_population_list_through_mutation(population_list,i,k,cor,n_inp_for_each_segment): old_index1 = random.randint(0,len(population_list)-1) old_individual1 = population_list[old_index1] mutate_corindex = random.randint(0,len(cor)) mutate_value = random.randint(0,n_inp_for_each_segment-1) new_individual = [] for corindex in range(0,len(cor)+1): if (corindex==mutate_corindex): new_individual.append( mutate_value ) else: new_individual.append( old_individual1[corindex] ) new_individual.append( -1.0 ) new_individual.append( [] ) population_list.append(new_individual) def generate_an_individual_in_population_list_through_crossover(population_list,i,k,cor,n_inp_for_each_segment): old_index1 = random.randint(0,len(population_list)-1) old_index2 = random.randint(0,len(population_list)-1) while (old_index1==old_index2): old_index2 = random.randint(0,len(population_list)-1) old_individual1 = population_list[old_index1] old_individual2 = population_list[old_index2] crossover_corindex = random.randint(0,len(cor)) new_individual = [] for corindex in range(0,len(cor)+1): if (corindex<=crossover_corindex): new_individual.append( old_individual1[corindex] ) else: new_individual.append( old_individual2[corindex] ) new_individual.append( -1.0 ) new_individual.append( [] ) population_list.append(new_individual) def generate_an_individual_in_population_list(population_list,i,k,cor,type_of_creation,n_inp_for_each_segment): if (type_of_creation in [0,1,2]): if type_of_creation==0: generate_an_individual_in_population_list_from_nothing( population_list,i,k,cor,n_inp_for_each_segment) if type_of_creation==1: generate_an_individual_in_population_list_through_mutation( population_list,i,k,cor,n_inp_for_each_segment) if type_of_creation==2: generate_an_individual_in_population_list_through_crossover(population_list,i,k,cor,n_inp_for_each_segment) else: print("Error in generate_an_individual_in_population_list") exit(-1) def generate_individuals_in_population_list(population_list,i,k,cor,number_of_elements_to_add,type_of_creation,n_inp_for_each_segment): for index in range(0,number_of_elements_to_add): generate_an_individual_in_population_list(population_list,i,k,cor,type_of_creation,n_inp_for_each_segment) def prune_population_list(population_list,max_allowed_number_of_individuals_in_population): while (len(population_list)>max_allowed_number_of_individuals_in_population): population_list.pop() def obtainparametersempirically_executiontime_for_segment_of_task_and_segmentset_GA(i,k,cor,ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits): counter = 0 n_inp_for_each_segment = 10 generate_input_files_for_each_segment_separately(cor+[[i,k]],0,n_inp_for_each_segment-1,inputsizeinbits,0,-1,-1) population_list = [] target_population_size = 100 generate_individuals_in_population_list(population_list,i,k,cor,target_population_size,0,n_inp_for_each_segment) counter = fill_executiontime_for_population_list(i,k,cor,priorities,proc,executablecodefilename,population_list,counter) for generation_index in range(1,5): generate_input_files_for_each_segment_separately(cor+[[i,k]],n_inp_for_each_segment+0, n_inp_for_each_segment+(n_inp_for_each_segment-1), inputsizeinbits,0,0,n_inp_for_each_segment-1) generate_input_files_for_each_segment_separately(cor+[[i,k]],n_inp_for_each_segment+n_inp_for_each_segment, n_inp_for_each_segment+(2*n_inp_for_each_segment-1),inputsizeinbits,1,0,n_inp_for_each_segment-1) generate_input_files_for_each_segment_separately(cor+[[i,k]],n_inp_for_each_segment+2*n_inp_for_each_segment,n_inp_for_each_segment+(3*n_inp_for_each_segment-1),inputsizeinbits,2,0,n_inp_for_each_segment-1) n_inp_for_each_segment = n_inp_for_each_segment + 3*n_inp_for_each_segment generate_individuals_in_population_list(population_list,i,k,cor,target_population_size,0,n_inp_for_each_segment) generate_individuals_in_population_list(population_list,i,k,cor,target_population_size,1,n_inp_for_each_segment) generate_individuals_in_population_list(population_list,i,k,cor,target_population_size,2,n_inp_for_each_segment) counter = fill_executiontime_for_population_list(i,k,cor,priorities,proc,executablecodefilename,population_list, counter) prune_population_list(population_list,target_population_size) return population_list[0][len(cor)+1] def obtainparametersempirically_for_a_given_segment(i,k,ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits): executiontimes_for_this_task = obtainparametersempirically_executiontime_for_segment_of_task_and_segmentset_GA(i,k,[],ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits) print("i,k") print(i,k) print("executiontimes_for_this_task") print(executiontimes_for_this_task) CO_for_this_task = [] relevantsegmentsets = [ segmentset for segmentset in generate_setofsegmentsets_regardless_of_victimtask(1,ntasks,nprocessors,priorities,proc,V) if segmentsetincludesgivensegment(segmentset,i,k) ] for segmentset in relevantsegmentsets: cor = obtaincorunnerset(i,k,segmentset) print("cor") print(cor) if (len(cor)>=1): executiontime_with_corunners = obtainparametersempirically_executiontime_for_segment_of_task_and_segmentset_GA(i,k,cor,ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits) print("executiontime_with_corunners") print(executiontime_with_corunners) lb_speed = executiontimes_for_this_task / executiontime_with_corunners if (lb_speed>1.0): print("Warning: lb_speed > 1. i = " + str(i) + " k = " + str(k) + " This is not necessarily an error but it is odd.") lb_speed = 1.0 CO_for_this_task.append([cor,lb_speed]) return executiontimes_for_this_task,CO_for_this_task def obtainparametersempirically(): ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits = gettasksetfromGUIcomponent() for i in range(1,ntasks+1): for k in range(1,len(V[i-1])+1): executiontimes[i-1][k-1], CO[i-1][k-1] = obtainparametersempirically_for_a_given_segment(i,k,ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits) setGUIcomponentsbasedontaskset(ntasks,nprocessors,priorities,proc,periods,deadlines,V,executiontimes,pd,CO,executablecodefilename,inputsizeinbits) random.seed(123) bottomframe1=Frame(bottomframe) bottomframe1.pack(side=TOP) bottomframe2=Frame(bottomframe) bottomframe2.pack(side=BOTTOM) Label(bottomframe1, text=" ", justify=LEFT).pack(side=TOP) butloadtasksetfromfile = Button(bottomframe2,text="Load taskset from file taskset.txt", padx = 20, command=loadtasksetfromfile) butsavetasksettofile = Button(bottomframe2,text="Save taskset to file taskset.txt", padx = 20, command=savetasksettofile) but = Button(bottomframe2,text="Do schedulability analysis", padx = 20, command=genericdoschedulabilityanalysis) but4 = Button(bottomframe2,text="Options...", padx = 20, command=options) but5 = Button(bottomframe2,text="Do experiments...", padx = 20, command=doexperiments) but6 = Button(bottomframe2,text="Obtain parameters empirically", padx = 20, command=obtainparametersempirically) butloadtasksetfromfile.pack(side=LEFT) butsavetasksettofile.pack(side=LEFT) but.pack(side=LEFT) but4.pack(side=LEFT) but5.pack(side=LEFT) but6.pack(side=LEFT) setGUIcomponentstodefaulttaskset() window.mainloop() # // how to compile it: # // gcc -o measureexecutiontime measureexecutiontime.c -pthread # # #define _GNU_SOURCE # #include # #include # #include # #include # #include # #include # #include # #include # #include # #include # # #include # #include # #include # # #include # # #include # # #include # # #include # #include # # #include # #include # # #define MAX_ALLOWED_NUMBER_OF_TASKS 1000 # # int childfinished[MAX_ALLOWED_NUMBER_OF_TASKS]; // this does not store the parent; that is, it will have only ntasks-1 elements # pid_t childpids[MAX_ALLOWED_NUMBER_OF_TASKS]; // this does not store the parent; that is, it will have only ntasks-1 elements # # char* get_execfn_str_from_argv(int index, char** argv) { # return argv[1+4*index]; # } # char* get_inpfn_str_from_argv(int index, char** argv) { # return argv[1+4*index+1]; # } # char* get_priorities_str_from_argv(int index, char** argv) { # return argv[1+4*index+2]; # } # char* get_proc_str_from_argv(int index, char** argv) { # return argv[1+4*index+3]; # } # int get_priorities_int_from_argv(int index, char** argv) { # int temp; # int temp2; # temp2 = sscanf(get_priorities_str_from_argv(index,argv),"%d",&temp); # if (temp2==1) { # return temp; # } else { # fprintf(stderr,"Error. Tried to parse a string and expected an integer to be interpreted as priority. This parsing failed.\n"); fflush(stderr); # exit(-1); # } # } # int get_proc_int_from_argv(int index, char** argv) { # int temp; # int temp2; # temp2 = sscanf(get_proc_str_from_argv(index,argv),"%d",&temp); # if (temp2==1) { # return temp; # } else { # fprintf(stderr,"Error. Tried to parse a string and expected an integer to be interpreted as proc. This parsing failed.\n"); fflush(stderr); # exit(-1); # } # } # # void setRTpriority(int OS_prio) { # int ret; struct sched_param param; # param.sched_priority = OS_prio; # ret = sched_setscheduler( 0, SCHED_FIFO, ¶m); # if (ret!=0) { # fprintf(stderr,"sched_setscheduler failed. ret = %d\n", ret); fflush(stderr); # fprintf(stderr,"check whether you have super user privileges\n"); fflush(stderr); # exit(-1); # } # } # # void setprocessoraffinity(int OS_cpu) { # cpu_set_t mask; int ret; # CPU_ZERO(&mask); # CPU_SET(OS_cpu,&mask); # ret = sched_setaffinity( 0, sizeof(mask), &mask); # if (ret!=0) { # fprintf(stderr,"sched_setaffinity failed. ret = %d\n", ret); fflush(stderr); # exit(-1); # } # } # # int get_OS_prio_from_taskset_prio(int tasksetprio) { # int OS_prio; # OS_prio = 32 + tasksetprio; # return OS_prio; # } # # int get_OS_proc_from_taskset_proc(int tasksetproc) { # int OS_proc; # OS_proc = tasksetproc-1; # return OS_proc; # } # # unsigned long long diff_ns_timespec(struct timespec* x, struct timespec* y) { # unsigned long long abillion = 1000000000; # unsigned long long u; # u = x->tv_sec; # u = u * abillion; # u = u + x->tv_nsec; # unsigned long long v; # v = y->tv_sec; # v = v * abillion; # v = v + y->tv_nsec; # return u-v; # } # double diff_s_timespec(struct timespec* x, struct timespec* y) { # unsigned long long abillion = 1000000000; # unsigned long long t; # unsigned long long tsec; # unsigned long long tnsec; # double t_as_double_secondpart; # double t_as_double_nsecondpart; # double t_as_double; # t = diff_ns_timespec( x, y); # tsec = t / abillion; # tnsec = t % abillion; # t_as_double_secondpart = tsec; # t_as_double_nsecondpart = tnsec; # t_as_double_nsecondpart = t_as_double_nsecondpart / abillion; # t_as_double = t_as_double_secondpart + t_as_double_nsecondpart; # if (t_as_double<0) { fprintf(stderr,"Error diff_s_timespec. t_as_double=%lf\n", t_as_double); fflush(stderr); } # return t_as_double; # } # # void set_allow_new_job() { # int fd; char c; int n_characters_written; # remove("allow_new_job.dat"); # fd = open("allow_new_job.dat", O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR ); # if (fd==-1) { # fprintf(stderr,"There was an error in set_allow_new_job when opening.\n"); fflush(stderr); exit(-1); # } # c = 1; # n_characters_written = write(fd,&c,1); # if (n_characters_written!=1) { # fprintf(stderr,"There was an error in set_allow_new_job when writing. n_characters_written = %d\n", n_characters_written); fflush(stderr); exit(-1); # } # close(fd); # } # int is_new_job_allowed() { # int fd; char c; int n_characters_read; # fd = open("allow_new_job.dat", O_RDONLY); # if (fd==-1) { # fprintf(stderr,"There was an error in is_new_job_allowed when opening.\n"); fflush(stderr); exit(-1); # } # n_characters_read = read(fd,&c,1); # if (n_characters_read!=1) { # fprintf(stderr,"There was an error in is_new_job_allowed when reading. n_characters_read = %d\n", n_characters_read); fflush(stderr); exit(-1); # } # close(fd); # if (c==1) { # return 1; # } else if (c==0) { # return 0; # } else { # fprintf(stderr,"There was an error in is_new_job_allowed when reading. Unexpected character read.\n"); fflush(stderr); exit(-1); # } # } # void set_disallow_new_job() { # int fd; char c; int n_characters_written; # fd = open("allow_new_job.dat", O_WRONLY); # if (fd==-1) { # fprintf(stderr,"There was an error in set_disallow_new_job when opening.\n"); fflush(stderr); exit(-1); # } # c = 0; # n_characters_written = write(fd,&c,1); # if (n_characters_written!=1) { # fprintf(stderr,"There was an error in set_disallow_new_job when writing. characters_written = %d\n", n_characters_written); fflush(stderr); exit(-1); # } # close(fd); # } # # char commandstr[20000]; # # int main(int argc, char** argv) { # int OS_prio; # int OS_cpu; # struct timespec mybegin; # struct timespec myend; # int status_clock_gettime_begin; # int status_clock_gettime_end; # unsigned long long mydifference; # double t; # int iterator; # int ntasks; # int index; # int pid; # int w_status; # int allchildrenfinished; # int continueflag; # if (argc==0) { # fprintf(stderr,"Error: This should not happen. zero arguments.\n"); fflush(stderr); # exit(-1); # } # if (argc==1) { # fprintf(stderr,"Error. There was just a single argument and it was %s.\n", argv[0]); fflush(stderr); # exit(-1); # } # if ((argc%4)!=1) { # fprintf(stderr,"Error. Incorrect number of arguments. argc=%d.\n", argc); fflush(stderr); # exit(-1); # } # if (argc>4*MAX_ALLOWED_NUMBER_OF_TASKS+1) { # fprintf(stderr,"The number of arguments is too large. We can't handle this. argc=%d.\n", argc); fflush(stderr); # exit(-1); # } # set_allow_new_job(); # ntasks = (argc-1)/4; # # for (index=0;index