示例#1
0
    def start_aio(self):
        self._start_time = coro.get_now()
        self.main_thread_state = 'Starting writers.'
        self.log(1, 'Starting %i writers.', self.options.num_writers)
        for x in xrange(self.options.num_writers):
            self._worker_semaphore.acquire()
            coro.spawn(self._writer, x)

        while 1:
            # Spin lock.
            status = 'Waiting for writers to ramp up %i/%i.' % (self._writes_finished, self.options.reader_delay)
            self.main_thread_state = status
            self.log(2, status)
            if int(self._worker_semaphore) == 0:
                self.log(0, 'EEP!  All writers exited too fast.')
                self.main_thread_state = 'Aborted.'
                return
            if self._writes_finished < self.options.reader_delay:
                coro.sleep_relative(0.5)
            else:
                break

        self.main_thread_state = 'Starting readers.'
        self.log(1, 'Starting %i readers.', self.options.num_readers)
        for x in xrange(self.options.num_readers):
            self._worker_semaphore.acquire()
            coro.spawn(self._reader, x)

        self.main_thread_state = 'Waiting for all threads to finish.'
        self.log(1, 'Waiting till all threads finished.')
        self._worker_semaphore.block_till_zero()
        self.main_thread_state = 'Done.'
示例#2
0
    def start_lio(self):
        self._start_time = coro.get_now()
        self.main_thread_state = 'Starting LIO workers.'
        self.log(1, 'Starting %i lio workers.', self.options.num_lio_workers)
        for x in xrange(self.options.num_lio_workers):
            self._worker_semaphore.acquire()
            coro.spawn(self._lio, x)

        self.main_thread_state = 'Waiting for all threads to finish.'
        self.log(1, 'Waiting till all threads finished.')
        self._worker_semaphore.block_till_zero()
        self.main_thread_state = 'Done.'
示例#3
0
    def test_scheduled_staging_interrupt(self):
        """Test interrupting a thread that is scheduled and in the staging list."""
        t = coro.get_now() + coro.ticks_per_sec*3
        exception_raised = [False]
        def foo():
            self.assertFalse(exception_raised[0])
            try:
                coro.sleep_absolute(t)
            except TestException:
                exception_raised[0] = True

        c = coro.spawn(foo)
        coro.sleep_absolute(t)
        c.raise_exception(TestException)
        coro.yield_slice()
        self.assertTrue(exception_raised[0])
示例#4
0
    def _reader(self, reader_num):
        selfish_acts = 1
        self.reader_status[reader_num] = 'Starting.'
        try:
            while 1:
                if coro.get_now() > self._start_time + self.options.duration*coro.ticks_per_sec:
                    self.reader_status[reader_num] = 'Finished.'
                    return
                if not selfish_acts % self.options.greediness:
                    self.reader_status[reader_num] = 'Greediness sleep.'
                    coro.sleep_relative(0)
                if not self._have_blocks_to_read():
                    self.reader_status[reader_num] = 'Sleeping, waiting for writers to catch up.'
                    coro.sleep_relative(0.1)
                    continue
                pos, size, area = self._get_to_read()

                self.log(3, '%i: read(%i, %i)', reader_num, size, pos)
                try:
                    if random.random() < self.options.cancel_percent/100.0:
                        try:
                            self.reader_status[reader_num] = 'Reading with cancel.'
                            data = coro.with_timeout(0, coro.aio_read, self._fd, size, long(pos))
                        except coro.TimeoutError:
                            self._read_cancel_success += 1
                        else:
                            self._read_cancel_fail += 1
                    else:
                        self.reader_status[reader_num] = 'Reading.'
                        data = coro.aio_read(self._fd, size, long(pos))
                        expected_data = t_aio.make_data(pos, size)
                        if data != expected_data:
                            self._assertion_errors += 1
                            self.log(0, 'ERROR: data read=%i expected=%i pos=%i', len(data), size, pos)
                            fname = tempfile.mktemp()
                            f = open(fname, 'w')
                            f.write(data)
                            f.close()
                            self.log(0, 'Wrote temp file %s', fname)
                finally:
                    self._read_locks.delete(area)
                selfish_acts += 1
                self._reads_finished += 1
                self._bytes_read += size
        finally:
            self._worker_semaphore.release()
示例#5
0
    def test_scheduled_staging_interrupt(self):
        """Test interrupting a thread that is scheduled and in the staging list."""
        t = coro.get_now() + coro.ticks_per_sec * 3
        exception_raised = [False]

        def foo():
            self.assertFalse(exception_raised[0])
            try:
                coro.sleep_absolute(t)
            except TestException:
                exception_raised[0] = True

        c = coro.spawn(foo)
        coro.sleep_absolute(t)
        c.raise_exception(TestException)
        coro.yield_slice()
        self.assertTrue(exception_raised[0])
