To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.roboticsOpen lugnet.robotics in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / 450
449  |  451
Subject: 
Re: RCX Programming Questions and Sensor Ideas
Newsgroups: 
lugnet.robotics
Date: 
Wed, 11 Nov 1998 15:24:48 GMT
Viewed: 
2919 times
  
Paul Haas writes:

On Wed, 11 Nov 1998, Ben Laurie wrote:

It isn't guaranteed to work, either, though it is likely to in the end.
This is because two processes can conspire to always have r31 == 2 when
you test for r31 == 1.

Oops.

I don't know how the scheduler in the RCX works.  It might execute 1
opcode from each task in order. If 2 tasks get in sync, then they will
never leave the semaphore code as written.

Here's a fixed version.  I added a random backoff.

Paul Haas wrote:
2. You can use a counter, because += 1 and -= 1 are atomic operations.

    int r31;
    int done;
    r31 = 0;

    // stuff happens.
    // Heres our semaphore stuff.
    done = 0;  // We're not done yet.

    while ( ! done ) {
         while ( r31 != 0 ) {
         } ; // busy wait.
        r31 += 1;  // This operation is atomic.
        if ( r31 == 1 ) {  // Were we the only process to touch the counter?
             // Do critical section stuff here.
             done = 1;
        }
            else {
                sleep(Random(10));
            }
        r31 -= 1;  // Remove our reservation.
   }

Paul, Are you sure you want to sleep before decrementing r31?  As written,
r31 is always >= 1 during the sleep -- which prevents any other tasks from
obtaining a lock on the resource during this sleep time.  In other words,
once any two tasks are competing for the same resource using the method
above, they will be effectively deadlocked until one of them miraculously
wakes up at the exact instant that the other one is re-entering the outer
while loop.  Perhaps it would be safer to decrement r31 before sleeping...

   while (1)
   {
      // Wait for a chance to seize the resource.
      while (r31 != 0) {}

      // Attempt to seize exclusive control of the resource using an
      // atomic increment operation.
      r31 += 1;

      // Now check if there were other contenders for the resource...
      if (r31 == 1)
      {
         // If we were the only contender, then do our work as quickly
         // as possible, release our lock, and exit the loop.
         ...{critical section stuff}...
         r31 -= 1;
         break;
      }
      else
      {
         // Otherwise relinquish our attempt immediately to give others
         // a chance, and then wait a random amount of time before
         // trying again.
         r31 -= 1;
         sleep(Random(10));
      }
   }

--ToddL

p.s.  I also wonder -- in avoiding harmonic task oscillation, is sleeping
Might it be sufficient instead simply to busy-count to some random value?



Message has 1 Reply:
  Re: RCX Programming Questions and Sensor Ideas
 
(...) I think "oops" applies in this case. Your fix looks correct. (...) It doesn't have to be random, just each task needs a different delay. This is easy, since each task has to run its own version of the code. For task 3 insert 3 noops, for task (...) (26 years ago, 11-Nov-98, to lugnet.robotics)

Message is in Reply To:
  Re: RCX Programming Questions and Sensor Ideas
 
(...) Oops. I don't know how the scheduler in the RCX works. It might execute 1 opcode from each task in order. If 2 tasks get in sync, then they will never leave the semaphore code as written. Here's a fixed version. I added a random backoff. (...) (...) (26 years ago, 11-Nov-98, to lugnet.robotics)

17 Messages in This Thread:






Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact

This Message and its Replies on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR