]> rtime.felk.cvut.cz Git - linux-conf-perf.git/blob - scripts/loop.py
Fix thread cooperation in loop
[linux-conf-perf.git] / scripts / loop.py
1 #!/usr/bin/env python3
2 import os
3 import sys
4 import subprocess
5 import signal
6 from threading import Thread
7 from threading import Lock
8
9 from conf import conf
10 from conf import sf
11 import initialize
12 import configurations
13 import kernel
14 import boot
15 import exceptions
16 import database
17
18 __confs_unmeasured__ = []
19
20 def prepare():
21         """Prepare for measuring
22         Outcome is Linux image for generated configuration."""
23         global __confs_unmeasured__
24         if len(__confs_unmeasured__) == 0:
25                 dtb = database.database()
26                 confs = dtb.get_unmeasured()
27                 if len(confs) == 0:
28                         configurations.generate()
29                         confs = dtb.get_unmeasured()
30                         if len(confs) == 0:
31                                 raise exceptions.NoApplicableConfiguration()
32                 __confs_unmeasured__ = list(confs)
33         con = __confs_unmeasured__.pop()
34         kernel.config(con.cfile)
35         img = kernel.make(con.hash)
36         print("Prepared image: " + img)
37         return img, con
38
39 def measure(kernelimg, con):
40         try:
41                 os.remove(sf(conf.jobfolder_linux_image))
42         except FileNotFoundError:
43                 pass
44         os.symlink(kernelimg, sf(conf.jobfolder_linux_image))
45         boot.boot(con)
46         print("Configuration '" + con.hash + "' measured.")
47
48 # Threads #
49 __terminate__ = False
50 class mainThread(Thread):
51         def run(self):
52                 if conf.single_loop:
53                         img, config = prepare()
54                         measure(img, config)
55                 else:
56                         while not __terminate__:
57                                 img, config = prepare()
58                                 measure(img, config)
59
60 # Multithread section #
61 __conflist__ = set()
62 __listlock__ = Lock()
63
64 class prepareThread(Thread):
65         def __init__(self, name='prepare'):
66                 Thread.__init__(self, name=name)
67         def run(self):
68                 __listlock__.aquire()
69                 while not __terminate__ and len(__conflist__) <= conf.multithread_buffer:
70                         __listlock__.release()
71                         try:
72                                 img, config = prepare()
73                         except exceptions.NoApplicableConfiguration:
74                                 return
75                         __listlock__.aquire()
76                         __conflist__.add((img, config))
77                         if not __measurethread__.isActive():
78                                 __measurethread__.start()
79                 __listlock__.release()
80
81 class measureThread(Thread):
82         def __init__(self, name='measure'):
83                 Thread.__init__(self, name=name)
84         def run(self):
85                 __listlock__.aquire()
86                 while not __terminate__ and len(__conflist__) > 0:
87                         img, config = __conflist__.pop()
88                         __listlock__.release()
89                         if not __preparethread__.isActive():
90                                 __preparethread__.start()
91                         measure(img, config)
92                         __listlock__.aquire()
93                 __listlock__.release()
94
95 __preparethread__ = prepareThread()
96 __measurethread__ = measureThread()
97
98 # Start and sigterm handler #
99 def sigterm_handler(_signo, _stack_frame):
100         __terminate__ = True
101
102 def loop():
103         initialize.all()
104         global thr
105         thr = mainThread()
106         thr.start()
107         try:
108                 thr.join()
109         except KeyboardInterrupt:
110                 __terminate__ = True
111
112 #################################################################################
113
114 if __name__ == '__main__':
115         signal.signal(signal.SIGTERM, sigterm_handler)
116         loop()