In order to gurantee Bounded wait in Test and set Instruction,following is the code given in Operating system book,Galvin -:
do {
1 waiting[i] = true;
2 while (waiting[i] && test_and_set(&lock)) ;
3 waiting[i] = false;
/* critical section */
4 j = (i + 1) % n;
5 while ((j != i) && !waiting[j])
6 j = (j + 1) % n;
7 if (j == i)
8 lock = false;
9 else
10 waiting[j] = false;
/* remainder section */
} while (true);
I am getting the complete code and concluded that
A process P_i will be in the critical section if either
Waiting [i]=false or test_and_set(&lock)=FALSE which ensures that Lock was FALSE previously. so Exit Section is either setting Waiting[j] or lock to FALSE.
But i have got some doubts-:
if in the exit section section it is found that same process again requests for critical section i.e
if j==i
then according to the code,that process have to start its execution form line number 2,i.e will execute
test_and_set(&lock))
in while loop and find the return value of test_and_set(&lock)) as false and then move to critical section.My doubt is that if same process wants to be in critical section ,is it necessary to start its exection right from line number 2
2.Now i want to do following Permutation and want to check the possible outcome.i want to swap line number 8 and 10
in line number 8 if i make
waiting[j]=false;
then also it will move to critical section even though lock =true now.
in line number 10 if i make
lock=false
then also it(process p_j) will move to critical section even though waiting[i]=true and i think it would be better because line number 3 will assign waiting[i]=false ,after the while loop breaks due to test_and_set(&lock)=false.
On the other hand if i make this change process have to execute test_and_set(&lock) which is time consuming
Is my assumption for point2 right?
what is the correct reason for point 1?
Thanks
Regarding point 1:
My doubt is that if same process wants to be in critical section ,is
it necessary to start its exection right from line number 2
A process is basically an program in execution. A process just cannot jump around choosing which instruction to execute next. The control flow decides that. The control of the code(which is the process itself) suggests that if a process successfully enters critical section, and again wants to enter critical section, then it will first execute lines 4 to 10 and then execute remainder section and would have to start execution right from line 1
Regarding your point 2
Now i want to do following Permutation and want to check the possible
outcome.i want to swap line number 8 and 10
If you swap the lines, the bounded waiting condition would no longer exist.
Proof
Suppose that only 1 process P(i) made the request to access Critical Section and it successfully entered. So
lock = true and waiting[i] = true
because only then it would have been able to come out of the for loop. Now it starts executing from line 4
Then j takes following values:
i + 2 , i + 3, ......0 , 1 , 2 , 3 , 4....i
wrap around of values occurs because of % operator. And Because no other process made request to enter critical section, waiting[j] = false for j != i
Therefore the condition while ((j != i) && !waiting[j]) becomes false when j equals i, and now we are at line 7. The new code is:
if (j == i)
waiting[j] = false;
else
lock = false;
Now if any process makes a request to enter critical section, then while (waiting[i] && test_and_set(&lock)) ; would always evaluate to true because lock is true and waiting[i] is also true and it would be stuck in spinlock. There would be no progress.
Related
I am using a Queue and hold block together, where the hold remains blocked until all the agents arrive at the Queue block.
How to change it and want to allow only a fixed number of agents (say 5 agents) at fixed intervals of time(say every 3 minutes)? Current properties of my Queue and hold block:
queue_block_properties
hold_block_properties
Create a cyclic event with recurrence time 3 minutes.
Also create a variable which you can name count of type int.
In the event action field write:
count = 0;
hold.unblock();
Then, in the On enter field of the hold block write the following:
count++;
if( count == 5 ) {
self.block();
}
The only question that I have is whether you want every 3 minutes to have exactly 5 agents leave or whether it's okay if they arrive a bit later. In other words if after 3 minutes, there are only 3 agents in the queue, do they leave and the hold remains unblocked in case another 2 arrive before the next cycle? Or does the hold block blocks again immediately?
In the solution I provided, if there are less than 5 at the cycle time occurrence, and then new agents arrive before the next cycle, they can pass.
Otherwise, create a new variable called target for example and write the following in the event action:
count= 0;
if( queue.size() >= 5 ) {
target = 5;
hold.unblock();
}
else if ( queue.size() > 0 ) {
target = queue.size();
hold.unblock();
}
And in the on enter of the hold, write:
count++;
if( count == target ) {
self.block();
target = 0;
}
I would advise to not use a hold block for such delicate control of releasing agents. Instead, I would propose a simpler solution.
Simply let the agents build up in the queue and then you remove them using an event. The only action for this event is to remove the minimum between your set number of agents and the queue size, from the queue and send them to an enter block. The enter block is where your process flow then continues. See the screenshot below.
Code in the event is
for (int i = 0; i < min(5, queue.size()); i ++){
enter.take(queue.remove(0));
}
On that note, you can also use the Wait block (Which is hidden in the Auxillary section in the PML library
Then you can ditch the enter block and simply call the following code
for (int i = 0; i < min(5, wait.size()); i ++){
wait.free(wait.get(0));
}
Consider the following Barrier method to implement synchronization :
void barrier
{
P(s);
process_arrived++;
V(s);
while(process_arrived != 3);
P(s);
process_left++;
if(process_left == 3)
{
process_Arrived = 0;
process_left = 0;
}
V(s);
}
It is known that this code does not work because of a flaw, but I am not able to find the flaw.
The problem is with the condition : if (process_left == 3)
It may lead to deadlock if two barrier invocations are used in immediate succession.
Initially, process_arrived and process_left will be '0'.
When a process arrives, it increments process_arrived and waits till maximum number of processes have arrived. After that processes are allowed to leave.
Consider the following scenario:
P1 comes and waits till process_arrived becomes 3 ( currently process_arrived = 1)
P2 comes and waits till process_arrived becomes 3 ( currently process_Arrived = 2)
Now P3 comes for execution. The condition in while loop fails and executes further, making process_left = 1 and again enters the function immediately.
It makes process_Arrived = 4 and waits in while loop.
P2 gets a chance to execute makes process_left = 2 and leaves.
P1 executes further and finds that process_left = 3, thereby making both process_arrived and process_left = 0. (Remember that P3 has already entered and is waiting at the barrier, so here a count is lost)
P1 again executes , makes process_arrived = 1 and waits.
P2 also executes again. makes process_arrived = 2 and waits.
Now every process will wait for ever. Hence a deadlock has occurred.
options = optimset('Display','iter','MaxIter',3,'OutputFcn',#outfun);
[x,fval,~,output] = fminsearch(#(param) esm6(param,identi),result(k,1:end-1),options);
This code will find the local Minimum of my esm6 function and due to the 'Display' Option it will Output strings like this
Iteration Func-count min f(x) Procedure
0 1 36.9193
1 5 35.9815 initial simplex
2 7 35.4924 contract inside
3 9 35.4924 contract inside
4 11 33.0085 expand
So in the command window, i get the function Count for each Iteration step. The structure output, which is created by fminsearch has only the total amount of func-count in it. Is there a way to receive all the Information, that is outputed in the command window also in the Output-structure?
EDIT:
I think i'm pretty Close to the solution. I wrote this outputfunction:
function stop = outfun(x,optimvalues,state);
stop = false;
if state == 'iter'
history = evalin('base','history');
history = [history; optimvalues.iteration optimvalues.funcCount];
assignin('base','history',history);
end
end
due to http://de.mathworks.com/help/matlab/math/output-functions.html this should work, but in fact, matlab tells me,
??? Reference to non-existent field 'funcCount'.
any idea, why this happens?
I was watching the talk given by Martin Odersky as recommended by himself in the coursera scala course and I am quite curious about one aspect of it
var x = 0
async { x = x + 1 }
async { x = x * 2 }
So I get that it can give 2 if if the first statement gets executed first and then the second one:
x = 0;
x = x + 1;
x = x * 2; // this will be x = 2
I get how it can give 1 :
x = 0;
x = x * 2;
x = x + 1 // this will be x = 1
However how can it result 0? Is it possible that the statement don't execute at all?
Sorry for such an easy question but I'm really stuck at it
You need to think about interleaved execution. Remember that the CPU needs to read the value of x before it can work on it. So imagine the following:
Thread 1 reads x (reading 0)
Thread 2 reads x (reading 0)
Thread 1 writes x + 1 (writing 1)
Thread 2 writes x * 2 (writing 0)
I know this has already been answered, but maybe this is still useful:
Think of it as a sequence of atomic operations. The processor is doing one atomic operation at a time.
Here we have the following:
Read x
Write x
Add 1
Multiply 2
The following two sequences are guaranteed to happen in this order "within themselves":
Read x, Add 1, Write x
Read x, Multiply 2, Write x
However, if you are executing them in parallel, the time of execution of each atomic operation relative to any other atomic operation in the other sequence is random i.e. these two sequences interleave.
One of the possible order of execution will produce 0 which is given in the answer by Paul Butcher
Here is an illustration I found on the internet:
Each blue/purple block is one atomic operation, you can see how you can have different results based on the order of the blocks
To solve this problem you can use the keyword "synchronized"
My understanding is that if you mark two blocks of code (e.g. two methods) with synchronized within the same object then each block will own the lock of that object while being executed, so that the other block cannot be executed while the first hasn't finished yet. However, if you have two synchronised blocks in two different objects then they can execute in parallel.
I am trying to write a rule to detect if a given event has occurred for 'n' number times in last 'm' duration of time.
I am using drools version 5.4.Final. I have also tried 5.5.Final with no effect.
I have found that there are a couple of Conditional Elements, as Drools call it, accumulate and collect. I have used collect in my sample rule below
rule "check-login-attack-rule-1"
dialect "java"
when
$logMessage: LogMessage()
$logMessages : ArrayList ( size >= 3 )
from collect(LogMessage(getAction().equals(Action.Login)
&& isProcessed() == false)
over window:time(10s))
then
LogManager.debug(Poc.class, "!!!!! Login Attack detected. Generating alert.!!!"+$logMessages.size());
LogManager.debug(Poc.class, "Current Log Message: "+$logMessage.getEventName()+":"+(new Date($logMessage.getTime())));
int size = $logMessages.size();
for(int i = 0 ; i < size; i++) {
Object msgObj = $logMessages.get(i);
LogMessage msg = (LogMessage) msgObj;
LogManager.debug(Poc.class, "LogMessage: "+msg.getEventName()+":"+(new Date(msg.getTime())));
msg.setProcessed(true);
update(msgObj); // Does not work. Rule execution does not proceed beyond this point.
// retract(msgObj) // Does not work. Rule execution does not proceed beyond this point.
}
// Completed processing the logs over a given window. Now removing the processed logs.
//retract($logMessages) // Does not work. Rule execution does not proceed beyond this point.
end
The code to inject logs is as below. The code injects logs at every 3 secs and fires rules.
final StatefulKnowledgeSession kSession = kBase.newStatefulKnowledgeSession();
long msgId = 0;
while(true) {
// Generate Log messages every 3 Secs.
// Every alternate log message will satisfy a rule condition
LogMessage log = null;
log = new LogMessage();
log.setEventName("msg:"+msgId);
log.setAction(LogMessage.Action.Login);
LogManager.debug(Poc.class, "PUSHING LOG: "+log.getEventName()+":"+log.getTime());
kSession.insert(log);
kSession.fireAllRules();
LogManager.debug(Poc.class, "PUSHED LOG: "+log.getEventName()+":"+(new Date(log.getTime())));
// Sleep for 3 secs
try {
sleep(3*1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
msgId++;
}
With this, what I could achieve is checking for existence of the above said LogMessage in last 10 secs. I could also find out the exact set of LogMessages which occurred in last 10 secs triggering the rule.
The problem is, once these messages are processed, they should not take part in next cycle of evaluation. This is something which I've not be able to achieve. I'll explain this with example.
Consider a timeline below, The timeline shows insertion of log messages and the state of alert generation which should happen.
Expected Result
Secs -- Log -- Alert
0 -- LogMessage1 -- No Alert
3 -- LogMessage2 -- No Alert
6 -- LogMessage3 -- Alert1 (LogMessage1, LogMessage2, LogMessage3)
9 -- LogMessage4 -- No Alert
12 -- LogMessage5 -- No Alert
15 -- LogMessage6 -- Alert2 (LogMessage4, LogMessage5, LogMessage6)
But whats happening with current code is
Actual Result
Secs -- Log -- Alert
0 -- LogMessage1 -- No Alert
3 -- LogMessage2 -- No Alert
6 -- LogMessage3 -- Alert1 (LogMessage1, LogMessage2, LogMessage3)
9 -- LogMessage4 -- Alert2 (LogMessage2, LogMessage3, LogMessage4)
12 -- LogMessage5 -- Alert3 (LogMessage3, LogMessage4, LogMessage5)
15 -- LogMessage6 -- Alert4 (LogMessage4, LogMessage5, LogMessage6)
Essentially, I am not able to discard the messages which are already processed and have taken part in an alert generation. I tried to use retract to remove the processed facts from its working memory. But when I added retract in the then part of the rule, the rules stopped firing at all. I have not been able to figure out why the rules stop firing after adding the retract.
Kindly let me know where am I going wrong.
You seem to be forgetting to set as processed the other 3 facts in the list. You would need a helper class as a global to do so because it should be done in a for loop. Otherwise, these groups of messages can trigger the rule as well:
1 no triggering
1,2 no triggerning
1,2,3 triggers
2,3,4 triggers because a new fact is added and 2 and 3 were in the list
3,4,5 triggers because a new fact is added and 3 and 4 were in the list
and so on
hope this helps