示例#6
0
    def _writer(self, writer_num):
        selfish_acts = 1
        self._num_live_writers += 1
        self.writer_status[writer_num] = 'Starting.'
        try:
            while 1:
                if coro.get_now() > self._start_time + self.options.duration*coro.ticks_per_sec:
                    self.writer_status[writer_num] = 'Finished.'
                    return
                if not selfish_acts % self.options.greediness:
                    self.writer_status[writer_num] = 'Greediness sleep.'
                    coro.sleep_relative(0)
                self.writer_status[writer_num] = 'Getting area to write.'
                pos, size, area = self._get_to_write()

                self.log(3, '%i: write(%i, %i)', writer_num, size, pos)
                data = t_aio.make_data(pos, size)
                try:
                    if random.random() < self.options.cancel_percent/100.0:
                        try:
                            self.writer_status[writer_num] = 'Writing with cancel.'
                            num_written = coro.with_timeout(0, coro.aio_write, self._fd, data, long(pos))
                        except coro.TimeoutError:
                            self._write_cancel_success += 1
                        else:
                            self._written.append((pos, size))
                            self._write_cancel_fail += 1
                    else:
                        self.writer_status[writer_num] = 'Writing.'
                        num_written = coro.aio_write(self._fd, data, long(pos))
                        if num_written != size:
                            self.log(0, 'ERROR: Failed to write %i bytes (%i written).' % (size, num_written))
                            self._assertion_errors += 1
                        else:
                            self._written.append((pos, size))
                finally:
                    self._write_locks.delete(area)
                selfish_acts += 1
                #print len(self._written)
                self._writes_finished += 1
                self._bytes_written += size
        finally:
            self._worker_semaphore.release()
            self._num_live_writers -= 1
示例#7
0
    def _lio(self, worker_num):
        selfish_acts = 1
        self._num_live_writers += 1
        self.lio_status[worker_num] = 'Starting.'
        try:
            while 1:
                if coro.get_now() > self._start_time + self.options.duration*coro.ticks_per_sec:
                    self.lio_status[worker_num] = 'Finished.'
                    return
                if not selfish_acts % self.options.greediness:
                    self.lio_status[worker_num] = 'Greediness sleep.'
                    coro.sleep_relative(0)
                num_events = random.randint(self.options.min_lio, self.options.max_lio)
                requests = []
                reads_to_unlock = []
                writes_to_unlock = []
                self.log(3, '%i: lio(%i)', worker_num, num_events)
                if self._have_blocks_to_read():
                    do_read = random.randint(0, 1)
                else:
                    do_read = False
                if do_read:
                    expected_result = []
                else:
                    expected_result = 0

                for unused in xrange(num_events):
                    if do_read:
                        if not self._have_blocks_to_read():
                            # Skip the rest of the reads.
                            continue
                        self.lio_status[worker_num] = 'Getting area to read.'
                        pos, size, area = self._get_to_read()
                        requests.append((self._fd, pos, size))
                        data = t_aio.make_data(pos, size)
                        expected_result.append(data)
                        self.log(3, '%i: lio_read(%i, %i)', worker_num, size, pos)
                        reads_to_unlock.append(area)
                        lio_op = coro.lio_read
                    else:
                        self.lio_status[worker_num] = 'Getting area to write.'
                        pos, size, area = self._get_to_write()
                        data = t_aio.make_data(pos, size)
                        requests.append((self._fd, pos, data))
                        expected_result += size
                        self.log(3, '%i: lio_write(%i, %i)', worker_num, size, pos)
                        writes_to_unlock.append(area)
                        lio_op = coro.lio_write

                try:
                    if random.random() < self.options.cancel_percent/100.0:
                        try:
                            if do_read:
                                self.lio_status[worker_num] = 'Doing LIO READ with cancel.'
                            else:
                                self.lio_status[worker_num] = 'Doing LIO WRITE with cancel.'
                            result = coro.with_timeout(0, lio_op, requests)
                        except coro.TimeoutError:
                            self._write_cancel_success += 1
                            continue
                        else:
                            self._write_cancel_fail += 1
                    else:
                        if do_read:
                            self.lio_status[worker_num] = 'Doing LIO READ.'
                        else:
                            self.lio_status[worker_num] = 'Doing LIO WRITE.'
                        result = lio_op(requests)
                finally:
                    for area in reads_to_unlock:
                        self._read_locks.delete(area)
                    for area in writes_to_unlock:
                        self._write_locks.delete(area)

                if do_read:
                    if len(result) != len(expected_result):
                        self.log(0, 'ERROR: Length of result (%i) is not expected (%i).', len(result), len(expected_result))
                        continue

                    for result_value, expected_value in zip(result, expected_result):
                        if result_value != expected_value:
                            self.log(0, 'ERROR: Expected read of %i bytes, got %i bytes not equal.', len(expected_value), len(result_value))
                        else:
                            self._reads_finished += 1
                            self._bytes_read += len(expected_value)
                else:
                    # doing a write, return value is just an integer.
                    if result != expected_result:
                        self.log(0, 'ERROR: Result from write (%i) not expected (%i).', result, expected_result)
                        continue
                    else:
                        self._writes_finished += 1
                        self._bytes_written += expected_result
                        self._written.append((pos, size))

        finally:
            self._num_live_writers -= 1
            self._worker_semaphore.release()