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.'
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.'
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])
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()
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])
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
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()