Lock

lock name = <expression>

The lock keyword can only be used from a FISH operator, it cannot be used in a normal FISH function. Inside a FISH operator, this statement locks a global symbol and allows it to be written to from a general expression in a way that is both thread safe and deterministic.

The first token following the lock statement must be the name of a global symbol.

There are only four available valid forms of syntax after the global symbol name. They are:

  • lock name = math.max (name ,<expression>)

    This finds the maximum value and assigns it to the symbol. Only two arguments may be given to math.max.

  • lock name = math.min (name ,<expression>)

    This finds the minimum value and assigns it to the symbol. Only two arguments may be given to math.max.

  • lock name = <expression>

    This simply sets the value of the symbol. The code guarantees that the last call in the order of the splitting that caused multi-thread execution will be the one that takes precedence.

  • lock name += <expression>

    This accumulates a value in the symbol. The symbol value must be of either integer or real type, and the expression must result in a value of those two types as well.

There are a few rules governing the use of a lock statement:

  • A given symbol can only be used in a lock statment of one of those four types in a given operator. More than one lock statement of the same type on the same symbol may be used.
  • A symbol cannot be the target of a lock statment if it has been read from by any preceding code.

The following are examples of using a lock statement to safely write to a global FISH symbol from an operator:

lock maxval = math.max(maxval,thisval)
lock myval = a*b*c

It is worth noting that a common desire is to associate some other value with the maximum value obtained. For example if you want find the FLAC3D grid point corresponding to maximum displacement. In this case you may use the lock sym = math.max(sym,val) syntax but use a structure as the symbol. Structures are compared by comparing each member in order. So make a structure whose first value is a real (displacement magnitude) and whose second is a grid point pointer. The following FLAC3D example demonstrates:

fish struct mystruct(disp,gp)

[global maxgp = struct mystruct(0.0,null)]

fish operator findmax(gp)
    local dispmag = math.mag(gp.disp(gp))
    lock maxgp = math.max(maxgp,struct mystruct(dispmag,gp))
end
[findmax(::gp.list)]
fish list contents [maxgp]