예제 #1
0
    def __init__(self, qmp, event):
        super().__init__()
        self.running = qmp.running

        self.totalRunning = 0
        self.total = 0

        self.qmp = qmp
        self.qmp.timeMetric.connect(self.handle_sample)

        self.kill_event = event

        self.data = 0

        self.lim = 10
        self.window = 10
        self.rate_value = 10

        self.sem = QSemaphore(1)

        self.all_min_val = -1
        self.all_max_val = -1

        self.plot_min_val = -1
        self.plot_max_val = -1

        self.initui()
예제 #2
0
    def __init__(self, qmp, parent):
        super().__init__()
        self.qmp = qmp
        self.qmp.memoryMap.connect(self.update_tree)

        self.parent = parent

        self.tree_sem = QSemaphore(1)
        self.sending_sem = QSemaphore(
            1)  # used to prevent sending too many requests at once

        self.init_ui()
        self.get_map()
예제 #3
0
class SamplingThread(QThread):
    sample = Signal()

    def __init__(self):
        super().__init__()
        self.sem = QSemaphore()
        self.rate = 10

    def run(self):
        while True:
            if self.sem.tryAcquire(1, (1.0 / self.rate) * 1000):
                break
            self.sample.emit()

    def end_thread(self):
        self.sem.release()

    def update(self, rate):
        self.rate = rate
예제 #4
0
class MyThread(QThread):
    timing_signal = Signal(bool) 

    def __init__(self, mem):
        super().__init__()
        mem.kill_signal.connect(self.end)    
        self.sem = QSemaphore() 
        self.running = True
    def run(self):
        while True:
            if self.sem.tryAcquire(1, 1000): # try to acquire and wait 1s to try to acquire
                break
            if self.running:
                self.timing_signal.emit(True)

    def end(self, b):
        self.sem.release()

    def halt(self, running):
        self.running = running
예제 #5
0
파일: PortImpl.py 프로젝트: ifm/nexxT
class InterThreadConnection(QObject):
    """
    Helper class for transmitting data samples between threads
    """
    transmitInterThread = Signal(object, QSemaphore)

    def __init__(self, qthread_from):
        super().__init__()
        self.moveToThread(qthread_from)
        self.semaphore = QSemaphore(1)
        self._stopped = True

    def receiveSample(self, dataSample):
        """
        Receive a sample, called in the source's thread. Uses a semaphore to avoid buffering infinitely.
        :param dataSample: the sample to be received
        :return: None
        """
        self._receiveSample(dataSample)

    @handleException
    def _receiveSample(self, dataSample):
        assert QThread.currentThread() is self.thread()
        while True:
            if self._stopped:
                logger.info(
                    "The inter-thread connection is set to stopped mode; data sample discarded."
                )
                break
            if self.semaphore.tryAcquire(1, 500):
                self.transmitInterThread.emit(dataSample, self.semaphore)
                break

    def setStopped(self, stopped):
        """
        When the connection is stopped (the default), acquire will not deadlock and there is a warning when samples are
        transmitted, samples are not forwarded to the input port in this case. Note: This method is thread safe and
        may be called from any thread.
        :return:
        """
        self._stopped = stopped
예제 #6
0
    def __init__(self, qmp, base=0, max=constants['block_size']):
        super().__init__()

        self.flag = False
        self.threshold = 2048 # number of resident bytes

        self.qmp = qmp
        self.init_ui()

        self.baseAddress = base
        self.maxAddress = self.baseAddress

        self.delta = 4 # adds a small buffer area for scrolling action to happen

        self.sem = QSemaphore(1) # semaphore for controlling access to the enabling / disabling of the scroll listening
        self.pos = self.chr_display.verticalScrollBar().value()

        self.highlight_sem = QSemaphore(1) # semaphore for controlling access to highlighting state
        self.is_highlighted = False
        self.highlight_addr = 0

        self.endian = Endian.little
        self.endian_sem = QSemaphore(1)

        self.hash = randint(0, 0xfffffffffffffff)

        icon = QIcon('package/icons/nasa.png')
        self.setWindowIcon(icon)

        self.max_size = 0xfffffffffffffff

        self.qmp.pmem.connect(self.update_text)
        self.grab_data(val=self.baseAddress, size=min(max, constants['block_size'] + base)-self.baseAddress)

        self.t = MyThread(self)
        self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True))
        self.qmp.stateChanged.connect(self.t.halt)
        self.t.running = self.qmp.running
        self.t.start()

        self.show()
