Why do you need to use while loops as opposed to if statements when working with condition variables? - operating-system

There is all sorts of documentation online and in books that say that you should always use a while loop as opposed to an if statement when using condition variables, but I have never seen a clear explanation as to why. I understand spurious wakeups can occur, but if this happens, wouldn't the thread still be checking the condition of the if statement? What makes a while loop so different?
What is the difference in outcomes between these two snippets of pseudocode?
lock(mu)
count--;
unlock(mu)
if(count > 0) {
lock(mu)
wait(cond, mu)
unlock(mu)
}
else{
lock(mu)
signal(cond)
unlock(mu)
}
lock(mu)
count--;
unlock(mu)
while (count > 0) {
lock(mu)
wait(cond, mu)
unlock(mu)
}
lock(mu)
signal(cond)
unlock(mu)

The key difference between using a while loop and an if statement when using condition variables is that the former ensures that the thread will continue to check the condition even after it has been notified. In the case of a spurious wakeup, where the thread is awakened without the condition actually being met, the while loop will cause the thread to go back to sleep and continue waiting until the condition is actually satisfied.
In contrast, the if statement will only check the condition once, before the thread goes to sleep. If a spurious wakeup occurs, the thread will not go back to sleep and will continue execution without checking the condition again. This can lead to incorrect behavior and potential race conditions.
Therefore, using a while loop is recommended when using condition variables to ensure that the thread continues to check the condition until it is actually satisfied. This avoids potential issues with spurious wakeups and ensures that the thread behaves as expected.

Related

What is the order that reactive statements are executed in?

