Consider we use a single lock variable to solve the mutual exclusion problem as in the code below? - operating-system

boolean lock = false;
// in thread 1
while (true) {
if (lock) {
lock = true;
criticalRegion1();
lock = false;
}
}
// in thread 2
while (true) {
if (!lock) {
lock = true;
criticalRegion(2);
lock = false;
}
}
Does this work correctly? If yes, explain how. If no, describe how the program can execute resulting in a race condition?

This is a homework question. To find the right answer for this (and for most things involving race conditions in general):
Break the code that each thread does into "atomic pieces". For example, something like x++; should be considered three steps (temp = x; temp++; x = temp; where temp is a register and not a variable). Forget about things that don't have globally visible state (e.g. accessing a local variable isn't important because a different thread won't care, but accessing a global variable is important because a different thread will see or effect it).
Next; imagine every possible order that these "important atomic pieces" could be done in; and see if there's a problem.
For example, if one thread has 2 atomic pieces A and B; and if the other thread has 2 atomic pieces C and D; then you would want to consider:
A, B, C then D
A, C, B then D
C, A, B then D
A, C, D then B
C, A, D then B
C, D, A then B
Note: This sounds like a lot of work at first; but it won't take much practice before you're able to quickly skip "not likely to be a problem" cases and focus on "more likely to be a problem" cases.

Related

PureScript - Simple Multiline Computation

