aboutsummaryrefslogtreecommitdiff
path: root/scripts/loop.py
blob: f7b82bfffcc1257bc358813afe8941dd42bdeaac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#!/usr/bin/env python3
import os
import sys
import subprocess
import signal
from threading import Thread
from threading import Lock
from threading import Event

from conf import conf
from conf import sf
import initialize
import configurations
import kernel
import boot
import exceptions
import database
import utils

__confs_unmeasured__ = []
__confs_prepared__ = []

def prepare():
	"""Prepare for measuring
	Outcome is Linux image for generated configuration."""
	def get():
		confs = dtb.get_unmeasured()
		for pr in __confs_prepared__:
			for cn in confs.copy():
				if pr == cn.hash:
					confs.remove(cn)
					break
		return confs
	print("Preparing new image.")
	global __confs_unmeasured__
	if len(__confs_unmeasured__) == 0:
		dtb = database.database()
		confs = get()
		if len(confs) == 0:
			configurations.generate()
			confs = get()
			if len(confs) == 0:
				raise exceptions.NoApplicableConfiguration()
		__confs_unmeasured__ = list(confs)
	con = __confs_unmeasured__.pop()
	kernel.config(con.config)
	img = kernel.make(con.hash)
	print("Prepared image: " + img)
	__confs_prepared__.append(con.hash)
	return img, con

def measure(kernelimg, con):
	print("Measuring " + con.hash)
	try:
		os.remove(sf(conf.jobfolder_linux_image))
	except FileNotFoundError:
		pass
	os.symlink(kernelimg, sf(conf.jobfolder_linux_image))
	boot.boot(con)
	print("Configuration '" + con.hash + "' measured.")
	__confs_prepared__.remove(con.hash)

# Multithread #
__conflist__ = []
__listlock__ = Lock()
__preparethreadEvent__ = Event()
__measurethreadEvent__ = Event()

class prepareThread(Thread):
	global __preparethread__
	global __measurethread__
	def __init__(self, name='prepare'):
		Thread.__init__(self, name=name)
	def run(self):
		print('Prepare thread start')
		while not __terminate__:
			try:
				img, config = prepare()
			except exceptions.NoApplicableConfiguration:
				return
			__listlock__.acquire()
			__conflist__.append((img, config))
			__preparethreadEvent__.set()
			if len(__conflist__) > conf.multithread_buffer:
				__listlock__.release()
				print('Prepare thread suspended')
				__measurethreadEvent__.wait()
				print('Prepare thread waken')
			else:
				__listlock__.release()
			__measurethreadEvent__.clear()
		print('Prepare thread stop')

class measureThread(Thread):
	global __preparethread__
	global __measurethread__
	def __init__(self, name='measure'):
		Thread.__init__(self, name=name)
	def run(self):
		print('Measure thread start')
		while not __terminate__:
			__listlock__.acquire()
			if len(__conflist__) <= 0:
				__listlock__.release()
				print('Measure thread suspended')
				__preparethreadEvent__.wait()
				print('Measure thread waken')
				__listlock__.acquire()
			__preparethreadEvent__.clear()
			img, config = __conflist__.pop()
			__listlock__.release()
			__measurethreadEvent__.set()
			measure(img, config)
		print('Measure thread stop')

__preparethread__ = prepareThread()
__measurethread__ = measureThread()

# Start and sigterm handler #
def sigterm_handler(_signo, _stack_frame):
	global __terminate__
	__terminate__ = True
	if conf.multithread:
		__measurethreadEvent__.set()
		__preparethreadEvent__.set()

# Main loop and single thread #
__terminate__ = False
def loop():
	utils.dirtycheck()
	initialize.all()
	if conf.multithread:
		__preparethread__.start()
		__measurethread__.start()
	else:
		if conf.single_loop:
			img, config = prepare()
			measure(img, config)
		else:
			while not __terminate__:
				img, config = prepare()
				measure(img, config)

#################################################################################

if __name__ == '__main__':
	signal.signal(signal.SIGTERM, sigterm_handler)
	signal.signal(signal.SIGINT, sigterm_handler)
	loop()