source: research/2008-displacement/main-cpushare @ 2763

Last change on this file since 2763 was 2288, checked in by Sam Hocevar, 12 years ago
  • Add mode 8, for the very first graphic in the paper.
  • Add results for mode 8 in part0/lena-values.txt.
  • Make the bytecode version use less memory.
  • Property svn:executable set to *
File size: 4.2 KB
Line 
1#! /usr/bin/python
2
3import os, struct, sys, random
4
5import gd
6
7from cpushare.proto_const import *
8from cpushare.exceptions import CompilationError
9
10# Our input data
11source = False
12result = False
13todo = 0
14
15# Parse command line
16if len(sys.argv) < 4:
17    print 'Usage: %s <buy_order.cpu> -<mode> [image list]' % (sys.argv[0],)
18    sys.exit(-1)
19mode = sys.argv[2]
20done = 0
21source = sys.argv[3:]
22result = [False] * len(source)
23
24class buy_state_machine_class(object):
25    buy_api = '0.0.0'
26
27    w, h = 0, 0
28    index = -1
29    answer = ''
30
31    def __init__(self, protocol):
32        self.protocol = protocol
33        self.handler = self.stringReceived
34
35    def start(self):
36        global mode, todo, source
37        gd.gdMaxColors = 256 * 256 * 256
38        while todo < len(source):
39            try:
40                self.index = todo
41                im = gd.image(source[self.index])
42                break
43            except:
44                todo += 1
45                self.result = "Error\n"
46        if todo >= len(source):
47            return # We're finished... FIXME: isn't the transaction stuck?
48        todo += 1
49        # Send argument count
50        self.protocol.sendString(PROTO_SECCOMP_FORWARD + chr(3))
51        # Send arguments
52        msg = chr(3)
53        msg += "bytecode\0"
54        msg += mode + "\0"
55        msg += source[self.index] + "\0"
56        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
57        # Send image size
58        (self.w, self.h) = (w, h) = im.size()
59        print 'sending %s (%dx%d)' % (source[self.index], w, h)
60        msg = chr(w / 256) + chr(w % 256) + chr(h / 256) + chr(h % 256)
61        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
62        # Send image contents
63        msg = ''
64        for y in range(h):
65            for x in range(w):
66                p = im.getPixel((x, y))
67                rgb = im.colorComponents(p)
68                msg += chr(rgb[1]) # use green coordinate
69        self.protocol.sendString(PROTO_SECCOMP_FORWARD + msg)
70        print '%s bytes sent' % len(msg)
71
72    def stringReceived(self, string):
73        control = string[0]
74        data = string[1:]
75
76        if control == PROTO_SECCOMP_FORWARD:
77            self.answer += data
78            if ord(self.answer[-1]) != 0:
79                return
80            global done, result
81            result[self.index] = self.answer[:-1]
82            print self.answer[:-1],
83            self.protocol.sendString(PROTO_SECCOMP_SUCCESS)
84            done += 1
85            if done < len(source):
86                return
87            from twisted.internet import reactor
88            reactor.stop()
89        elif control == PROTO_SECCOMP_SIGNAL:
90            print 'Checkpoint starting'
91        elif control == PROTO_LOG:
92            print repr(data)
93        else:
94            if control == PROTO_SECCOMP_SUCCESS:
95                pass
96            elif control == PROTO_SECCOMP_FAILURE:
97                status = struct.unpack('!i', data)[0]
98                exit_code = status >> 8
99                signal = status & 0xff
100                s = 'Seccomp failure: status %d, exit_code %d, signal %d.' % \
101                      (status, exit_code, signal)
102                print s
103            else:
104                s = 'Unknown failure %d - %s' % (ord(control), repr(string))
105                self.protocol.sendString(PROTO_SECCOMP_FAILURE + s)
106                print s
107            self.protocol.sendString(PROTO_SECCOMP_FAILURE)
108            self.protocol.transport.loseConnection()
109
110    def connectionLost(self):
111        pass
112
113# Build local module
114from new import module
115m = module('cpushare_buy')
116
117# Create bytecode -- i686 only
118from cpushare.seccomp_gen import seccomp_gen_class
119m.seccomp_gen_hash = {}
120m.seccomp_gen_hash['i686'] = seccomp_gen_class('bytecode', 'i686')
121m.seccomp_gen_hash['i686'].heap_kbytes = 1
122m.seccomp_gen_hash['i686'].stack_kbytes = 1
123
124# Estimate of the max number of seconds that the sell client
125# will take to checkpoint and send its state back to us
126m.checkpoint_sec = 10
127
128# Our buying state machine
129m.buy_state_machine_class = buy_state_machine_class
130
131# Append our module to the global list of modules
132sys.modules['cpushare_buy'] = m
133
134# Build a new command line and run twistd
135sys.argv = [sys.argv[0], '-q', '-n', 'cpushare', '--order', sys.argv[1]]
136from twisted.scripts.twistd import run
137run()
138
Note: See TracBrowser for help on using the repository browser.