I want to find the expexted hazards until CC7(clock cycle 7) with appropriate reasons and solution - cpu-architecture

I want to find the expexted hazards in below code until clock cycle 7 with appropriate reasons and solution.
1: sub $2,$2,$3
2: lw $4, 0($2)
3: and $1,$4,$2
4: beq $1,$2,1
5: or $5,$1,$6
6: add $2,$5,$3
In my opinion
line2: Ex hazard (solution is forwarding)
line3: Ex hazard , mem hazard (solution is forwarding and add one bubble)
line5: Condition hazard
line6: Ex hazard (forwarding)
I want solve this problem...

You are mostly correct.
Let's further discuss that: instruction #3 has two hazards, both $4 and $2 are RAW dependencies of prior instructions.  Though the insertion of the bubble to cover the MEM-to-EX hazard delays instruction #3, it will still read a stale value for $2 so that other delay doesn't help: it will need a forward for that register as well.
You've missed the EX hazard with $1 on instruction #4.
Instruction #5 also has a RAW hazard on $1, and this will require forwarding, because instruction #5's ID stage (assuming branch not taken) overlaps with instruction #3's MEM stage, which is not sufficient to avoid the hazard of stale values in RAW dependencies.

Related

arm64 ptrace SINGLESTEP: are the steps described in this paper correct?

