Mark Peschel
Mark Peschel

Reputation: 334

Why does it seem like my BACI monitor functions don't share any variables or conditions?

I am trying to write a concurrent program that will print the letters A and B in order. The following program looks fine and compiles, but every time I run it, it deadlocks.

monitor simple_monitor { 
  int isAPrinted = 0;
  condition B_wait;

  void monitorA() { 
    isAPrinted = 1;
    cout << "A: Value of isAPrinted is now " << isAPrinted << endl;
    signalc (B_wait);
  } 

  void monitorB() {
   cout << "B: Value of isAPrinted is now " << isAPrinted << endl;
   if ( !isAPrinted ) 
      waitc( B_wait ); 
  }
} 


int main() { cobegin { monitorA(); monitorB();  } }

Specifically, I'm getting an error that looks like this:

Executing PCODE ...
A: Value of isAPrinted is now 1
B: Value of isAPrinted is now 0

BACI System: Command-line PCODE Interpreter in Java, 09:46  05 Nov 2007
Execution of process 2 aborted at loc 23
>>>Deadlock in process 2
 Process       Active Suspend  PC    xpc   atomic
 0 main             0  6000    38     0     0
 1 monitorA         0    -1     0     0     0
 2 monitorB         0  2607    23     0     0
...

If monitorB runs first, it's supposed to wait on B_wait, so monitorA can start and call signalc(B_wait), waking monitorB. But when monitorB does run first, it doesn't wake up when monitorA finishes.

If monitorA runs first, it's supposed to set isAPrinted to 1, so monitorB won't wait on B_wait. But when monitorA does run first, isAPrinted stays 0 when monitorB runs!

It's like these are running in two independent execution contexts! But I can compile example programs that look just like this, and they run fine. What gives?

I am using javabaci as downloaded from Dr. Tracy Camp's website. "baci" stands for "Ben-Ari Concurrent Interpreter". It is an educational program used by some university-level operating systems courses to teach semaphores.

Upvotes: 0

Views: 29

Answers (1)

Mark Peschel
Mark Peschel

Reputation: 334

It appears that, in javabaci at least, you should not call monitor functions directly from a cobegin() block. Literally all you have to do is wrap the monitor function calls in another function.

So instead of

int main() { cobegin { monitorA(); monitorB();  } }

write

void A() { monitorA(); }
void B() { monitorB(); }
main() { cobegin { A(); B();  } }

Upvotes: 0

Related Questions