from multiprocessing import Pool, cpu_count, freeze_support
import gui
import time
class Settings:
    def __init__(self):
        self.testtime = 60
        self.cycletime = 0.5
        self.stress = 1000
        self.calibrated = False
        self.cpucount = cpu_count()
        #self.oldtesttime = 60
        self.oldcycletime = 0.5
def stresser(stress, stresss):
    #if not y:
    #    y = x
    z = 10000
    for s in range(stress):
        for h in range(stress):
            z *= h
    return z

def calibrate(aimtime, takentime, settings, toleranz, hitcount):
    
    change = int(round((aimtime-takentime)*1500))
    #change = int(round((aimtime-takentime)*100)**3)
    print (change, toleranz)
    #change = change
    settings.stress += change
    if aimtime-toleranz > takentime:
        
        hitcount = 0
    elif aimtime+toleranz < takentime:
        #settings.stress -= change
        hitcount = 0
    else: hitcount += 1
    return hitcount

def calibration(settings):
    aimtime = settings.cycletime/2
    pool2 = Pool(settings.cpucount)
    calitime = 60
    if settings.cycletime > 1:
        calitime *= 2
    print (calitime)
    teststart = time.clock()
    toleranz = aimtime*0.05
    print (toleranz)
    hitcount = 0
    firstrun = True
    while 1:
        results = []
        start = time.clock()
        for x in range(settings.cpucount):
            results.append(
                pool2.apply_async(stresser, (settings.stress, settings.stress)))
        for result in results:
            result.get()
        end = time.clock()
        took = end-start
        print ("for",settings.stress," stress, ",hitcount,"hitcount",
               settings.cycletime-took,"pausetime",took,"runtime")
        pause = settings.cycletime-took
        if settings.stress < 0:
            print ("abort by failure")
            settings.calibrated = 3
            settings.stress = 1
            break
        if teststart + calitime < time.clock():
            print ("abort by time")
            settings.calibrated = 2
            break
        if firstrun:
            print (start)
        elif hitcount < 3:
            hitcount = calibrate(aimtime, took, settings, toleranz, hitcount)
        else:
            settings.calibrated = 1
            break
        if pause > 0:
            time.sleep(pause)
        firstrun = False
def test(settings, update_func):
    #aimtime = settings.cycletime/2
    pool2 = Pool(settings.cpucount)
    
    teststart = time.clock()
    #hitcount = 0
    runtime = 0
    #counter = 0
    print (settings.stress)
    while 1:
        results = []
        start = time.clock()
        for x in range(settings.cpucount):
            results.append(
                pool2.apply_async(stresser, (settings.stress,settings.stress,)))
        for result in results:
            result.get()
        end = time.clock()
        if teststart + settings.testtime < time.clock():
            break
        took = end-start
        pause = settings.cycletime-took
        #pause = settings.cycletime-time.clock()+start
        print (took, pause, took+pause)
        if pause > 0:
            time.sleep(pause)
        #counter += 1
        update_func(runtime+settings.cycletime)
        runtime = time.clock()-teststart
def run():
    global stress
    aimtime = cycletime/2
    print ("Processes :",cpucount)
    pool2 = Pool(cpucount)
    results = []
    toleranz = aimtime*0.05
    teststart = time.clock()
    done = 0
    hitcount = 0
    while 1:
        start = time.clock()
        for x in range(cpucount):
            results.append(
                pool2.apply_async(stresser, (stress,stress,)))
        for result in results:
            result.get()
        end = time.clock()
        took = end-start
        print (took, stress, hitcount)
        took = end-start
        pause = cycletime-took
        if pause > 0:
            time.sleep(pause)
        done += 1
        if hitcount < 3:
            stress, hitcount = calibrate(aimtime, took, stress, toleranz, hitcount)
        if teststart + testtime < time.clock():
            print ("done")
            break
    timetaken = time.clock()-teststart
    print ("time taken:",timetaken)
    print ("frequency:", done/timetaken)
if __name__ == "__main__":
    freeze_support()
    settings = Settings()
    gui.start(settings)