I was reading the paper Hiding in the Shadows: Empowering ARM for Stealthy Virtual Machine Introspection and I was wondering whether the steps they are described in paragraph "2.3 Debug Exceptions" were correct or not:
AArch64 allows to generate Software Step exceptions by setting the SS
bit of the Monitor Debug System Control MDSCR_EL1 and Saved Program
Status Register SPSR of the target exception level. For instance, to
single-step a hit breakpoint in EL1 the monitor must set the
MDSCR_EL1.SS and SPSR_EL1.SS bits. After returning to the trapped
instruction, the SPSR will be written to the process state PSTATE
register in EL1. Consequently, the CPU executes the next instruction
and generates a Software Step exception.
I have tried to understand how single-stepping happens in freeBSD, and I am noticing a mismatch.
I am basing the following lines of code to the release 12.3.0 of freeBSD (4 December 2021), commit: 70cb68e7a00ac0310a2d0ca428c1d5018e6d39e1. I chose to base this question on freeBSD because, in my opinion, following its code is easier than Linux, but the same principles shall be common to both families.
According to my understanding, this is what happens in freeBSD:
1- Ptrace single step is invoked, arriving in the architecture-independent code proc_sstep(), in sys_process.c:
int proc_sstep(struct thread *td)
{
PROC_ACTION(ptrace_single_step(td));
}
2- Architecture-dependent code ptrace_single_step()is called, in arm64/ptrace_machdep.c:
int ptrace_single_step(struct thread *td)
{
td->td_frame->tf_spsr |= PSR_SS;
td->td_pcb->pcb_flags |= PCB_SINGLE_STEP;
return (0);
}
Here single step bit (number 21) is set in the "Process State" of the tracee (tracee = thread that is traced) and a flag is set.
3- After a while, the traced task will be selected for scheduling. In cpu_throw() of swtch.S (where the new thread takes place), the flags of the new thread are checked, to see if it must single step:
/* If we are single stepping, enable it */
ldr w5, [x4, #PCB_FLAGS]
set_step_flag w5, x6
4- set_step_flag macro in defined in the same swtch.S:
.macro set_step_flag pcbflags, tmp
tbz \pcbflags, #PCB_SINGLE_STEP_SHIFT, 999f
mrs \tmp, mdscr_el1
orr \tmp, \tmp, #1
msr mdscr_el1, \tmp
isb
999:
.endm
Here, if the single-step flag is set, it sets the single step bit of register MDSCR_EL1 (bit in position 0).
4- To the best of my understanding, the combination of single step bit on SPSR_EL1 of the "Pstate" + single step bit on MDSCRL_EL1 implies that the tracee execute 1 instruction and it traps.
5- Trap is recognized as a EXCP_SOFTSTP_EL0 and it is handled in do_el0_sync() function of trap.c:
case EXCP_SOFTSTP_EL0:
td->td_frame->tf_spsr &= ~PSR_SS;
td->td_pcb->pcb_flags &= ~PCB_SINGLE_STEP;
WRITE_SPECIALREG(mdscr_el1,
READ_SPECIALREG(mdscr_el1) & ~DBG_MDSCR_SS);
call_trapsignal(td, SIGTRAP, TRAP_TRACE,
(void *)frame->tf_elr, exception);
userret(td, frame);
break;
Here, all the flags are reset and the traced thread receives a SIGTRAP (sent by itself, I think). Being traced, it will stop. And the tracer, at this point, can return from a possible waitpid().
What I could observe differs from the paper explanation. Can you check and correct the steps that I listed, please ?

I got error while simulate code written in PROMELA

I am using ispin and got an error stating spin: trails end after 10 steps and transition fail.
How can I prevent this error from happening?
You prevent the error from happening in one of two ways:
fix your Promela model - you have a bug in your Promela that needs to be removed
you've found an error in the system that you are modeling. Congratulations. You now report the error to the person in charge of the system that you are modeling.
In practice, when you have a trail indicating an error, you next perform
spin -p -t <name of the model>.pml
which will print out the step by step model executions that lead to the error. You scour them to confirm that they are correct - if so, see #2 above; if not correct, see #1.
I had the same problem and it is fixed after putting -DVECTORSZ :
in the advanced parameters settings window of verification tab.I have also increased the physical memory to 2048.

Getting Updated Value while using lock?

this is my first Procedure.
define frame LockFrame Customer.Name Customer.CreditLimit Customer.Balance.
pause.
DO TRANSACTION:
for each Customer exclusive-lock:
assign Customer.CreditLimit = Customer.CreditLimit + 5.
pause 1 no-message.
display Customer.Name Customer.CreditLimit Customer.Balance.
end.
end.
and thsi is my second Procedure.
define frame LockFrame Customer.Name Customer.CreditLimit Customer.Balance.
pause.
DO TRANSACTION:
for each Customer exclusive-lock:
assign Customer.Balance= Customer.Balance + 2.
pause 1 no-message.
display Customer.Name Customer.CreditLimit Customer.Balance.
end.
end.
When I run first Procedure and just after second procedure, I have to get the value Updated by first (here CrditLimit).(and vice versa)
But I am not able to run second since the record is locked by the first.It is showing an error message.
I think problem is with my locking.Please help on this.
This is exactly what you should expect.
The record is locked, exclusively for the benefit of the first procedure, until the transaction commits. The commit will occur at the 2nd END statement.
I'm not sure why you have PAUSE in there -- you should never block on IO inside a transaction block -- that will only lead to problems (like users locking each other while they get up and go get coffee...)
You almost NEVER really want to enclose an update of an entire table in a transaction (which is what your DO TRANSACTION block is doing). Even if you think that is what you want to do, or have been told that that is what you must do it is probably wrong. This is usually the result of confusing a "business transaction" with a "database transaction" -- they are not the same thing -- especially when large amounts of data are in play.
A better way to write your code (apply the same concept to both samples):
define buffer updCustomer for customer.
for each customer no-lock /* where whatever */:
/* maybe some no-lock logic... */
do for updCustomer transaction:
find updCustomer exclusive-lock where recid( updCustomer ) = recid( customer ).
assign
updCustomer.creditLimit = customer.creditLimit + 5.
.
display
updCustomer.name
updCustomer.creditLimit
updCustomer.balance
.
end.
pause 1 no-message.
end.
Using NO-LOCK on the FOR EACH allows selection logic or other logic to run without needing the lock. Using the update buffer and the DO FOR ... TRANSACTION block tightly scopes the record lock and the transaction to that single block. Placing the PAUSE outside the block prevents the "user goes to get coffee" problem.
I hesitate to comment on any answer that Tom has given, since I consider him authoritative. But I want to point out two small things.
First of all, the use of RECID might be better as ROWID. ROWID is recommended for use by Progress (see http://documentation.progress.com/output/OpenEdge102a/oe102ahtml/wwhelp/wwhimpl/common/html/wwhelp.htm?context=dvref&file=dvref-15-48.html) since RECID is "supported for backward compatibility. For most applications, use the ROWID function, instead."
But that's minor, really. What's also important in my opinion is what Tom did in his example for you - he defined a buffer ("define buffer updCustomer for customer.") that he used in the update. I want to encourage you to use buffers EVERY time you work with a record, especially if you get into using persistent or super procedures, or if you are using functions or internal procedures.
Why? Defining a buffer ensures that the scope of the buffer you are updating is limited to the place where you defined it. As an example, Progress will "leak" the default buffer into your super procedure if you aren't careful. Imagine this scenario...a program that finds a record, calls a function in a super procedure to do "some stuff" and then deletes the record.
FIND MyTable WHERE MyTable.fk = fkValue NO-LOCK NO-ERROR.
UpdateOtherStuff(MyTable.fkValue).
DeleteMyRecord(MyTable.fkValue).
But in "UpdateOtherStuff", it does some work including this...
FOR EACH MyTable:
If MyTable.Thing = 'ThingOne' THEN LEAVE.
/* other processing here... */
END.
You might be surprised when you find that the super procedure shares the default "MyTable" buffer with your program, and ends up repositioning the record somewhere you don't want...so that the call to "DeleteMyRecord()" has a different record than you expect.
The problem would be solved if "UpdateOtherStuff" had a "DEFINE BUFFER ... FOR MyTable" at the top, even if it was "DEFINE BUFFER MyTAble for MyTable" (strange as that looks...).
That's why Tom's example, including a DEFINE BUFFER..., should be a template for the work you do in the ABL.
This question was asked previously - see https://stackoverflow.com/a/5490130/1433147.

What is a Flag in CX-Programmer?

During the reading of PLC documentation (Omron CP1L PLC and CX-Programmer), there are some missing explanation. For example, it defines "Flag" as "a bit that serves as an interface between in*struction", does that mean flag is some sort of conditional Power Flow?
It gets more confusing with the terms "Differential Up/Down", "Carry Flag"? What are flags and what do they do in the ladder logic? Are they a simple or instruction to use or just a concept that I don't really need to program in ladder?
[EDITED]
Where to add / modify / delete the flag in an instruction? I open up the edit but flag isn't there.
Ok, this is a better question.
PLCs are like any program - data is stored as different types. Think of flags as interchangeable with the term "bit", "boolean", etc. They are very important.
If you have CX-Programmer, a much better place to get information is the Instruction Reference (Help --> Instruction Reference --> yourPLC). These show time diagrams of most of the instructions and how each of the parameters and flags operate.
For example, a basic timer (TIM) works by assigning it a value. If you use a BCD type 100ms timer and assign its SV (setpoint value) a BCD value of 300 then you have created a timer with a 30 second limit (300 x 100ms). When the timer turns on it will begin counting and the PV (process value) will start from 300 and count down. When the value reaches zero the timer's flag turns ON to indicate that it has expired. If the timer's number is, say T100 then you can use T100 as a contact in another rung of logic - it will be true when the timer's execution conditions are TRUE and the timer has expired.
Differentials (UP/DOWN) are special flags which are true for only one PLC scan (ie: they are true for one execution cycle only) when their input conditions change from FALSE to TRUE (ie:OFF to ON) for UP differentials, and TRUE to FALSE (ie:ON to OFF) for DOWN differentials. You would use differentials in cases where you wanted to perform an action the moment a given condition changes.
Flags can be used for almost anything. You can use them as general booleans in your own programs, they can be parts of certain operations (ie: the CY (carry) flag is used on arithmetic operations which result in a carry - other flags are used to indicate overflows or div/0 errors, etc).
Edit again : (to answer extended question).
A basic timer's completion flag is a contact with its number. Say I have a 100ms timer, T100, which turns on when contact 10.00 is on:
10.00 ___
|-----| |---------------------------------------|TIM|
|100|
| |
|#20|
|___|
Now, once 10.00 has been ON for two seconds, the timer will elapse and the flag for timer 100, T100, will turn ON. If I had another rung where
| T100 W15.00
|-----| |-----------------------------------( )
Then work bit W15.00 would be turned on when the timer elapsed and would remain on so long as the timer's input condition remained satisfied (ie: so long as 10.00 remains ON). Flags work in different ways for different things, however. Each operation can use them in different ways.
The example from the Omron Instruction Reference (Help -> Instruction Reference -> [select PLC]) looks like this :
Well very good explanation with example and the flags value can be found in memory area it is pure binary either 0 or 1, as i was read the documentation work-bit memory location changes as per timer type e.g TIM/TIMX or TIMH or TIMHX, both are BCD timers but unit for the timer changes.

Question on critical section algorithm

The Operating System Concepts 6th edition present one trival algorithm to implementate ciritical section.
do{
while (turn != i);
critical section
trun = j;
remainder section
} while(1);
Note,Pi is the process with identifier i,Pj is the process with identifier j.To simlify the question,the book limit the i,j to 0 and 1,the two processes constriant enviroment.
Question1 is,dose this algorithm voilate the Progress requirement which is one of the three requirements to ciritical section solution?
In my opinion,when Pi is in its remainder section,it cannot participate in the decision on whether Pj can enter the critical section.Then it is bound to the requirement.
Or my understanding of progress requirement is totally wrong.So because if Pi retired from the remainder section,It could not get into the cirtical section immediate,this alg violate the rule.
Question2,
If turn == 0 and P1 is ready to enter
itscritical section,P1 cannot do
so,even thought P0 may be in its
remainder section
Whats the meaning of this statement?As far as I could think,I could not understand why turn == 0 and p0 be in its remainder section could be exist concurrently...
So is this statement wrong?
Suppose that turn = 0 initially. P0 does its critical section and sets turn = 1. Now, P1 must execute its critical section before P0 may execute its one again. But just because both threads have a critical section doesn't mean that they're going to want to alternate their use of it in this way — in fact, P1 may never take its turn. (And in the general case, you can't determine this at compile time.)
So basically the problem is that the threads are forced to alternate their turns, even if one of them actually doesn't want to enter its critical section for an indefinitely long time.
By the way, your answer to Question 1 is correct. The algorithm doesn't fail the Progress condition, it fails the Bounded Waiting condition.