Parallel QuickSort using CCR

Since there was some requests to get the code for the parallel QuickSort mentioned here I decided to post the code I used. This is not a complete listing. You need the samples that can be downloaded from here. This listing is an extension to the Sort class in Chapter6/ParallelSort/Sort.cs.

    1:          private static DispatcherQueue queue = 
   2:              new DispatcherQueue("CcrQueue");
   3:          private static Port<SortInfo> infoPort = new Port<SortInfo>();
   4:          private static Port<int> resultPort = new Port<int>();
   5:          private static EventWaitHandle done = 
   6:              new EventWaitHandle(false, EventResetMode.ManualReset);
   7:          private static int remaining = 0;
   8:          private static int[] theArray = null;
   9:   
  10:          class SortInfo
  11:          {
  12:              public int from;
  13:              public int to;
  14:              public int depth;
  15:          }
  16:   
  17:          public static void CcrQuickSort(int[] array)
  18:          {
  19:              theArray = array;
  20:              remaining = array.Length;
  21:              Arbiter.Activate(queue, 
  22:                  Arbiter.Receive(true, infoPort, CcrSortPart));
  23:              Arbiter.Activate(queue, 
  24:                  Arbiter.Receive(false, resultPort, CcrSortPartDone));
  25:              infoPort.Post(
  26:                  new SortInfo
  27:                      {
  28:                          from = 0,
  29:                          to = array.Length,
  30:                          depth = 
  31:                          (int) Math.Log(Environment.ProcessorCount,2)+4
  32:                      });
  33:              done.WaitOne();
  34:          }
  35:   
  36:          private static void CcrSortPartDone(int count)
  37:          {
  38:              remaining -= count;
  39:              if (remaining <= 0)
  40:                  done.Set();
  41:              else
  42:                  Arbiter.Activate(queue,
  43:                      Arbiter.Receive(false, resultPort, CcrSortPartDone));
  44:          }
  45:   
  46:          private static void CcrSortPart(SortInfo info)
  47:          {
  48:              if (info.from == info.to)
  49:                  return;
  50:              if (info.to - info.from <= Threshold)
  51:              {
  52:                  InsertionSort(theArray, info.from, info.to);
  53:                  resultPort.Post(info.to - info.from);
  54:              }
  55:              else
  56:              {
  57:                  int pivot = info.from;
  58:                  pivot = Partition(theArray, info.from, info.to, pivot);
  59:                  if (info.depth > 0)
  60:                  {
  61:                      infoPort.Post(new SortInfo
  62:                                        {
  63:                                            from = info.from, 
  64:                                            to = pivot, 
  65:                                            depth = info.depth - 1
  66:                                        });
  67:                      infoPort.Post(new SortInfo
  68:                                        {
  69:                                            from = pivot + 1, 
  70:                                            to = info.to, 
  71:                                            depth = info.depth - 1
  72:                                        });
  73:                  }
  74:                  else
  75:                  {
  76:                      CcrSortPart(new SortInfo
  77:                                      {
  78:                                          from = info.from, 
  79:                                          to = pivot
  80:                                      });
  81:                      CcrSortPart(new SortInfo
  82:                                      {
  83:                                          from = pivot + 1, 
  84:                                          to = info.to
  85:                                      });
  86:                  }
  87:                  resultPort.Post(1);
  88:              }
  89:          }

The use of a static array and remaining counter are obviously not a great design for your typical application, but sneaked in there in the hunt for a saving a few microseconds. Didn't really matter...