Link to home
Start Free TrialLog in
Avatar of brianpowell
brianpowellFlag for United States of America

asked on

mutex generic question

A and B are mutexes, and are initialized
Whats the proper way to handle mutex A And B

void Task1(void)
{
   while (1)
   {
      mutex_acquire(A);
      do_task1_A_stuff();

      mutex_acquire(B);
      do_task1_AB_stuff();

      mutex_release(A);
      do_task1_B_stuff();

      mutex_release(B);
   }
}

void Task2(void)
{
   while (1)
   {
      mutex_acquire(B);
      do_task2_B_stuff();

      mutex_acquire(A);
      do_task2_AB_stuff();

      mutex_release(B);
      do_task2_A_stuff();

      mutex_release(A);
   }
}
ASKER CERTIFIED SOLUTION
Avatar of sunnycoder
sunnycoder
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
One possible way would be

void Task1(void)
{
   while (1)
   {
      mutex_acquire(A);
      do_task1_A_stuff();

      mutex_acquire(B);
      do_task1_AB_stuff();

      do_task1_B_stuff();

      mutex_release(B);
      mutex_release(A);
   }
}

void Task2(void)
{
   while (1)
   {
      mutex_acquire(A);
      mutex_acquire(B);
      do_task2_B_stuff();

      do_task2_AB_stuff();

      mutex_release(B);
      do_task2_A_stuff();

      mutex_release(A);
   }
}

Make sure that resources/mutexes are acquired in same fixed order and released in the reverse order. It is similar to prioritizing the resources and making sure that no lower priority resource is requested if you have a larger priority resource already acquired.
how about

void Task1(void)
{
   while (1)
   {
      mutex_acquire(A);
      do_task1_A_stuff();
      mutex_release(A); /* can be removed, but might interleave better */

      mutex_acquire(A); /* can be removed ... */
      mutex_acquire(B);
      do_task1_AB_stuff();
      mutex_release(B); /* avoid deadlock with task 2 */
      mutex_release(A); /* release task 2 if blocked */

      mutex_acquire(B);
      do_task1_B_stuff();
      mutex_release(B);
   }
}

void Task2(void)
{
   while (1)
   {
      mutex_acquire(B);
      do_task2_B_stuff();
      mutex_release(B); /* release task 1 if blocked */

      mutex_acquire(A); /* wait for task 1 */
      mutex_acquire(B);
      do_task2_AB_stuff();
      mutex_release(B);
      mutex_release(A); /* can be removed ... */

      mutex_acquire(A); /* can be removed ... */
      do_task2_A_stuff();
      mutex_release(A);
   }
}
Are you allowed to reorder the P() and V() calls ? or is this some kind of exercise you need to solve in that specific order ?