Skip to content

Commit

Permalink
Add optimizations for scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
ktbarrett committed May 7, 2024
1 parent a87c04e commit 2db2ac0
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 35 deletions.
53 changes: 20 additions & 33 deletions src/cocotb/_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,8 +260,6 @@ def __init__(self, test_complete_cb: Callable[[], None]) -> None:

self._current_task = None

self._is_reacting = False

self._write_task = None
self._writes_pending = Event()

Expand Down Expand Up @@ -338,30 +336,6 @@ def _test_completed(self, trigger=None):
# if it did, make sure we handle the test completing
self._check_termination()

def _react(self, trigger):
"""
Called when a trigger fires.
We ensure that we only start the event loop once, rather than
letting it recurse.
"""
if self._is_reacting:
# queue up the trigger, the event loop will get to it
self._pending_triggers.append(trigger)
return

if self._pending_triggers:
raise InternalError(
f"Expected all triggers to be handled but found {self._pending_triggers}"
)

# start the event loop
self._is_reacting = True
try:
self._event_loop(trigger)
finally:
self._is_reacting = False

def _event_loop(self, trigger):
"""
Run an event loop triggered by the given trigger.
Expand Down Expand Up @@ -524,7 +498,7 @@ def _unschedule(self, task):
self._cleanup()

elif Join(task) in self._trigger2tasks:
self._react(Join(task))
self._pending_triggers.append(Join(task))
else:
try:
# throws an error if the background task errored
Expand Down Expand Up @@ -581,7 +555,10 @@ def _resume_task_upon(self, task, trigger):
raise InternalError("More than one task waiting on an unprimed trigger")

try:
trigger._prime(self._react)
if isinstance(trigger, GPITrigger):
trigger._prime(self._event_loop)
else:
trigger._prime(self._pending_triggers.append)
except Exception as e:
# discard the trigger we associated, it will never fire
self._trigger2tasks.pop(trigger)
Expand Down Expand Up @@ -716,16 +693,26 @@ def start_soon(self, task: Union[Coroutine, Task]) -> Task:
self._queue(task)
return task

def _add_test(self, test_task):
def _add_test(self, test_task: Task[None]) -> None:
"""Called by the regression manager to queue the next test"""
if self._mode != self._MODE_NORMAL:
raise InternalError("Test was not started in Normal Mode.")

if self._test is not None:
raise InternalError("Test was added while another was in progress")
raise InternalError("Test was added while another was in progress.")

self._test = test_task
self._resume_task_upon(
test_task,
NullTrigger(name=f"Start {test_task!s}", outcome=_outcomes.Value(None)),

# like _resume_task_upon, but forcing the NullTrigger to go through the main entry point
trigger = NullTrigger(
name=f"Start {test_task!s}", outcome=_outcomes.Value(None)
)
test_task._trigger = trigger
trigger_tasks = self._trigger2tasks.setdefault(trigger, [])
trigger_tasks.append(test_task)

# call into main entry point
trigger._prime(self._event_loop)

# This collection of functions parses a trigger out of the object
# that was yielded by a task, converting `list` -> `Waitable`,
Expand Down
4 changes: 2 additions & 2 deletions tests/test_cases/test_cocotb/test_scheduler.py
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ def react_wrapper(trigger):
log = logging.getLogger("cocotb.test")
log.debug("react_wrapper start")
assert coro_scheduled is False
cocotb._scheduler._react(trigger)
cocotb._scheduler._event_loop(trigger)
assert coro_scheduled is True
log.debug("react_wrapper end")

Expand Down Expand Up @@ -651,7 +651,7 @@ def react_wrapper(trigger):
log = logging.getLogger("cocotb.test")
log.debug("react_wrapper start")
sim_resumed = False
cocotb._scheduler._react(trigger)
cocotb._scheduler._event_loop(trigger)
sim_resumed = True
log.debug("react_wrapper end")

Expand Down

0 comments on commit 2db2ac0

Please sign in to comment.