
  PROCEDURE [INLINE] mtp$set_lock (VAR lock: mtt$monitor_lock;
    VAR locked: boolean);

{ Reading the free running clock in the compare swap loop is to prevent two CPUs
{ from getting in synch on compare swap when one CPU is trying to set a lock while
{ the other CPU is trying to clear the lock.
{ When they get in synch, the compare swap for the set always sees the lock set,
{ while the compare swap for the clear always sees that the other processor has
{ the word locked for compare swap (left 32 bits all ones).

    VAR
      frc: ost$free_running_clock,
      id,
      actual: integer,
      result: 0.. 2;

    id := #read_register (osc$pr_base_constant);
    REPEAT
      frc := #FREE_RUNNING_CLOCK (0);
      #compare_swap (lock, 0, id, actual, result);
    UNTIL result <> 2;
    IF result = 0 THEN
      locked := TRUE;
    ELSE
      locked := FALSE;
    IFEND;

  PROCEND mtp$set_lock;

?? PUSH (LISTEXT := ON) ??
*copyc mtt$monitor_lock
*copyc osc$processor_defined_registers
*copyc ost$free_running_clock
?? POP ??
