Jump to content
Sign in to follow this  
Prodavec

Atomacity of the expressions and critical sections based on it

Recommended Posts

Hi! I need some information related to executing scripts in parallel on arma's VM. I'm aware of this thread but it doesn't cover all aspects about atomicity and nobody from BIS team had written in that topic.

Let's begin.

We have two threads with completely identical code which started almost at the same time:

globalVariable = 0;

fnc_Thread =
{
   // Some job
   diag_log format ["[fnc_Thread] _this: %1 | globalVariable: %2", _this, globalVariable];
};

fnc_StartThreads =
{
   1 spawn fnc_Thread;
   2 spawn fnc_Thread;
};

For example - I don't want to execute that threads in parallel: if some of that threads is already running - do not run another one. Obviously we have to set some flag that indicates, some thread is already running:

locked = false; // at init phase
...

fnc_Thread =
{
   if (!locked) then
   {
       locked = true;

       // Some job
       diag_log format ["[fnc_Thread] _this: %1 | globalVariable: %2", _this, globalVariable];

       locked = false;
   };
};

So if locked == true then do not allow another thread to run. That's simple.

Thread 1: if (!locked) then {// allow execution} (locked = false)

Thread 1: then {locked = true;...} (locked = true)

Thread 2: if (!locked) then {// not allowed} (locked = true)

But for example we have a lot of concurent threads and low FPS (so often happened on ArmA servers, especially with a lot of objects on the map and high online). As we know from that article each statment is executed with 0.3 ms delay in scheduled environment. Now, what happens with threads working in parallel?

Thread 1: if (!locked) then {// allow execution} (locked = false)

Thread 2: if (!locked) then {// allow execution} (locked = false)

Thread 1: then {locked = true;...} (locked = true)

Thread 2: then {locked = true;...} (locked = true)

Both threads began to execute statements in their THEN {...} block.

Also there's a special syntax of the IF:

_result = if (a > b) then {true} else {false};

So the first question: is there any pause (0.3 ms) between expression evaluating in if (if_expression) and first expression in then {first_expression; second_expression; ...};

As I understood from this thread - one expression is evaluated as atomic, in other words it's executed "at once". But it's related only for ONE expression with SEMICOLON at the end. In other words:

if ((a > b) || (d < e) || (f == g)) then  // no delay and all expression evaulated at once
{
   sleep 0.0003; // 0.3 ms delay in scheduled environment
   expression1;
   sleep 0.0003;
   expression2;
   ...
}
else
{
   // same as above
};

What happens if we will use alternative syntax?

_result = if (test) then {c = a + b; true} else {d = e - f; false};

The second question: Has whole IF block with alternative syntax evaluated at once?

Samatra has suggested to use the next solution:

(lock renamed to locked, because lock is reserved by the engine :))

if(if(!locked) then {locked = true; true} else {false}) then {
   //...
   locked = false;
}; 

This solution based on assumption that alternative syntax of the IF statement is atomic. But probably not.

Anyone know how to solve the task: test/exchange the variable and set the flag at the same time like CMPXCHG of the x86 instruction set.

English is not my native

Edited by Prodavec

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now
Sign in to follow this  

×