]> rtime.felk.cvut.cz Git - linux-conf-perf.git/blob - scripts/loop.py
Add skeleton for kconfig2sat tool
[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 from threading import Event
9
10 from conf import conf
11 from conf import sf
12 import initialize
13 import configurations
14 import kernel
15 import boot
16 import exceptions
17 import database
18 import utils
19
20 __confs_unmeasured__ = []
21 __confs_prepared__ = []
22
23 def prepare():
24         """Prepare for measuring
25         Outcome is Linux image for generated configuration."""
26         def get():
27                 confs = dtb.get_unmeasured()
28                 for pr in __confs_prepared__:
29                         for cn in confs.copy():
30                                 if pr == cn.hash:
31                                         confs.remove(cn)
32                                         break
33                 return confs
34         print("Preparing new image.")
35         global __confs_unmeasured__
36         if len(__confs_unmeasured__) == 0:
37                 dtb = database.database()
38                 confs = get()
39                 if len(confs) == 0:
40                         configurations.generate()
41                         confs = get()
42                         if len(confs) == 0:
43                                 raise exceptions.NoApplicableConfiguration()
44                 __confs_unmeasured__ = list(confs)
45         con = __confs_unmeasured__.pop()
46         kernel.config(con.config)
47         img = kernel.make(con.hash)
48         print("Prepared image: " + img)
49         __confs_prepared__.append(con.hash)
50         return img, con
51
52 def measure(kernelimg, con):
53         print("Measuring " + con.hash)
54         try:
55                 os.remove(sf(conf.jobfolder_linux_image))
56         except FileNotFoundError:
57                 pass
58         os.symlink(kernelimg, sf(conf.jobfolder_linux_image))
59         boot.boot(con)
60         print("Configuration '" + con.hash + "' measured.")
61         os.remove(sf(conf.build_folder) + '/' + kernelimg)
62         __confs_prepared__.remove(con.hash)
63
64 # Multithread #
65 __conflist__ = []
66 __listlock__ = Lock()
67 __preparethreadEvent__ = Event()
68 __measurethreadEvent__ = Event()
69
70 class prepareThread(Thread):
71         global __preparethread__
72         global __measurethread__
73         def __init__(self, name='prepare'):
74                 Thread.__init__(self, name=name)
75         def run(self):
76                 print('Prepare thread start')
77                 while not __terminate__:
78                         try:
79                                 img, config = prepare()
80                         except exceptions.NoApplicableConfiguration:
81                                 return
82                         __listlock__.acquire()
83                         __conflist__.append((img, config))
84                         __preparethreadEvent__.set()
85                         if len(__conflist__) > conf.multithread_buffer:
86                                 __listlock__.release()
87                                 print('Prepare thread suspended')
88                                 __measurethreadEvent__.wait()
89                                 print('Prepare thread waken')
90                         else:
91                                 __listlock__.release()
92                         __measurethreadEvent__.clear()
93                 print('Prepare thread stop')
94
95 class measureThread(Thread):
96         global __preparethread__
97         global __measurethread__
98         def __init__(self, name='measure'):
99                 Thread.__init__(self, name=name)
100         def run(self):
101                 print('Measure thread start')
102                 while not __terminate__:
103                         __listlock__.acquire()
104                         if len(__conflist__) <= 0:
105                                 __listlock__.release()
106                                 print('Measure thread suspended')
107                                 __preparethreadEvent__.wait()
108                                 print('Measure thread waken')
109                                 __listlock__.acquire()
110                         __preparethreadEvent__.clear()
111                         img, config = __conflist__.pop()
112                         __listlock__.release()
113                         __measurethreadEvent__.set()
114                         measure(img, config)
115                 print('Measure thread stop')
116
117 __preparethread__ = prepareThread()
118 __measurethread__ = measureThread()
119
120 # Start and sigterm handler #
121 def sigterm_handler(_signo, _stack_frame):
122         global __terminate__
123         __terminate__ = True
124         if conf.multithread:
125                 __measurethreadEvent__.set()
126                 __preparethreadEvent__.set()
127
128 # Main loop and single thread #
129 __terminate__ = False
130 def loop():
131         utils.dirtycheck()
132         initialize.all()
133         if conf.multithread:
134                 __preparethread__.start()
135                 __measurethread__.start()
136         else:
137                 if conf.single_loop:
138                         img, config = prepare()
139                         measure(img, config)
140                 else:
141                         while not __terminate__:
142                                 img, config = prepare()
143                                 measure(img, config)
144
145 #################################################################################
146
147 if __name__ == '__main__':
148         signal.signal(signal.SIGTERM, sigterm_handler)
149         signal.signal(signal.SIGINT, sigterm_handler)
150         loop()