Preemptive
Preemptive shared resource.
Preempted
dataclass
Interrupt cause delivered when a process is evicted from a PreemptiveResource.
Attributes:
| Name | Type | Description |
|---|---|---|
by |
Process
|
the process that caused the preemption. |
usage_since |
float
|
simulation time when the preempted process acquired the resource. |
Source code in src/asimpy/preemptive.py
15 16 17 18 19 20 21 22 23 24 25 | |
PreemptiveResource
Shared resource where higher-priority processes can preempt lower-priority users.
Priority is an integer; lower values are served first (0 is highest priority).
When a new acquire request has better priority than the worst current user
and preempt=True, that user is interrupted with a Preempted cause and
removed from the resource. The preempted process is responsible for catching
the Interrupt, tracking remaining work, and re-acquiring.
Important: do not call release() when handling a Preempted interrupt
— the preempted process has already been removed from the user list.
Example usage:
async def run(self):
remaining = service_time
while remaining > 0:
await resource.acquire(priority=self.priority)
started = self.now
try:
await self.timeout(remaining)
remaining = 0
resource.release()
except Interrupt as intr:
if isinstance(intr.cause, Preempted):
remaining -= self.now - intr.cause.usage_since
# do NOT call release() here
else:
resource.release()
raise
Source code in src/asimpy/preemptive.py
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |
count
property
Current number of active users.
__init__(env, capacity=1)
Construct a preemptive resource.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
env
|
Environment
|
simulation environment. |
required |
capacity
|
int
|
maximum number of concurrent users. |
1
|
Raises:
| Type | Description |
|---|---|
ValueError
|
for non-positive capacity. |
Source code in src/asimpy/preemptive.py
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | |
acquire(priority=0, preempt=True)
async
Acquire one unit of the resource.
The calling process is identified via env.active_process, so this
must be called from within a Process.run() coroutine.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
priority
|
int
|
lower value = higher priority (0 is best). |
0
|
preempt
|
bool
|
if True, may interrupt the lowest-priority current user when the resource is full and that user has lower priority than this request. |
True
|
Source code in src/asimpy/preemptive.py
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 | |
release()
Release one unit of the resource.
The calling process is identified via env.active_process.
Do not call this when handling a Preempted interrupt — the process
has already been removed from the user list by the preemptor.
Raises:
| Type | Description |
|---|---|
RuntimeError
|
if the calling process is not a current user. |
Source code in src/asimpy/preemptive.py
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | |