Atomic vs. SetBits

A private (members-only) forum for discussing all issues related to the Beta test of Native mode devices.
Locked
Don_Kirby
Posts: 341
Joined: 15 October 2006, 3:48 AM
Location: Long Island, New York

Atomic vs. SetBits

Post by Don_Kirby »

I've been using standard bitwise operations to handle a few variables. I've since changed that to SetBits, as the docs indicate that the resulting code guaranteed atomic, as well as smaller. Is this atomicity valid for the native mode devices as well. or do I still need to use the Atomic structure?

-Don
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Atomic vs. SetBits

Post by dkinzer »

Don_Kirby wrote:Is this atomicity valid for the native mode devices[...]?
Yes. An invocation of SetBits() generates a call to the ZX Library function setBits() in which interrupts are disabled during the bit manipulation. The situations where you will need to use an Atomic block are if your code:
  • uses a multi-byte register or variable (read or write) that is also used by another task or an Interrupt Service Routine.
  • performs a read-modify-write on a register or variable that is also used by another task or an ISR
  • has two or more statements that must be executed without interruption.
Writing code for the VM mode devices has the same potential problems except for the first item and the existence of an ISR does not need to be considered. The only way to guarantee atomicity for the second two cases in the VM mode devices is to use a Semaphore. You can use the Semaphore strategy in native mode devices unless an ISR is among the potential accessors. That said, an Atomic block is simpler to use and it even works correctly if you use an Exit Loop or Exit Sub inside the block.
- Don Kinzer
mikep
Posts: 796
Joined: 24 September 2005, 15:54 PM

Post by mikep »

It is important to note in the documentation that operations which were atomic in the VM may no longer be atomic in the generated C code. The simplest example of this is:

Code: Select all

b = b + 1
which results in a single ZVM opcode.

It would be nice if we can use the same atomicity constructs regardless of target machine and the compiler generates the correct code. In particular the VM compiler doesn't need to generate extra code if the block inside the construct results in only one VM instruction (e.g. increment, decrement or system library call). Therefore the fragment:

Code: Select all

b= b + 2
would result in some extra atomicity logic in the resultant VM code.
Mike Perks
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

mikep wrote:

Code: Select all

b = b + 1
which results in a single ZVM opcode.
This is true with the default optimization options and if the variable 'b' is both integral and RAM-based. Otherwise, the compiler generates a series of instructions to effect a read-modify-write operation.
mikep wrote:It would be nice if we can use the same atomicity constructs regardless of target machine and the compiler generates the correct code.
I believe that we can implement the Atomic block construct for VM mode but some VM changes are required to support it. Those same changes would also support EnableInt()/DisableInt(). If these are implemented, the functionality of UpdateRTC() and Yield() should be done as well.

To facilitate writing code that will compile for either VM mode or native mode devices, a pre-defined string constant (described in section 3.9), Option.TargetCode, is available whose value is either "ZVM" or "Native". This can be used in a conditional thusly:

Code: Select all

#if Option.TargetCode = "ZVM"
  ' this code is for the VM devices only
#else
  ' this code is for the native mode devices only
#endif
- Don Kinzer
Locked