Let's say we have the following component script
let x = 0;
function increase() {
x += 1;
}
$: console.log(x)
$: if (x == 4) {
x = 0;
}
https://svelte.dev/repl/2bca979673114afea9fc6b37434653a3?version=3.29.0
Intuitively I would expect from cotinually calling increase, is to have the values 0,1,2,3,4,1,2,3,4,... logged to the console. But this is not the case. Instead, the second reactive statement runs first, and 4 is never logged; it is 0. Switching the order of the reactive statements has no effect.
How do you make the logging statement execute before the other one and what is the reason that it runs second, in the first place?
The order in which reactive statements that depends on the same variables are run is not specified / guaranteed by Svelte. You have to build your components with the expectation that they can be run in any order, and make sure that your code doesn't depend on any specific order.
You must not rely on a given order you observe in a specific case either -- it can change following a change in Svelte's internal implementation (e.g. new optimisations), or when the code of your own component changes (causing a different compiler output, that can change the order of reactive blocks for hard-to-anticipate reasons).
The reasons why this happens are highly technical (i.e. I don't really know), but they boil down to ease of implementation / optimization of the compiler. Reactive statements are a kind of async operations, that typically can't guarantee order of execution.
If you really need 2 operations to happen in a specific order then, for peace of mind, you need them in the same reactive block.
$: {
console.log(x) // op 1
if (x == 4) x = 0 // op 2
}

Why does pthread_cond_wait return if a breakpoint is set with Xcode 9?

The following swift code should block forever - pthread_cond_wait should never return as no one signals it.
When I run it - it blocks as expected.
If I so much as set a breakpoint using Xcode 9 (9.0.1) the execution continues to the print("hi") line.
Is this a strange Xcode bug or am I doing something totally wrong?
import Foundation
func check(_ ret:Int32){
if ret != 0 {
fatalError("Error \(ret)")
}
}
var cond = pthread_cond_t()
pthread_cond_init(&cond,nil)
var mutex = pthread_mutex_t()
check(pthread_mutex_init(&mutex,nil))
check(pthread_mutex_lock(&mutex))
check(pthread_cond_wait(&cond,&mutex))
print("Hi")
check(pthread_mutex_unlock(&mutex))
Also checked with pthread_cond_timedwait, same behaviour.
pthread_cond_wait can have spurious wakeups. POSIX is very explicit about this:
When using condition variables there is always a Boolean predicate involving shared variables associated with each condition wait that is true if the thread should proceed. Spurious wakeups from the pthread_cond_timedwait() or pthread_cond_wait() functions may occur. Since the return from pthread_cond_timedwait() or pthread_cond_wait() does not imply anything about the value of this predicate, the predicate should be re-evaluated upon such return.
It seems that in your environment, running under a debugger makes such wakeups happen, probably due to the extra signals the debugger triggers. It is certainly annoying if a debugger influences application behavior in such a way, but technically, it is not a bug.

Breaking when a method returns null in the Eclipse debugger

I'm working on an expression evaluator. There is an evaluate() function which is called many times depending on the complexity of the expression processed.
I need to break and investigate when this method returns null. There are many paths and return statements.
It is possible to break on exit method event but I can't find how to put a condition about the value returned.
I got stuck in that frustration too. One can inspect (and write conditions) on named variables, but not on something unnamed like a return value. Here are some ideas (for whoever might be interested):
One could include something like evaluate() == null in the breakpoint's condition. Tests performed (Eclipse 4.4) show that in such a case, the function will be performed again for the breakpoint purposes, but this time with the breakpoint disabled. So you will avoid a stack overflow situation, at least. Whether this would be useful, depends on the nature of the function under consideration - will it return the same value at breakpoint time as at run time? (Some s[a|i]mple code to test:)
class TestBreakpoint {
int counter = 0;
boolean eval() { /* <== breakpoint here, [x]on exit, [x]condition: eval()==false */
System.out.println("Iteration " + ++counter);
return true;
}
public static void main(String[] args) {
TestBreakpoint app = new TestBreakpoint();
System.out.println("STARTED");
app.eval();
System.out.println("STOPPED");
}
}
// RESULTS:
// Normal run: shows 1 iteration of eval()
// Debug run: shows 2 iterations of eval(), no stack overflow, no stop on breakpoint
Another way to make it easier (to potentially do debugging in future) would be to have coding conventions (or personal coding style) that require one to declare a local variable that is set inside the function, and returned only once at the end. E.g.:
public MyType evaluate() {
MyType result = null;
if (conditionA) result = new MyType('A');
else if (conditionB) result = new MyType ('B');
return result;
}
Then you can at least do an exit breakpoint with a condition like result == null. However, I agree that this is unnecessarily verbose for simple functions, is a bit contrary to flow that the language allows, and can only be enforced manually. (Personally, I do use this convention sometimes for more complex functions (the name result 'reserved' just for this use), where it may make things clearer, but not for simple functions. But it's difficult to draw the line; just this morning had to step through a simple function to see which of 3 possible cases was the one fired. For today's complex systems, one wants to avoid stepping.)
Barring the above, you would need to modify your code on a case by case basis as in the previous point for the single function to assign your return value to some variable, which you can test. If some work policy disallows you to make such non-functional changes, one is quite stuck... It is of course also possible that such a rewrite could result in a bug inadvertently being resolved, if the original code was a bit convoluted, so beware of reverting to the original after debugging, only to find that the bug is now back.
You didn't say what language you were working in. If it's Java or C++ you can set a condition on a Method (or Function) breakpoint using the breakpoint properties. Here are images showing both cases.
In the Java example you would unclik Entry and put a check in Exit.
Java Method Breakpoint Properties Dialog
!
C++ Function Breakpoint Properties Dialog
This is not yet supported by the Eclipse debugger and added as an enhancement request. I'd appreciate if you vote for it.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=425744

Why it is not possible to terminate loop from a signal handler in Perl?

Does anybody can explain why the next script does not work? What is the cause for the Label not found for "last SOME_BLOCK" error?
#!/usr/bin/perl
use v5.14;
SOME_BLOCK: {
alarm 1;
$SIG{ALRM} = sub {
last SOME_BLOCK;
};
my $count = 0;
while (1) {
$count += 1;
say $count;
}
};
Exiting a subroutine via last or next is forbidden according to perldoc (and generally triggers a warning). This is because it's quite messy - Perl would need to search dynamically up scopes to find the block that you're trying to skip, and call return from various functions (but what return value should be used?). return is generally safer.
In the signal handling context, it's extra messy because Perl actually has to pause execution of your script in order to execute the signal handler. So it's now running two separate execution contexts, and the signal handler context cannot affect the control flow of the main context directly, which is why you get that error.
There are two things you can do:
throw an exception (using die) and catch it in the outer block. This is undesirable, as it could interrupt pretty much anything.
set a global flag defined outside the signal handler e.g. ($caught_signal = 1) and check for that in the inner code at a convenient point.

return NOT exiting function properly in MATLAB

I'm running a recursive function which searches a room for an object. This code is working in conjunction with another process essentially running the same code. The first thing the code does is check to see if the other one has found the object and, if so, it is supposed to break out of the function.
When I do the check to see if the other process has found the object, if it has, I use "return" to break out of that function at which time it's supposed to move onto other lines of code...However, for some reason it doesn't fully break out but instead just runs the function again and again.
Any ideas on how I can get it to break out?
I would and can provide the code but it's kind of long
EDIT
Parent script
!matlab -r "zz_Mock_ROB2_Find" & distT = 0.3;
Rob1_ObjFound = 0;
matrix = search_TEST_cam(rob, vid, 0.3, XYpos, 'north', stack, matrix, 0);
disp('I"M OUT')
Recursive code
function matrix = search_TEST_cam(rob1, vid, distT, startingPos, currentDir, stack, matrix, bT)
Rob1_ObjFound = 0;
Rob2_ObjFound = 0;
try
load('Rob2_ObjFound.mat', 'Rob2_ObjFound');
catch
end
if(Rob2_ObjFound == 1)
setDriveWheelsCreate(rob1, 0, 0);
disp('ROB_2 FOUND THE OBJECT')
pause(0.5)
BeepRoomba(rob1)
pause(0.5)
setDriveWheelsCreate(rob1, 0, 0);
return
end
Use break to break out of a for or a while loop and terminate execution, i.e., statements after that are ignored. For e.g.,
for i=1:5
if i==3
break
else
fprintf('%u,',i)
end
end
outputs 1,2, and the code terminates when i=3. If you have nested loops, break will only break out of its current loop and move on to the parent loop.
To skip only the current iteration and move on to the next, use continue. Using the same example,
for i=1:5
if i==3
continue
else
fprintf('%u,',i)
end
end
outputs 1,2,4,5,.
Using return in a function just returns control to the parent function/script that called it.
It seems like you're using the wrong one in your code. However, it's hard to tell without knowing how you're using them. Anyway, you can try one of these three and see if it makes a difference.
It's hard to say without seeing your code, but I doubt it's a problem with the RETURN statement. It's more likely a problem with how you've set up your recursion. If your recursive function has called itself a number of times, then when you finally invoke a RETURN statement it will return control from the current function on the stack to the calling function (i.e. a previous call to your recursive function). I'm guessing the calling function doesn't stop the recursion properly and ends up calling itself again, continuing the recursion.
My advice: check the exit conditions for your recursive function to make sure that, when the object is found and the most recent call returns, every previous call is properly informed that it should return as well.