wait() in semaphores is Atomic - operating-system

I am new to OS.This question might sound a little dumb, but please help me to understand the concept behind it.
Let S-> A semaphore variable
Now let wait(S) be implemented as
wait(S){
while S<=0 ;
S--;
}
Now wait(S) is an atomic operation.Atomic means it cannot be interrupted.
Now if I have a uniprocessor then the Process executing wait() will run forever and will never be preempted if some other process sets S=0.
How does it work out? Please Explain.

Related

UVM End of test Objection Mechanism and Phase Ready to End Implementation

I am exploring different ways to end a UVM test. One method that has come often from studying different blogs from Verification Academy and other sites is to use the Phase Ready to End. I have some questions regarding the implementation of this method.
I am using this method in scoreboard class, where my understanding is after my usual run phase is finished, it will call the phase ready to end method and implement it. The reason I am using it my scoreboard's run_phase finishes early, and there are some data into queues that need to be processed. So I am trying to prolong this scoreboard run_phase using this method. Here are is some pseudo-code that I have used.
function void phase_ready_to_end(uvm_phase phase);
if (phase.get_name() != "run") return;
if (queue.size() != 0) begin
phase.raise_objection(.obj(this));
fork
begin
delay_phase(phase);
end
join_none
end
endfunction
task delay_phase(uvm_phase phase);
wait(queue.size() == 0);
phase.drop_objection(.obj(this));
endtask
I have taken inspiration for this implementation from this link UVM-End of Test Mechanism for your reference. Here are some of the ungated thoughts in my mind on which I need guidance and help.
to the best of my understanding the phase_ready_to_end is called at the end of run_phase and when it runs it raises the objection for that scoreboard run_phase and runs delay_phase task.
That Delay Phase task is just waiting for the queue to end, but I am not seeing any method or task which will pop the items from the queue. Does I have to call some method to pop from the queue or as according to the 1st point above the raised objection will start the run phase so there is no need for that and we have to wait for a considerable amount of time?
Let me give you some pre-context to this question. I have a scoreboard where there are two queues whose write methods are implemented and they are being fed correctly by their source.
task run_phase (uvm_phase phase);
forever begin
compare_queues(); // this method takes data from two queues and compares them, both queues implementation are fine and they take data from their respective sources. Let me give you a scenario, let's suppose there are a total of 10 transactions being generated but the scoreboard was able to process only 6 of them and there are 4 transactions left when all objections are dropped. So to tackle that I implement this phase_to_ready_end method in my scoreboard.
end
endtask
The problem with this method that I am having is that, when I raise the objection in this phase_ready_to_end and call delay_phase method, nothing happens. And I am curious is there more to this implementation or not?
Sorry for the delay. I have shared more context to the existing question. Please see to that, let me know if it is confusing.
We have a pair of monitors that calls write method implemented inside the scoreboard. The monitors typically capture the transaction from BUS and call these WR methods to push the transactions. Thus two source and destination monitors WR into two - source and destination - queues as and when they find the transactions.
We have a checker task with RD-n-check running in forever loop in the run-phase of scoreboard. It's in a while loop and watches if the destination queue has non-zero entry. Once it finds so, it pops the head entry from destination queue and then pops the head entry from source queue as well and compares the two entries to declare if the check was a PASS or FAIL.
There are more than 2 queues and more than a pair of source/destination of course, but broadly this is the architecture around here.
Now in the current scenario, it seems that the checker tasks stop prints after certain point of time in some of the test cases. Upon adding debug prints thoroughly, it seems that checker tasks that does the job #2/#3 above and gets called inside the forever loop of the run-phase, exits gracefully one last time. However they are entered again - which is to say that the forever loop that should be calling them didn't call. As if the forever loop of run-phase stopped completely.
We also added another forever loop in run-phase that observes whether the queues are empty. From prints inside that parallel loop and from the monitor prints, we know that the queues aren't empty and monitors did push WRs into the queues for a long time.
It seems that the forever loop stopped working suddenly ( going by prints spewed out) all of a sudden but another set of threads that we added in runphase in another forever loop just to monitor those queues - keep printing that the queues have contents. So run-phase shouldn't be over but the checker tasks running in forever has stopped.
We are using Vivado 2020.2 for the simulation. This is a baffling/weird problem for us and we did go through prints multiple times to make sure nothing has been missed out. It seems we are missing very very basic or has hit a bug/broken some basics of UVM coding to land into here.
If you have any help, thoughts here, will appreciate that greatly.
The function phase_ready_to_end() gets called at the end of every task-based phase when all objections have been dropped (or never raised at all).
Typically a scoreboard has a queue or some kind of array of transactions waiting to be checked sent from a monitor via an analysis_port write() method. If your scoreboard is an in-order comparison checker, the queue size is zero when there are no more transactions waiting to be received.
If you look at the code in the link you shared, there is the following in the write_south method doing exactly that:
if (!item.compare(item_stream.pop_front()))