예제 #7
0
 def __init__(self, mem):
     super().__init__()
     mem.kill_signal.connect(self.end)    
     self.sem = QSemaphore() 
     self.running = True
예제 #8
0
class MemDumpWindow(QWidget):

    kill_signal = Signal(bool)

    def __init__(self, qmp, base=0, max=constants['block_size']):
        super().__init__()

        self.flag = False
        self.threshold = 2048 # number of resident bytes

        self.qmp = qmp
        self.init_ui()

        self.baseAddress = base
        self.maxAddress = self.baseAddress

        self.delta = 4 # adds a small buffer area for scrolling action to happen

        self.sem = QSemaphore(1) # semaphore for controlling access to the enabling / disabling of the scroll listening
        self.pos = self.chr_display.verticalScrollBar().value()

        self.highlight_sem = QSemaphore(1) # semaphore for controlling access to highlighting state
        self.is_highlighted = False
        self.highlight_addr = 0

        self.endian = Endian.little
        self.endian_sem = QSemaphore(1)

        self.hash = randint(0, 0xfffffffffffffff)

        icon = QIcon('package/icons/nasa.png')
        self.setWindowIcon(icon)

        self.max_size = 0xfffffffffffffff

        self.qmp.pmem.connect(self.update_text)
        self.grab_data(val=self.baseAddress, size=min(max, constants['block_size'] + base)-self.baseAddress)

        self.t = MyThread(self)
        self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True))
        self.qmp.stateChanged.connect(self.t.halt)
        self.t.running = self.qmp.running
        self.t.start()

        self.show()
        

    def init_ui(self):   
        self.hbox = QHBoxLayout() # holds widgets for refresh button, desired address, and size to grab
        self.vbox = QVBoxLayout() # main container
        self.lower_hbox = QSplitter() # holds memory views
        self.lower_container = QHBoxLayout() # holds  lower_hbox and the endian_vbox
        self.endian_vbox = QVBoxLayout()

        self.hbox.addWidget(QLabel('Address:'))
        self.address = QLineEdit()
        self.hbox.addWidget(self.address)

        self.hbox.addWidget(QLabel('Size:'))
        self.size = QLineEdit()
        self.hbox.addWidget(self.size)

        self.hbox.addWidget(QLabel('Grouping:'))
        self.grouping = QComboBox()
        self.grouping.addItems(['1','2','4','8'])
        self.hbox.addWidget(self.grouping)

        self.search = QPushButton('Search')
        self.search.clicked.connect(lambda:self.find(self.address.text(), constants['block_size']))
        self.hbox.addWidget(self.search)

        self.refresh = QPushButton('Refresh')
        self.refresh.clicked.connect(lambda:self.grab_data(val=self.address.text(), size=self.size.text(), grouping=self.grouping.currentText(), refresh=True))
        self.hbox.addWidget(self.refresh)

        self.save = QPushButton('Save')
        self.save.clicked.connect(lambda: self.save_to_file())
        self.disable_save(self.qmp.running)
        self.qmp.stateChanged.connect(self.disable_save)
        self.hbox.addWidget(self.save)

        self.auto_refresh = QCheckBox('Auto Refresh')
        self.auto_refresh.setCheckState(Qt.CheckState.Checked)
        self.auto_refresh.stateChanged.connect(self.auto_refresh_check)
        self.hbox.addWidget(self.auto_refresh)

        self.vbox.addLayout(self.hbox)
        
        # textbox for addresses
        self.addresses = QTextEdit()
        self.addresses.setReadOnly(True)
        self.addresses.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.addresses.setLineWrapMode(QTextEdit.NoWrap)
        self.addresses.setCurrentFont(QFont('Courier New'))
        self.addresses.setGeometry(0,0,150,500)
        self.lower_hbox.addWidget(self.addresses)

        # textbox for hex display of memory
        self.mem_display = QTextEdit()
        self.mem_display.setReadOnly(True)
        self.mem_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.mem_display.setLineWrapMode(QTextEdit.NoWrap)
        self.mem_display.setCurrentFont(QFont('Courier New'))
        self.mem_display.setGeometry(0,0,600,500)
        self.lower_hbox.addWidget(self.mem_display)
        
        # textbox for char display of memory
        self.chr_display = QTextEdit()
        self.chr_display.setReadOnly(True)
        self.chr_display.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.chr_display.setLineWrapMode(QTextEdit.NoWrap)
        self.chr_display.setCurrentFont(QFont('Courier New'))
        self.mem_display.setGeometry(0,0,400,500)
        self.lower_hbox.addWidget(self.chr_display)

        self.lower_container.addWidget(self.lower_hbox)

        self.mem_display.verticalScrollBar().valueChanged.connect(self.addresses.verticalScrollBar().setValue) #synchronizes addresses's scroll bar to mem_display's 
        self.addresses.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue) #synchronizes mem_display's scroll to addresses's, allowing for searching for addresses to scrol mem_display to the desired point 
        self.chr_display.verticalScrollBar().valueChanged.connect(self.mem_display.verticalScrollBar().setValue)  
        self.mem_display.verticalScrollBar().valueChanged.connect(self.chr_display.verticalScrollBar().setValue)  

        self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll) # allows us to do scrolling

        # setting up endiannes selection buttons
        self.little = QRadioButton("Little Endian")
        self.little.click()
        self.little.clicked.connect(lambda:self.change_endian(Endian.little))
        self.big = QRadioButton("Big Endian")
        self.big.clicked.connect(lambda:self.change_endian(Endian.big))
        self.endian_vbox.addWidget(self.little)
        self.endian_vbox.addWidget(self.big)
        self.endian_vbox.addSpacing(400)

        self.lower_container.addLayout(self.endian_vbox)

        self.vbox.addLayout(self.lower_container)
        self.vbox.setSpacing(10)
        self.setLayout(self.vbox)
        self.setWindowTitle("Memory Dump")
        self.setGeometry(100, 100, 1550, 500)

    def disable_save(self, val):
        self.save.setEnabled(not val)

    def save_to_file(self):
        try:
            filename = QFileDialog().getSaveFileName(self, 'Save', '.', options=QFileDialog.DontUseNativeDialog)
        except Exception as e:
            return

        if filename[0] == '':
            return

        args = {
            'val': self.baseAddress,
            'size': self.maxAddress - self.baseAddress,
            'filename': filename[0]
        }

        self.qmp.command('pmemsave', args=args)
        



    def auto_refresh_check(self, value):
        if self.auto_refresh.checkState() == Qt.CheckState.Checked and not self.t.isRunning():
            self.t = MyThread(self)
            self.t.timing_signal.connect(lambda:self.grab_data(val=self.baseAddress, size=self.maxAddress-self.baseAddress, grouping=self.grouping.currentText(), refresh=True))
            self.t.start()
        elif self.auto_refresh.checkState() == Qt.CheckState.Unchecked:
            self.kill_signal.emit(True)


    def closeEvent(self, event):
        self.kill_signal.emit(True)
        self.qmp.pmem.disconnect(self.update_text)
        while True:
            if self.sem.tryAcquire(1, 1):
                break
            self.sem.release(10)
        event.accept()


    def update_text(self, value):
        if not value or value['hash'] != self.hash: # semaphore must be held before entering this function
            return
        byte = value['vals']
        if self.refresh:
            self.clear_highlight()
            self.addresses.clear()  # clearing to refresh data, other regions will be refilled through scrolling
            self.mem_display.clear()
            self.chr_display.clear()
            
        s = [''] * ceil((len(byte) / (16))) # hex representation of memory
        addresses =  '' # addresses
        count = self.baseAddress # keeps track of each 16 addresses
        if self.pos == self.max:  # scrolling down
            count = self.maxAddress 

        self.maxAddress = max(count + (len(byte)), self.maxAddress)
 

        first = True
        chars = [''] * len(s) # char represenation of memory
        index = 0
        self.endian_sem.acquire()
        nums = ''
        for tup in byte:
            b = tup['val']
            if count % 16 == 0:
                if first:
                    addresses += f'0x{count:08x}' 
                    first = False
                else:
                    addresses += f'\n0x{count:08x}' 

                    index += 1
            count += 1
             
            if self.endian == Endian.big:
                if tup['ismapped']:
                    nums = f'{b:02x}' + nums
                    chars[index] += f'{char_convert(b):3}'
                else:
                    nums = '**' + nums
                    chars[index] += f'{".":3}'

            elif self.endian == Endian.little:  
                if tup['ismapped']:     
                    nums += f'{b:02x}'      
                    chars[index] = f'{char_convert(b):3}' + chars[index]
                else:
                    nums = '**' + nums
                    chars[index] = f'{".":3}' + chars[index]

            if count % self.group == 0:
                if self.endian == Endian.big:
                    s[index] += nums + ' '
                elif self.endian == Endian.little:
                     s[index] = nums + ' ' + s[index]
                nums = ''
                #print(f'"{s[index]}"')
        self.endian_sem.release()

        s = '\n'.join(s)
        chars = '\n'.join(chars)

        scroll_goto = self.pos

        if self.pos > self.max - self.delta:  # scrolling down
            self.addresses.append(addresses)
            self.mem_display.append(s)
            self.chr_display.append(chars)
            if self.flag:
                self.flag = False
                scroll_goto = (1 - constants['block_size'] / self.threshold) * self.max
            else:
                scroll_goto = self.max

        elif self.pos < self.min + self.delta:    # scrolling  up
            addr_cur = self.addresses.textCursor()
            mem_cur = self.mem_display.textCursor()
            chr_cur = self.chr_display.textCursor()

            addr_cur.setPosition(0)
            mem_cur.setPosition(0)
            chr_cur.setPosition(0)

            self.addresses.setTextCursor(addr_cur)
            self.mem_display.setTextCursor(mem_cur)
            self.chr_display.setTextCursor(chr_cur)

            self.addresses.insertPlainText(addresses + '\n')
            self.mem_display.insertPlainText(s + '\n')
            self.chr_display.insertPlainText(chars + '\n')
            
            if self.flag:
                self.flag = False
                scroll_goto = (constants['block_size'] / self.threshold) * self.max
            else:
                scroll_goto = self.chr_display.verticalScrollBar().maximum() - self.max

        else:
            self.addresses.setPlainText(addresses)
            self.mem_display.setPlainText(s)
            self.chr_display.setPlainText(chars)

        self.highlight_sem.acquire()
        if self.is_highlighted:
            self.highlight_sem.release()
            self.highlight(self.highlight_addr, self.group)
        else:
            self.highlight_sem.release()

        self.chr_display.verticalScrollBar().setValue(scroll_goto)
        self.chr_display.verticalScrollBar().valueChanged.connect(self.handle_scroll)
        self.sem.release()


    def grab_data(self, val=0, size=constants['block_size'], grouping=1, refresh=False):       
        if val == None:
            val = 0
        if size == None:
            size = 1024

        if type(val) == str:
            try:
                val = int(val, 0)
            except Exception:
                val = 0
        
        if type(size) == str:
            try:
                size = int(size, 0)
            except Exception:
                size = constants['block_size']

        if type(grouping) == str:
            try:
                grouping = int(grouping, 0)
            except:
                grouping = 1

        if grouping not in [1, 2, 4, 8]:
            grouping = 1

        if val < 0:
            val = 0
        if val >= self.max_size:
            return
        if size < 0:
            size = constants['block_size']
        if size > self.threshold:
            size = self.threshold
        

        self.sem.acquire()

        val = val - (val % 16)
        if val < self.baseAddress or refresh:
            self.baseAddress = val
        if size % 16 != 0:
            size = size + (16 - (size % 16))
        if val + size > self.max_size:
            size = self.max_size - val
        
        try:
            self.chr_display.verticalScrollBar().valueChanged.disconnect(self.handle_scroll)
        except:
            pass
        self.pos = self.chr_display.verticalScrollBar().value()
        self.max = self.chr_display.verticalScrollBar().maximum()
        self.min = self.chr_display.verticalScrollBar().minimum()
        self.group = grouping

        self.refresh = refresh
        if refresh: 
            self.maxAddress = self.baseAddress
            
            self.highlight_sem.acquire()
            if self.is_highlighted and self.highlight_addr not in range(val, val + size):
                self.is_highlighted = False
                self.pos = 0
            self.highlight_sem.release()

        args = {
                'addr': val,
                'size': size,
                'hash': self.hash,
                'grouping': 1
                }
        self.qmp.command('get-pmem', args=args)


    def find(self, addr, size):
        try:
            addr = int(addr, 0)
        except ValueError as e:
            print(e)
            return
        if self.baseAddress <= addr and addr <= self.maxAddress:
            group = self.grouping.currentText()
            try:
                group = int(group, 0)
                if group not in [1, 2, 4, 8]:
                    group = 1
            except:
                group = 1
            self.highlight(addr, group)
            
        else:
            self.highlight_sem.acquire()
            self.is_highlighted = True
            self.highlight_addr = addr
            self.highlight_sem.release()
            self.grab_data(val=addr, size=size, refresh=True )


    def clear_highlight(self):
        fmt = QTextCharFormat()
        fmt.setFont('Courier New')
        # clearing past highlights
        addr_cur = self.addresses.textCursor()  # getting cursors
        mem_cur = self.mem_display.textCursor()
        chr_cur = self.chr_display.textCursor()

        addr_cur.select(QTextCursor.Document)   # selecting entire document
        mem_cur.select(QTextCursor.Document)
        chr_cur.select(QTextCursor.Document)
        
        addr_cur.setCharFormat(fmt) # adding format
        mem_cur.setCharFormat(fmt)
        chr_cur.setCharFormat(fmt)


    def highlight(self, addr, group):
        self.clear_highlight()
        
        # adding new highlights
        fmt = QTextCharFormat()
        fmt.setBackground(Qt.cyan)
        fmt.setFont('Courier New')

        addr_block = self.addresses.document().findBlockByLineNumber((addr - self.baseAddress) // 16) # gets linenos 
        mem_block = self.mem_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16)
        chr_block = self.chr_display.document().findBlockByLineNumber((addr - self.baseAddress) // 16)

        addr_cur = self.addresses.textCursor()  # getting cursors
        mem_cur = self.mem_display.textCursor()
        chr_cur = self.chr_display.textCursor()


        char_offset = 0
        mem_offset = 0
        self.endian_sem.acquire()
        if self.endian == Endian.big:
            mem_offset = ((addr % 16) // group) * (2 * group + 1)
            char_offset = (addr % 16) * 3
        elif self.endian == Endian.little:
            mem_offset = (((16 / group) - 1 )* (2 * group + 1)) - ((addr % 16) // group) * (2 * group + 1)
            char_offset = (15*3) - ((addr % 16) * 3)
        self.endian_sem.release()
        addr_cur.setPosition(addr_block.position()) # getting positions
        mem_cur.setPosition(mem_block.position() + mem_offset) # gives character offset within 16 byte line
        chr_cur.setPosition(chr_block.position() + char_offset) # sets position of char

        chr_text = self.chr_display.toPlainText()
        if chr_text[chr_cur.position()] == '\\' and chr_cur.position() + 1 < len(chr_text) and chr_text[chr_cur.position() + 1] in ['0', 'n', 't']:
            chr_cur.setPosition(chr_cur.position() + 2, mode=QTextCursor.KeepAnchor) 
        else:
            chr_cur.setPosition(chr_cur.position() + 1, mode=QTextCursor.KeepAnchor) 


        addr_cur.select(QTextCursor.LineUnderCursor)    # selects whole line
        mem_cur.select(QTextCursor.WordUnderCursor)     # selects just one word

        addr_cur.setCharFormat(fmt) # setting format
        mem_cur.setCharFormat(fmt)
        chr_cur.setCharFormat(fmt)

        self.addresses.setTextCursor(addr_cur)
        self.mem_display.setTextCursor(mem_cur)
        self.chr_display.setTextCursor(chr_cur)
        
        self.highlight_sem.acquire()
        self.is_highlighted = True
        self.highlight_addr = addr
        self.highlight_sem.release()


    def handle_scroll(self):
        if self.baseAddress > 0 and self.chr_display.verticalScrollBar().value() < self.chr_display.verticalScrollBar().minimum() + self.delta:
            size = constants['block_size']
            if self.maxAddress - self.baseAddress >= self.threshold:
                self.flag = True
                self.grab_data(val=self.baseAddress - constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText())
                return
            if self.baseAddress < size:
                size = self.baseAddress
            self.grab_data(val=self.baseAddress-size, size=size, grouping=self.grouping.currentText())
        elif self.chr_display.verticalScrollBar().value() > self.chr_display.verticalScrollBar().maximum() - self.delta and self.maxAddress <= self.max_size:
            if self.maxAddress - self.baseAddress >= self.threshold:
                self.flag = True
                self.grab_data(val=self.baseAddress + constants['block_size'], size=self.threshold, refresh=True, grouping=self.grouping.currentText())
            else:
                self.grab_data(val=self.maxAddress, grouping=self.grouping.currentText())
      
      
    def change_endian(self, endian):
        self.endian_sem.acquire()
        if endian == Endian.little:
            self.endian = endian
        elif endian == Endian.big:
            self.endian = endian
        self.endian_sem.release()
예제 #9
0
파일: PortImpl.py 프로젝트: ifm/nexxT
 def __init__(self, qthread_from):
     super().__init__()
     self.moveToThread(qthread_from)
     self.semaphore = QSemaphore(1)
     self._stopped = True
예제 #10
0
class MemTree(QWidget):
    def __init__(self, qmp, parent):
        super().__init__()
        self.qmp = qmp
        self.qmp.memoryMap.connect(self.update_tree)

        self.parent = parent

        self.tree_sem = QSemaphore(1)
        self.sending_sem = QSemaphore(
            1)  # used to prevent sending too many requests at once

        self.init_ui()
        self.get_map()

    def init_ui(self):

        self.vbox = QVBoxLayout()

        self.refresh = QPushButton('Refresh')
        self.refresh.clicked.connect(lambda: self.get_map())
        self.vbox.addWidget(self.refresh)

        self.tree = QTreeWidget()
        self.tree.itemDoubleClicked.connect(self.open_region)
        self.tree.setColumnCount(3)
        self.tree.header().setSectionResizeMode(QHeaderView.ResizeToContents)
        self.tree.header().setStretchLastSection(False)
        self.tree.setHeaderLabels(
            ['Memory Region', 'Start Address', 'End Address'])
        self.vbox.addWidget(self.tree)

        self.setLayout(self.vbox)
        self.setGeometry(100, 100, 500, 300)
        self.setWindowTitle("Memory Tree")
        self.show()

    def get_map(self):
        self.tree.clear()
        self.qmp.command('mtree')

    # finds item with name 'name' in self.tree
    # self.tree_sem must be acquired before use
    def find(self, name, node):
        if node.text(0) == name:
            return node
        else:
            for i in range(node.childCount()):
                result = self.find(name, node.child(i))
                if result:
                    return result
            return None

    def update_tree(self, value):
        if value != None:
            self.tree_sem.acquire()
            current_addr_space = ''

            for region in value:
                parent_node = self.tree
                parent = region['parent']

                if parent != '':
                    root = self.tree.invisibleRootItem()
                    for i in range(root.childCount()):
                        if root.child(i).text(0) == current_addr_space:
                            root = root.child(i)
                            break
                    parent_node = self.find(parent, root)
                else:
                    current_addr_space = region['name']

                node = QTreeWidgetItem(parent_node)
                node.setText(0, region['name'])
                start = region['start']
                end = region['end']
                if start < 0:
                    start = start + (1 << constants['bits'])
                if end < 0:
                    end = end + (1 << constants['bits'])
                node.setText(1, f'{start:016x}')
                node.setText(2, f'{end:016x}')
                node.setFont(0, QFont('Courier New'))
                node.setFont(1, QFont('Courier New'))
                node.setFont(2, QFont('Courier New'))

            self.tree_sem.release()

    def open_region(self, node, col):
        self.parent.open_new_window(
            MemDumpWindow(self.qmp,
                          base=int(node.text(1), 16),
                          max=int(node.text(2), 16)))
예제 #11
0
 def __init__(self):
     super().__init__()
     self.sem = QSemaphore()
     self.rate = 10
예제 #12
0
class TimeMultiplier(QWidget):
    updateRate = Signal(int)

    def __init__(self, qmp, event):
        super().__init__()
        self.running = qmp.running

        self.totalRunning = 0
        self.total = 0

        self.qmp = qmp
        self.qmp.timeMetric.connect(self.handle_sample)

        self.kill_event = event

        self.data = 0

        self.lim = 10
        self.window = 10
        self.rate_value = 10

        self.sem = QSemaphore(1)

        self.all_min_val = -1
        self.all_max_val = -1

        self.plot_min_val = -1
        self.plot_max_val = -1

        self.initui()

    def initui(self):
        lay = QVBoxLayout(self)
        toolbar = QHBoxLayout()
        main_box = QHBoxLayout()
        stats_box = QVBoxLayout()

        self.rate = QSpinBox()
        self.rate.setValue(self.rate_value)
        toolbar.addWidget(QLabel('Sampling Rate (Hz):'))
        toolbar.addWidget(self.rate)

        self.window_input = QSpinBox()
        self.window_input.setValue(self.window)
        toolbar.addWidget(QLabel('Window:'))
        toolbar.addWidget(self.window_input)

        self.limit = QSpinBox()
        self.limit.setValue(self.lim)
        toolbar.addWidget(QLabel('Limit (s):'))
        toolbar.addWidget(self.limit)

        self.refresh_button = QPushButton('Refresh')
        self.refresh_button.clicked.connect(self.handle_refresh)
        toolbar.addWidget(self.refresh_button)

        lay.addLayout(toolbar)

        fig = Figure(figsize=(7, 5),
                     dpi=65,
                     facecolor=(1, 1, 1),
                     edgecolor=(0, 0, 0))
        self.canvas = FigureCanvas(fig)

        main_box.addWidget(self.canvas)

        self.ax = fig.add_subplot()
        self.line, *_ = self.ax.plot([])

        self.ax.set_ylim(0, 1.1)
        self.ax.set_xlim(0, 1)

        self.ax.set_xlabel('Simulation Time (s)')
        self.ax.set_ylabel('Multiplier')
        self.fill = self.ax.fill_between(self.line.get_xdata(),
                                         self.line.get_ydata(),
                                         color='blue',
                                         alpha=.3,
                                         interpolate=True)

        self.canvas.draw()

        all_data = QLabel("All Data")
        bold_font = QFont()
        bold_font.setBold(True)
        all_data.setFont(bold_font)
        stats_box.addWidget(all_data)

        self.all_min = QLabel('Min:')
        stats_box.addWidget(self.all_min)

        self.all_max = QLabel('Max:')
        stats_box.addWidget(self.all_max)

        plot_data = QLabel("On Screen Data")
        plot_data.setFont(bold_font)
        stats_box.addWidget(plot_data)

        self.plot_min = QLabel('Min:')
        stats_box.addWidget(self.plot_min)

        self.plot_max = QLabel('Max:')
        stats_box.addWidget(self.plot_max)

        self.plot_med = QLabel('Median:')
        stats_box.addWidget(self.plot_med)

        self.plot_avg = QLabel('Mean:')
        stats_box.addWidget(self.plot_avg)

        main_box.addLayout(stats_box)

        lay.addLayout(main_box)
        self.setLayout(lay)

    def handle_refresh(self, val):
        self.rate_value = self.rate.value() if self.rate.value() > 0 else 10
        self.updateRate.emit(self.rate_value)

        self.lim = self.limit.value() if self.limit.value() > 0 else 10
        self.window = self.window_input.value(
        ) if self.window_input.value() > 0 else 10

    def start(self):
        self.sim_prev = None
        self.real_prev = time.time() * (10**9)  # converting from s to ns
        self.start_time = self.real_prev
        self.data = []
        self.lim_data = []  # data within limit
        self.t = SamplingThread()
        self.kill_event.connect(self.t.end_thread)
        self.t.sample.connect(self.get_time)
        self.updateRate.connect(self.t.update)
        self.t.start()

    def handle_sample(self, val):
        self.sem.acquire()
        if not self.sim_prev:
            self.sim_prev = val[0]['time_ns']
            self.real_prev = val[1]['time_ns']
            self.sem.release()
            return
        diff = (val[0]['time_ns'] - self.sim_prev) / (val[1]['time_ns'] -
                                                      self.real_prev)
        self.sim_prev = val[0]['time_ns']
        self.real_prev = val[1]['time_ns']
        self.data.append(diff)
        if len(self.data) > self.window:
            self.data = self.data[-1 * self.window:]
        avg = sum(self.data) / len(self.data)
        if len(self.lim_data) > self.lim * self.rate_value:
            self.lim_data = self.lim_data[-1 * self.lim * self.rate_value:]
        self.lim_data.append(avg)
        self.handle_stats()
        self.line.set_xdata(
            numpy.append(self.line.get_xdata(),
                         (val[1]['time_ns'] - self.start_time) / (10**9)))
        self.line.set_ydata(numpy.append(self.line.get_ydata(), avg))
        self.ax.set_xlim(
            (val[1]['time_ns'] - self.start_time) / (10**9) - self.lim,
            (val[1]['time_ns'] - self.start_time) / (10**9))

        #self.ax.collections.remove(self.fill)
        #self.fill = self.ax.fill_between(self.line.get_xdata(), self.line.get_ydata(), color='blue', alpha=.2, interpolate=True)
        self.canvas.draw()
        self.sem.release()

    def handle_stats(self):
        if self.lim_data[-1] > self.all_max_val or self.all_max_val < 0:
            self.all_max_val = self.lim_data[-1]
            self.all_max.setText(f'Max: {self.lim_data[-1]:.03f}')
        if self.lim_data[-1] < self.all_min_val or self.all_min_val < 0:
            self.all_min_val = self.lim_data[-1]
            self.all_min.setText(f'Min: {self.lim_data[-1]:.03f}')

        if self.lim_data[-1] > self.plot_max_val or self.plot_max_val > max(
                self.lim_data):
            self.plot_max_val = self.lim_data[-1]
            self.plot_max.setText(f'Max: {self.lim_data[-1]:.03f}')
        if self.lim_data[-1] < self.plot_min_val or self.plot_min_val < min(
                self.lim_data):
            self.plot_min_val = self.lim_data[-1]
            self.plot_min.setText(f'Min: {self.lim_data[-1]:.03f}')
        self.ax.set_ylim(0, max(1.1, self.plot_max_val + .1))
        avg = sum(self.lim_data) / len(self.lim_data)
        self.plot_avg.setText(f'Mean: {avg:.03f}')

        med = numpy.median(self.lim_data)
        self.plot_med.setText(f'Median: {med:.03f}')

    def get_time(self):
        self.qmp.command('itc-time-metric')