/// <summary>Prioritized selection of alternatives.</summary> /// <remarks>Returns an index of a ready alternative. If multiple alternatives are ready, the one with the highest priority is selected. /// PriSelect is blocked until one of the alternatives are ready.</remarks> /// <returns>An index of a ready alternative with the highest priority.</returns> /// <exception cref="Jibu.PoisonException">Thrown if a Channel that takes part in the Choice has been poisoned.</exception> // - PriSelectExample - // <code><include PriSelectExample/PriSelectExample.cs></code> // </example> public int PriSelect() { int tempSelect; Monitor.Enter(lockObject); choiceThreadId = Thread.CurrentThread.ManagedThreadId; selected = -1; choiceStatus = choiceState.INPROGRESS; traverseIndex = 0; fairIndex = 0; Monitor.Exit(lockObject); PriTraverse(); Monitor.Enter(lockObject); if (selected == -1) { choiceStatus = choiceState.WAITING; if (!poisoned) { Monitor.Wait(lockObject); } if (poisoned) { choiceStatus = choiceState.INACTIVE; Monitor.Exit(lockObject); throw new PoisonException("A Channel in this Choice was poisoned."); } } tempSelect = selected; Monitor.Exit(lockObject); return(tempSelect); }
internal void SignalPoison() { Monitor.Enter(lockObject); poisoned = true; if (choiceStatus == choiceState.WAITING) { Monitor.Pulse(lockObject); } choiceStatus = choiceState.INACTIVE; Monitor.Exit(lockObject); }
/// <summary>Creates a Choice object with the submitted alternatives.</summary> public Choice(params Alternative[] alternatives) { alts = alternatives; indices = new Dictionary <Alternative, int>(); for (int i = 0; i < alts.Length; i++) { alts[i].Mark(); indices.Add(alts[i], i); } lockObject = new object(); choiceStatus = choiceState.INACTIVE; }
private void PriTraverse() { try { while (traverseIndex < alts.Length) { AlternativeType type = alts[traverseIndex].Enable(this); if (type == AlternativeType.False) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) { return; } traverseIndex++; continue; } } if (type == AlternativeType.Channel) { lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; alts[traverseIndex].Reserve(choiceThreadId); return; } alts[traverseIndex].Reserve(-1); return; } } lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; return; } return; } } } catch (PoisonException) { SignalPoison(); } }
internal int SignalChoice(Alternative alt) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) { return(-1); } int index = indices[alt]; if (choiceStatus == choiceState.WAITING) { choiceStatus = choiceState.INACTIVE; Monitor.Pulse(lockObject); selected = index; return(choiceThreadId); } if (traverseIndex > fairIndex) { if (index > traverseIndex || index < fairIndex) { return(-1); } } else { if (index > traverseIndex && index < fairIndex) { return(-1); } } choiceStatus = choiceState.INACTIVE; selected = index; return(choiceThreadId); } }
/// <summary>Non-blocked fair selection of alternatives</summary> /// <remarks>Fair selection of alternatives. If no alternatives are ready, -1 is returned. /// TryFairSelect guarantee that a ready alternative will be chosen within n calls to TryFairSelect, /// where n is the number of alternatives. </remarks> /// <returns>An index of a ready alternative or -1 if no alternatives are ready. </returns> /// <exception cref="Jibu.PoisonException">Thrown if a Channel that takes part in the Choice has been poisoned.</exception> // <example> // - TryFairSelectExample - // <code><include TryFairSelectExample/TryFairSelectExample.cs></code> // </example> public int TryFairSelect() { int tempSelect; Monitor.Enter(lockObject); choiceThreadId = Thread.CurrentThread.ManagedThreadId; selected = -1; choiceStatus = choiceState.INPROGRESS; traverseIndex = fairIndex; Monitor.Exit(lockObject); FairTraverse(alts.Length); Monitor.Enter(lockObject); tempSelect = selected; choiceStatus = choiceState.INACTIVE; if (selected != -1) { fairIndex = selected + 1; if (fairIndex == alts.Length) { fairIndex = 0; } } else { if (poisoned) { Monitor.Exit(lockObject); throw new PoisonException("A Channel in this Choice was poisoned."); } } Monitor.Exit(lockObject); return(tempSelect); }
private void FairTraverse(int end) { try { bool wrapped = false; while (traverseIndex < end) { AlternativeType type = alts[traverseIndex].Enable(this); if (type == AlternativeType.False) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) return; traverseIndex++; if (traverseIndex == end && !wrapped) { traverseIndex = 0; end = fairIndex; wrapped = true; } continue; } } if (type == AlternativeType.Channel) { lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; alts[traverseIndex].Reserve(choiceThreadId); return; } alts[traverseIndex].Reserve(-1); return; } } lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; return; } return; } } } catch (PoisonException) { SignalPoison(); } }
private void PriTraverse() { try { while (traverseIndex < alts.Length) { AlternativeType type = alts[traverseIndex].Enable(this); if (type == AlternativeType.False) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) return; traverseIndex++; continue; } } if (type == AlternativeType.Channel) { lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; alts[traverseIndex].Reserve(choiceThreadId); return; } alts[traverseIndex].Reserve(-1); return; } } lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; return; } return; } } } catch (PoisonException) { SignalPoison(); } }
/// <summary>Prioritized selection of alternatives.</summary> /// <remarks>Returns an index of a ready alternative. If multiple alternatives are ready, the one with the highest priority is selected. /// PriSelect is blocked until one of the alternatives are ready.</remarks> /// <returns>An index of a ready alternative with the highest priority.</returns> /// <exception cref="Jibu.PoisonException">Thrown if a Channel that takes part in the Choice has been poisoned.</exception> // - PriSelectExample - // <code><include PriSelectExample/PriSelectExample.cs></code> // </example> public int PriSelect() { int tempSelect; Monitor.Enter(lockObject); choiceThreadId = Thread.CurrentThread.ManagedThreadId; selected = -1; choiceStatus = choiceState.INPROGRESS; traverseIndex = 0; fairIndex = 0; Monitor.Exit(lockObject); PriTraverse(); Monitor.Enter(lockObject); if (selected == -1) { choiceStatus = choiceState.WAITING; if (!poisoned) Monitor.Wait(lockObject); if (poisoned) { choiceStatus = choiceState.INACTIVE; Monitor.Exit(lockObject); throw new PoisonException("A Channel in this Choice was poisoned."); } } tempSelect = selected; Monitor.Exit(lockObject); return tempSelect; }
/// <summary>Non-blocked fair selection of alternatives</summary> /// <remarks>Fair selection of alternatives. If no alternatives are ready, -1 is returned. /// TryFairSelect guarantee that a ready alternative will be chosen within n calls to TryFairSelect, /// where n is the number of alternatives. </remarks> /// <returns>An index of a ready alternative or -1 if no alternatives are ready. </returns> /// <exception cref="Jibu.PoisonException">Thrown if a Channel that takes part in the Choice has been poisoned.</exception> // <example> // - TryFairSelectExample - // <code><include TryFairSelectExample/TryFairSelectExample.cs></code> // </example> public int TryFairSelect() { int tempSelect; Monitor.Enter(lockObject); choiceThreadId = Thread.CurrentThread.ManagedThreadId; selected = -1; choiceStatus = choiceState.INPROGRESS; traverseIndex = fairIndex; Monitor.Exit(lockObject); FairTraverse(alts.Length); Monitor.Enter(lockObject); tempSelect = selected; choiceStatus = choiceState.INACTIVE; if (selected != -1) { fairIndex = selected + 1; if (fairIndex == alts.Length) fairIndex = 0; } else { if (poisoned) { Monitor.Exit(lockObject); throw new PoisonException("A Channel in this Choice was poisoned."); } } Monitor.Exit(lockObject); return tempSelect; }
internal int SignalChoice(Alternative alt) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) return -1; int index = indices[alt]; if (choiceStatus == choiceState.WAITING) { choiceStatus = choiceState.INACTIVE; Monitor.Pulse(lockObject); selected = index; return choiceThreadId; } if (traverseIndex > fairIndex) { if (index > traverseIndex || index < fairIndex) return -1; } else { if (index > traverseIndex && index < fairIndex) return -1; } choiceStatus = choiceState.INACTIVE; selected = index; return choiceThreadId; } }
internal void SignalPoison() { Monitor.Enter(lockObject); poisoned = true; if (choiceStatus == choiceState.WAITING) Monitor.Pulse(lockObject); choiceStatus = choiceState.INACTIVE; Monitor.Exit(lockObject); }
/// <summary>Creates a Choice object with the submitted alternatives.</summary> public Choice(params Alternative[] alternatives) { alts = alternatives; indices = new Dictionary<Alternative, int>(); for (int i = 0; i < alts.Length; i++) { alts[i].Mark(); indices.Add(alts[i], i); } lockObject = new object(); choiceStatus = choiceState.INACTIVE; }
private void FairTraverse(int end) { try { bool wrapped = false; while (traverseIndex < end) { AlternativeType type = alts[traverseIndex].Enable(this); if (type == AlternativeType.False) { lock (lockObject) { if (choiceStatus == choiceState.INACTIVE) { return; } traverseIndex++; if (traverseIndex == end && !wrapped) { traverseIndex = 0; end = fairIndex; wrapped = true; } continue; } } if (type == AlternativeType.Channel) { lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; alts[traverseIndex].Reserve(choiceThreadId); return; } alts[traverseIndex].Reserve(-1); return; } } lock (lockObject) { if (choiceStatus != choiceState.INACTIVE) { selected = traverseIndex; choiceStatus = choiceState.INACTIVE; return; } return; } } } catch (PoisonException) { SignalPoison(); } }