Why does the order of a dispatched print() change when run in a Playground?

In a Udacity's GCD course there was a small quiz:
let q = DispatchQueue.global(qos: .userInteractive)
q.async { () -> Void in
print("tic")
}
print("tac")
Which will be printed first?
The correct answer is: tac, then tic. Seems logical.
But, why is it so only when I create an Xcode project? In a playground it prints tic then tac. What am I missing?
In GCD
DispatchQueue.global(qos: .userInteractive).async{}
is below
DispatchQueue.main.async{}
Even thought it has quality of service (qos) as UI thread it does not means it is a main thread. So may be there is a difference in performance with play ground and ui project
please check apples documentation as well.
Apples documentation on GCD
key to your answer is in the question what really are you asking the "system" to do, an by system that is the whatever the code is running on the playground, your computer/phone or emulator. You are executing an asynchronous "block" of code - print("tic") with some priority ".userInteractive". If the system handles the asynchronous block first or continues with "normal" execution depends on priority and available resources. With asynchronous calls there is no real why to guarantee that it is executed before or after the code continues that is the nature of being asynchronous i.e execute the block as soon as the system allows it, all without blocking your current work. So the difference you are seeing in playground vs a project/emulator is that the project/phone/emulator must keep the UI/primary thread responsive so it continue with print("tac"), while the development playground favors the thread executing print("tic"). Bottom line is it has to deal with priority of execution and the available resources and how its implemented on the system you're running the code.

swift stop loop and continue it with a button

is it possible to stop an for in loop and continue it and the stopped position with a button.
i mean something like this:
for x in 0..<5 {
if x == 3 {
// show a button
// this button have to be pressed
// which do some tasks
// when all tasks are finished >
// continue this loop at the stopped point
}
}
is this possible? if yes, how?
Short answer: use a semaphore
Longer answer:
Your situation is an example of the more general case of how to pause some computation, saving its current state (local variables, call stack, etc.), and later to resume it from the same point, with all state restored.
Some languages/systems provide coroutines to support this, others the more esoteric call with current continuation, neither are available to you (currently) Swift...
What you do have is Grand Central Dispatch (GCD), provided in Swift through Dispatch, which provides support for executing concurrent asynchronous tasks and synchronisation between them. Other concurrency mechanisms such as pthread are also available, but GCD tends to be recommended.
Using GCD an outline of a solution is:
Execute you loop as an asynchronous concurrent task. It must not be executing on the main thread or you will deadlock...
When you wish to pause:
Create a semaphore
Start another async task to display the button, run the other jobs etc. This new task must signal the semaphore when it is finished. The new task may call the main thread to perform UI operations.
Your loop task waits on the semaphore, this will block the loop task until the button task signals it.
This may sound complicated but with Swift block syntax and Dispatch it is quite simple. However you do need to read up on GCD first!
Alternatively you can ask whether you can restructure your solution into multiple parts so saving/restoring the current state is not required. You might find designs such as continuation passing style useful, which again is quite easy using Swift's blocks.
HTH

State of the conditional variable in pthread_cond_

while writing a thread program i came across small issue.
The issue is: How do i know the state of a conditional variable
I mean to ask if a pthread is already waiting on pthread_cond_wait and if i again try to wait on the same conditional variable it leads to deadlock condition. Inorder to avoid this could you please suggest how do i know the state of a condvar before waiting on the same.

Is blocking on mutex equivalent to empty while cycle?

I'm writing a concurrency application for the iPhone.
I wonder if this code:
while(!conditionBoolean)
{
// do nothing
// until another thread makes this variable true.
}
makeWork();
Is equivalent to the following:
[lock lock]; // this lock is locked by another thread
// causing the current to block until it's unlocked
[lock unlock];
makeWork();
If it's not, what's the difference?
Thank you.
You should prefer the second, the first will produce a tight loop and delay or maybe even prevent the variable being set in the way you want/expect. At the very least you would have to introduce a delay in that loop, a sleep of some kind.
Better still would be to wait on a signalling primitive for the work to complete, which then gets signalled by the other thread - the design is then deterministic, versus depending on a mutex or state variable that some other thread might lock or modify before you get your chance. In general, it's better for a multi-threaded design to be event-driven (push model), not check shared state opportunistically (pull model).
My understanding of mutexes is that the lock can occur in less cycles, so for example it's possible that while you read the conditionboolean to become true, it's possible that another thread could still change it to true while you're reading it, and another goes to false before you read it again. This turns into a race condition, which the mutex locking would hope to avoid. Also this could cause your code not to be the "next in line" if you have numerous functions with a similar while loop.