Consider the following JavaScript function, which performs a computation over several lines to clearly indicate the programmer's intent:
function computation(first, second) {
const a = first * first;
const b = second - 4;
const c = a + b;
return c;
}
computation(12, 3)
//143
computation(-3, 2.6)
//7.6
I have tried using do notation to solve this with PureScript but I seem to be just short of understanding some key concept. The do notation examples in the documentation only covers do notation when the value being bound is an array (https://book.purescript.org/chapter4.html#do-notation), but in my example I would like the values to be simple values of the Int or Number type.
While it is possible to perform this computation in one line, it makes the code harder to debug and does not scale to many operations.
How would the computation method be written correctly in PureScript so that...
If computation involved 1000 intermediate steps, instead of 3, the code would not suffer from excessive indenting but would be as readable as possible
Each step of the computation is on its own line, so that, for example, the code could be reviewed line by line by a supervisor, etc., for quality
You don't need the do notation. The do notation is intended for computations happening in a monad, whereas your computation is naked.
To define some intermediate values before returning result, use the let .. in construct:
computation first second =
let a = first * first
b = second - 4
c = a + b
in c
But if you really want to use do, you can do that as well: it also supports naked computations just to give you some choice. The difference is that within a do you can have multiple lets on the same level (and they work the same as one let with multiple definitions) and you don't need an in:
computation first second = do
let a = first * first -- first let
b = second - 4
let c = a + b -- second let
c -- no in

isdigit function for BCPL

I am currently programming in BCPL for an OS course and wanted to write a simple is_digit() function for validation in a program of mine.
A code snippet of my current code follows:
let is_digit(n) be {
if ((n >= '0') /\ (n <= '9')) then
resultis true;
}
I am aware that BCPL has no notion of types, but how would I be able to accomplish this sort of thing in the language?
Passing in a number yields a false result instead of the expected true.
is_digit() is a function returning a value, rather than a routine, so should use = VALOF rather than BE. Otherwise, the code is OK.
let is_digit(n) = valof {
.....
resultis true
}
Functions that return values should be using valof rather than be, the latter (a routine rather than a function) can be called as a function but the return value you get back from it will be undefined(a).
In addition, you should ensure you return a valid value for every code path. At the moment, a non-digit will not execute a RESULTIS statement, and I'm not entirely certain what happens in that case (so best to be safe).
That means something like this is what you're after, keeping in mind there can be implementation variations, such as & and /\ for and, or {...} and $(...$) for the block delimiters - I've used the ones documented in Martin's latest manual:
LET is_digit(n) = VALOF {
RESULTIS (n >= '0') & (n <= '9')
}
(a) Since Martin Richards is still doing stuff with BCPL, this manual may help in any future questions (or see his home page for a large selection of goodies).

How can unique-case violations be caught by or report to the test-bench

The goal is to create a mechanism to automatically catch unqiue case violations and have them reported to the test-bench for error counting during simulation. The log files can be huge making post processing less practical. Manually creating assertions is error prone (especially when then one-hot condition is not a continuous bus like the code below) and and a never ending assignment while the design is in development.
always_comb begin
unique case(1'b1)
a[3] : b = 4'h3;
a[2] : b = 4'h2;
c[10] : b = 4'hE;
c[8] : b = 4'h4;
endcase
end
I can enable/disable the reporting for unique case violations with $assertcontrol, therefore I believe it is possible to use VPI callback, but I'm having trouble using vpi_iterate() to find the unique case, currently I'm slowly traversing the design trying to figure out when to pass what kind of object my vpiHandle is pointing to. I tried vpi_iterate(vpiCallback, NULL), but my simulator returns a a massage stating vpiCallback has not been implemented yet.
The simulator is reporting unique case violations to the log file. So how can I get my test-bench to detect it?
I don't have the full answer yet, but here's something to get you started. I added your always_comb block to a module:
module some_module();
logic [3:0] a;
logic [3:0] b;
logic [8:0] c;
always_comb begin : always_comb_proc
unique case(1'b1)
a[3] : b = 4'h3;
a[2] : b = 4'h2;
c[10] : b = 4'hE;
c[8] : b = 4'h4;
endcase
end
initial begin
$add_cbs();
end
endmodule
I created a VPI system task that can find the handle to the unique case. It's just a matter of traversing the hierarchy:
void add_cbs_calltf() {
// getting the module could be more elegant
vpiHandle mod = vpi_handle_by_name("some_module", NULL);
// there's only one process - the 'always_comb'
vpiHandle proc_it = vpi_iterate(vpiProcess, mod);
vpiHandle proc = vpi_scan(proc_it);
// each 'always' process has an event control
// - for 'always_comb', this is implicit
vpiHandle ev_ctrl = vpi_handle(vpiStmt, proc);
// the event control contains the 'begin/end' statement
vpiHandle named_begin = vpi_handle(vpiStmt, ev_ctrl);
// finally, a 'begin/end' statement can contain other statements
// - the one and only in this case is the 'unique case'
vpiHandle stmt_it = vpi_iterate(vpiStmt, named_begin);
vpiHandle stmt = vpi_scan(stmt_it);
vpi_printf("stmt type = %s\n", vpi_get_str(vpiType, stmt));
vpi_printf("stmt case type = %d\n", vpi_get(vpiCaseType, stmt));
vpi_printf("stmt case qualifier = %d\n", vpi_get(vpiQualifier, stmt));
}
I still don't know how to add a callback when the "assertion" triggers, but this should be a step in the right direction. I'll probably look into it and update the answer.

Execution order in Scala for/yield block

I make three database calls (that all return Future values) using this syntax:
for {
a <- databaseCallA
b <- databaseCallB(a)
c <- databaseCallC(a)
} yield (a,b,c)
The second and third call depend on the result of the first, but the two of them could be run in parallel.
How can I get databaseCallC to be issued immediately after databaseCallB (without waiting for the result b)?
Or is this already happening?
This is not happening currently - you have told the Futures to start one after the other. To parallelise the second and third call, you could use this:
for {
a <- databaseCallA
(eventualB, eventualC) = (databaseCallB(a), databaseCallC(a))
b <- eventualB
c <- eventualC
} yield(a,b,c)
This will start both the computation of b and c as soon as a is available, and complete once all three are available with the triple

Simultaneous assignment in Go

I'm learning Go and can't understand one thing, why creators of this language do support simultaneous assignment? It is very easy to make mistakes like a, b = a, b and not a, b = b, a, as I would want, thanks in advance for any good explanations.
It is very easy to make mistakes like a, b = a, b and not a, b = b, a,
If simultaneous assignment were not available then you would have to do something else instead. An alternative approach might look something like this:
tmp = a
a = b
b = tmp
That's much easier to get wrong.
How else would you get access to the second, third, fourth, … return value of a function?