SystemVerilog semaphore + disabled block

D

dm

Guest
Hello, folks!

Consider following code, please:
--- 8< ---
// create semaphore with empty bucket
semaphore MySemaphore = new();
....
fork
begin : A
// blocks "A" thread
MySemaphore.get(1);
// ... critical section ...
MySemaphore.put(1);
end
begin : B
#1; disable A;
end
join
--- >8 ---

(1) fork-join thread "A" is blocked here with get() method -- because
there is unsufficient number of keys in the bucket (note, that in case
of multiple requests after this one -- that blocked the process
execution -- they are placed into FIFO waiting queue)
(2) after 1 time unit passes, thread "A" is disabled

According to the LRM, disabled block just immediately jumps to its
end. The question is: what is correct behavior for waiting FIFO?
-----------waiting-FIFO---------
| 4 | 3 | 2 | 1 |
| | | | |
| | | disab| |
--------------------------------

get() should be:
1) removed from the waiting FIFO
or
2) kept in the FIFO -- when execution will enter to "A" thread again,
it will immediately go to the "blocked place"?
 
On Dec 5, 4:40 am, dm <explo...@inbox.ru> wrote:
get() should be:
1) removed from the waiting FIFO
or
2) kept in the FIFO -- when execution will enter to "A" thread again,
it will immediately go to the "blocked place"?
The answer must be 1.

While the SystemVerilog LRM does not explicitly describe how disables
interact with semaphores, we can look at how disables work in
Verilog. If a process is waiting for something when it is disabled,
it stops waiting on that thing and jumps to the required place. It
does not keep track of where it was before the disable. And it
definitely cannot be 2, since the fork subprocess will terminate after
it exits block A and finishes executing the statement that was
forked. That process is gone, so it cannot re-enter the "A" block.
If the fork is executed again, a new process will be created and enter
"A", which is not the same process that was waiting at the get()
earlier.

This is an area where an implementation could have bugs, if the
implementor of semaphores did not consider the possibility of a
disable.

From a user's viewpoint, this also raises the danger of bugs in their
code. If the code contains disables, it may be difficult or
impossible to properly protect a critical section. For example,
consider the case where a process is running in the critical section
when it is disabled. It will not execute the put() at the end of the
critical section, so a semaphore key has been permanently lost. If
the semaphore was started with a single key to act as a mutex, this
will prevent any other process from ever getting a key and entering
the critical section.
 
On Dec 12, 3:19 am, sh...@cadence.com wrote:
On Dec 5, 4:40 am, dm <explo...@inbox.ru> wrote:



get() should be:
1) removed from the waiting FIFO
or
2) kept in the FIFO -- when execution will enter to "A" thread again,
it will immediately go to the "blocked place"?

The answer must be 1.

While the SystemVerilog LRM does not explicitly describe how disables
interact with semaphores, we can look at how disables work in
Verilog. If a process is waiting for something when it is disabled,
it stops waiting on that thing and jumps to the required place. It
does not keep track of where it was before the disable. And it
definitely cannot be 2, since the fork subprocess will terminate after
it exits block A and finishes executing the statement that was
forked. That process is gone, so it cannot re-enter the "A" block.
If the fork is executed again, a new process will be created and enter
"A", which is not the same process that was waiting at the get()
earlier.

This is an area where an implementation could have bugs, if the
implementor of semaphores did not consider the possibility of a
disable.

From a user's viewpoint, this also raises the danger of bugs in their
code. If the code contains disables, it may be difficult or
impossible to properly protect a critical section. For example,
consider the case where a process is running in the critical section
when it is disabled. It will not execute the put() at the end of the
critical section, so a semaphore key has been permanently lost. If
the semaphore was started with a single key to act as a mutex, this
will prevent any other process from ever getting a key and entering
the critical section.
Sharp,

1) Thanks a lot for valuable reply! I appreciate it highly!
2) I like the 'mindflow' you suggested! It definitely should be done
in such way :)

Kind regards,
dm
 

Welcome to EDABoard.com

Sponsor

Back
Top