Ejemplo n.º 1
0
        /// <summary>
        /// Acquires a resource according to the specified resource request, either blocking until successful, or
        /// returning &lt;null&gt; if the resource is not immediately available.
        /// </summary>
        /// <param name="resourceRequest">The IResourceRequest that specifies the criteria by which to select the resource.</param>
        /// <param name="blockAwaitingAcquisition">If true, request will suspend until granted. If false, will return false if unable to fulfill.</param>
        /// <returns>True if granted, false if not granted.</returns>
        public bool Acquire(IResourceRequest resourceRequest, bool blockAwaitingAcquisition)
        {
            if (blockAwaitingAcquisition)
            {
                IDetachableEventController dec = Model.Executive.CurrentEventController;
                if (dec == null)
                {
                    throw new ApplicationException("Someone tried to call Acquire(..., true) while not in a detachable event. This is not allowed.");
                }

                dec.SetAbortHandler(resourceRequest.AbortHandler);
                resourceRequest.ResourceRequestAborting += m_onResourceRequestAborting;

                while (true)
                {
                    if (Acquire(resourceRequest))
                    {
                        break;
                    }
                    m_waiters.Add(dec);
                    dec.Suspend();
                    dec.ClearAbortHandler();
                }
                return(true);
            }
            else
            {
                return(Acquire(resourceRequest));
            }
        }
Ejemplo n.º 2
0
 public BlockTilKeyGoneHandler(Exchange exchange, ITuple tuple)
 {
     m_exchange = exchange;
     m_idec     = m_exchange.m_exec.CurrentEventController;
     m_tuple    = tuple;
     m_myEvent  = m_exchange_TupleTaken;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Releases the resource held under this resource request back into the resource pool.
 /// </summary>
 /// <param name="resourceRequest">The resource request under which the resource has previously
 /// been acquired.</param>
 public void Release(IResourceRequest resourceRequest)
 {
     if (resourceRequest.ResourceObtained != null)
     {
         if (s_diagnostics)
         {
             string fromWhom = resourceRequest.ToString();
             if (resourceRequest.ResourceObtained != null)
             {
                 fromWhom = resourceRequest.ResourceObtained.Name;
             }
             _Debug.WriteLine(Name + " servicing request to release " + resourceRequest.QuantityDesired + " units of " + fromWhom);
         }
         IResource resourceReleased = resourceRequest.ResourceObtained;
         resourceRequest.ResourceObtained?.Release(resourceRequest);
         resourceRequest.Status = RequestStatus.Free;
         ResourceReleased?.Invoke(resourceRequest, resourceReleased);
         while (m_waiters.Count > 0)
         {
             IDetachableEventController dec = (IDetachableEventController)m_waiters[0];
             m_waiters.RemoveAt(0);
             if (dec.IsWaiting())
             {
                 dec.Resume();                    // We might be releasing all resources as a part of an abort.
             }
         }
     }
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Acquires the resource and quantity specifed by the resource request, blocking
        /// until it can return successfully.
        /// </summary>
        /// <param name="request">The resource request that describes the desired resource and quantity.</param>
        /// <returns>Always true.</returns>
        protected bool AcquireWithWait(IResourceRequest request)
        {
            IDetachableEventController dec = Model.Executive.CurrentEventController;

            if (dec == null)
            {
                throw new ApplicationException("Someone tried to call AcquireWithWait() while not in a detachable event. This is not allowed.");
            }

            dec.SetAbortHandler(request.AbortHandler);
            request.ResourceRequestAborting += m_onResourceRequestAborting;
            while (!Acquire(request, false))
            {
                m_waiters.Add(request, dec);
                dec.Suspend();
                dec.ClearAbortHandler();
            }
            if (request.ResourceObtained != null)
            {
                ResourceAcquired?.Invoke(request, request.ResourceObtained);
                return(true);
            }
            else
            {
                return(false);
            }
        }
Ejemplo n.º 5
0
        private void idec_AbortionEvent(IExecutive exec, IDetachableEventController idec, params object[] args)
        {
            string narrative = "A synchronizer failed to complete. It had " + m_synchChannels.Count
                               + " synch channels - following is the stack trace:\r\n" + new StackTrace(true);

            m_model.AddWarning(new GenericModelWarning("Synchronizer Aborted", narrative, this, null));
        }
Ejemplo n.º 6
0
        private ITuple BlockingTake(object key)
        {
            #region Ensure that this is a Detachable Event.
#if DEBUG
            if (m_exec.CurrentEventType != ExecEventType.Detachable)
            {
                throw new ApplicationException("Attempt to do a blocking take with an executive event that is not Detachable.");
            }
#endif
            #endregion

            while (true)
            {
                ITuple tuple = NonBlockingTake(key);
                if (tuple != null)
                {
                    return(tuple);
                }

                #region Wait 'til next take against this key.
                IDetachableEventController idec = m_exec.CurrentEventController;
                m_waitersToTake.Add(key, idec);
                idec.Suspend();
                #endregion
            }
        }
Ejemplo n.º 7
0
                private void FinishRewiringDisposal(IExecutive exec, object userData)
                {
                    IDetachableEventController plumbersIDEC = (IDetachableEventController)userData;

                    Console.WriteLine("{0} : {1} is done fixing the disposal.", exec.Now, Name);
                    plumbersIDEC.Resume();
                    Console.WriteLine("{0} : {1} is leaving.", exec.Now, Name);
                }
Ejemplo n.º 8
0
 /// <summary>
 /// Creates a new instance of the <see cref="T:TerminalResourceRequestAbortedWarning"/> class.
 /// </summary>
 /// <param name="exec">The executive under whose control this warning occurred.</param>
 /// <param name="mgr">The Resource Manager from which the resource was obtained.</param>
 /// <param name="req">The request through which the resource was obtained.</param>
 /// <param name="idec">The <see cref="Highpoint.Sage.SimCore.IDetachableEventController"/> that controls the thread in which the resource was last manipulated.</param>
 public TerminalResourceRequestAbortedWarning(IExecutive exec, IResourceManager mgr, IResourceRequest req, IDetachableEventController idec)
 {
     m_idec          = idec;
     ResourceRequest = req;
     ResourceManager = mgr;
     m_exec          = exec;
     Narrative       = GetNarrative();
 }
Ejemplo n.º 9
0
 public Dispensary(IExecutive executive, Mixture mixture)
 {
     m_executive                 = executive;
     m_getProcessor              = s_dummyIdec;
     m_waiters                   = new List <IDetachableEventController>();
     PeekMixture                 = mixture;
     executive.ExecutiveStarted += delegate { m_waiters.Clear(); PeekMixture.Clear(); };
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Blocks the caller's detachable event thread until this transfer has started.
 /// </summary>
 public void BlockTilStart()
 {
     _Debug.Assert(m_model.Executive.CurrentEventType == ExecEventType.Detachable);
     if (m_completionKey == long.MinValue /*i.e. it has not started*/)
     {
         IDetachableEventController waiter = m_model.Executive.CurrentEventController;
         m_startWaiters.Add(waiter);
         waiter.Suspend();
     }
 }
Ejemplo n.º 11
0
 public PfcStepJoiner(PfcExecutionContext rootStepPfcec, IProcedureFunctionChart[] childPfCs)
 {
     Debug.Assert(rootStepPfcec.IsStepCentric);
     m_rootStepEc = rootStepPfcec;
     m_model      = m_rootStepEc.Model;
     m_idec       = null;
     m_onTransitionStateChanged = new TransitionStateMachineEvent(OnTransitionStateChanged);
     m_pendingActions           = new List <IProcedureFunctionChart>(childPfCs);
     m_pendingActions.ForEach(delegate(IProcedureFunctionChart kid) {
         kid.GetFinishTransition().MyTransitionStateMachine.TransitionStateChanged += m_onTransitionStateChanged;
     });
 }
Ejemplo n.º 12
0
 public void Add(IResourceRequest rreq, IDetachableEventController idec)
 {
     if (!m_supportsPriorities)
     {
         base.Add(idec);
     }
     else
     {
         rreq.PriorityChangeEvent += m_rreqPriorityChangeEvent;
         m_dirty = true;                     // TODO: Not necessarily
         base.Add(new RscWaiterListEntry(rreq, idec, m_seqNum++));
     }
 }
Ejemplo n.º 13
0
        private void ProcessGetters(IExecutive exec, object userData)
        {
            m_getProcessor = exec.CurrentEventController;
            IDetachableEventController waiter = null;

            while (m_waiters.Count > 0 && m_waiters[0] != waiter)
            {
                waiter = m_waiters[0];
                waiter.Resume();
                m_getProcessor.Suspend();
            }
            m_getFlushEventId = -1;
            m_getProcessor    = s_dummyIdec;
        }
Ejemplo n.º 14
0
 /// <summary>
 /// Releases the specified request. Returns it to availability and the resource pool.
 /// </summary>
 /// <param name="request">The request.</param>
 public void Release(IResourceRequest request)
 {
     lock (this) {
         DoRollback(request);
         ReleasedEvent?.Invoke(request, this);
         ResourceReleased?.Invoke(request, this);
     }
     while (m_waiters.Count > 0)
     {
         IDetachableEventController dec = (IDetachableEventController)m_waiters[0];
         m_waiters.RemoveAt(0);
         dec.Resume();
     }
 }
Ejemplo n.º 15
0
        protected void GetPermissionToStart(PfcExecutionContext myPfcec, StepStateMachine ssm)
        {
            PfcExecutionContext root = myPfcec;
            int ascents = m_rootHeight;

            while (ascents > 0)
            {
                root = (PfcExecutionContext)myPfcec.Parent.Payload;
                ascents--;
            }

            Exchange exchange = null;

            if (m_myIndex == 0)
            {
                //Console.WriteLine(myPfcec.Name + " is creating an exchange and injecting it into pfcec " + root.Name + " under key " + m_sequenceKey);
                exchange = new Exchange(myPfcec.Model.Executive);
                root.Add(m_sequenceKey, exchange);
            }
            else
            {
                //Console.WriteLine(myPfcec.Name + " is looking for an exchange in pfcec " + root.Name + " under key " + m_sequenceKey);
                DictionaryChange dc = new DictionaryChange(myPfcec_EntryAdded);
                while (true)
                {
                    exchange = (Exchange)root[m_sequenceKey];
                    if (exchange == null)
                    {
                        root.EntryAdded += dc;
                        m_idec           = myPfcec.Model.Executive.CurrentEventController;
                        m_idec.Suspend();
                    }
                    else
                    {
                        root.EntryAdded -= dc;
                        break;
                    }
                }
                exchange.Take(m_myKey, true); // Only indices 1,2, ... take (and wait?). Index 0 only posts.
                //Console.WriteLine(myPfcec.Name + " got the key I was looking for!");
            }
            Guid nextGuysKey = GuidOps.Increment(m_myKey);

            exchange.Post(nextGuysKey, nextGuysKey, false);
            //Console.WriteLine(myPfcec.Name + " posted the key the next guy is looking for!");
        }
Ejemplo n.º 16
0
        private void TimeSeparatedTask(IExecutive exec, object userData)
        {
            IDetachableEventController dec = exec.CurrentEventController;

            Debug.WriteLine(exec.Now + " : " + userData.ToString() + " performing initialization of detachable task on thread " + System.Threading.Thread.CurrentThread.GetHashCode());

            while (m_random.Next(3) < 2)
            {
                DateTime when = exec.Now + TimeSpan.FromDays(1.5);

                Debug.WriteLine("Suspending task until " + when);

                dec.SuspendUntil(when);

                Debug.WriteLine(exec.Now + " : " + userData.ToString() + " performing continuation of detachable task on thread " + System.Threading.Thread.CurrentThread.GetHashCode());
            }
        }
Ejemplo n.º 17
0
        private void BlockingPost(ITuple tuple)
        {
            #region Ensure that this is a Detachable Event.
#if DEBUG
            if (m_exec.CurrentEventType != ExecEventType.Detachable)
            {
                throw new ApplicationException("Attempt to do a blocking post with an executive event that is not Detachable.");
            }
#endif
            #endregion

            NonBlockingPost(tuple);

            #region Wait 'til next take against this key.
            IDetachableEventController idec = m_exec.CurrentEventController;
            m_blockedPosters.Add(tuple.Key, idec);
            idec.Suspend();
            #endregion
        }
Ejemplo n.º 18
0
        internal void GetStartPermission(PfcExecutionContext pfcec)
        {
            IDetachableEventController currentEventController = m_myStep.Model.Executive.CurrentEventController;
            SsmData ssmData = GetSsmData(pfcec);

            if (!ssmData.State.Equals(StepState.Idle))
            {
                ssmData.QueueIdec.Enqueue(currentEventController);
                if (s_diagnostics)
                {
                    Console.WriteLine(m_myStep.Model.Executive.Now + " : suspending awaiting start of " + m_myStep.Name + " ...");
                }
                currentEventController.Suspend();
                if (s_diagnostics)
                {
                    Console.WriteLine(m_myStep.Model.Executive.Now + " : resuming the starting of     " + m_myStep.Name + " ...");
                }
            }
        }
Ejemplo n.º 19
0
        private ITuple BlockingRead(object key)
        {
            lock ( m_ts ) {
                while (true)
                {
                    ITuple tuple = NonBlockingRead(key);
                    if (tuple != null)
                    {
                        return(tuple);
                    }

                    #region Wait 'til next post against this key.
                    IDetachableEventController idec = m_exec.CurrentEventController;
                    m_waitersToRead.Add(key, idec);
                    idec.Suspend();
                    #endregion
                }
            }
        }
Ejemplo n.º 20
0
        private void LogSynchronization(object sortKey, IDetachableEventController idec, SynchChannel sc)
        {
            if (m_waiters.ContainsValue(idec))
            {
                throw new ApplicationException("Synchronize(...) called on a SynchChannel that is already waiting.");
            }
            if (!m_synchChannels.Contains(sc))
            {
                throw new ApplicationException("SynchChannel applied to a synchronizer that did not own it - serious error.");
            }

            if ((m_waiters.Count + 1) == m_synchChannels.Count)
            {
                m_exec.RequestEvent(new ExecEventReceiver(LaunchAll), m_exec.Now, m_exec.CurrentPriorityLevel, null);
            }
            m_waiters.Add(sortKey, idec);
            idec.SetAbortHandler(new DetachableEventAbortHandler(idec_AbortionEvent));
            idec.Suspend();
            idec.ClearAbortHandler();
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Unreserves a quantity of resource from this pool that was previously reserved under the provided
 /// resource request.
 /// </summary>
 /// <param name="resourceRequest">The resource request under which some resource was previously reserved.</param>
 public void Unreserve(IResourceRequest resourceRequest)
 {
     if (s_diagnostics)
     {
         _Debug.WriteLine(Name + " servicing request to unreserve " + resourceRequest.QuantityDesired + " units of " + resourceRequest);
     }
     if (resourceRequest.ResourceObtained != null)
     {
         resourceRequest.ResourceObtained.Unreserve(resourceRequest);
         resourceRequest.Status = RequestStatus.Free;
     }
     while (m_waiters.Count > 0)
     {
         IDetachableEventController dec = (IDetachableEventController)m_waiters[0];
         m_waiters.RemoveAt(0);
         if (dec.IsWaiting())
         {
             dec.Resume();                                    // We might be releasing all resources as a part of an abort.
         }
     }
 }
Ejemplo n.º 22
0
                public void FixTheSink(IExecutive exec, object userData)
                {
                    IDetachableEventController idec = exec.CurrentEventController;

                    Console.WriteLine("{0} : {1} is starting to fix the sink.", exec.Now, Name);
                    idec.SuspendFor(TimeSpan.FromMinutes(10.0)); // When the suspend call returns, 10 minutes have passed.

                    Console.WriteLine("{0} : {1} discovered that the disposal needed rewiring.", exec.Now, Name);

                    DateTime when = exec.Now + TimeSpan.FromMinutes(5.0);

                    exec.RequestEvent(new Electrician("Edgar").RewireDisposal, when, idec);
                    Console.WriteLine("{0} : {1} called the electrician and is starting to eat lunch.", exec.Now, Name);
                    idec.Suspend(); // When the suspend call returns (from the electrician calling "Resume",)
                                    // the electrician is done, and presumably the sink is fixed.
                    Console.WriteLine("{0} : {1} was told by the electrician that the disposal is fixed.", exec.Now,
                                      Name);
                    Console.WriteLine("{0} : {1} is resuming fixing the sink.", exec.Now, Name);
                    idec.SuspendFor(TimeSpan.FromMinutes(40.0)); // Finishing fixing the sink requires 40 minutes,
                                                                 // and on return from this call, that time has passed.
                    Console.WriteLine("{0} : {1} is done fixing the sink.", exec.Now, Name);
                }
Ejemplo n.º 23
0
        private ITuple NonBlockingTake(object key)
        {
            ITuple tuple;

            lock ( m_ts ) {
                tuple = (ITuple)m_ts[key];
                if (tuple != null)
                {
                    m_ts.Remove(key);
                    tuple.OnTaken(this);
                    TupleTaken?.Invoke(this, tuple);

                    IDetachableEventController blockedPoster = (IDetachableEventController)m_blockedPosters[tuple.Key];
                    if (blockedPoster != null)
                    {
                        m_blockedPosters.Remove(tuple.Key);
                        blockedPoster.Resume(s_postPriority);
                    }
                }
            }
            return(tuple);
        }
Ejemplo n.º 24
0
 private void WaitForAllActionsToComplete(IExecutive exec)
 {
     m_myIDEC = exec.CurrentEventController;
     m_myIDEC.Suspend();
 }
Ejemplo n.º 25
0
 public RscWaiterListEntry(IResourceRequest request, IDetachableEventController idec, int seq)
 {
     Request  = request;
     Idec     = idec;
     Sequence = seq;
 }
Ejemplo n.º 26
0
 private void OnResourceRequestAborting(IResourceRequest request, IExecutive exec, IDetachableEventController idec)
 {
     m_model.AddWarning(new TerminalResourceRequestAbortedWarning(exec, this, request, idec));
 }
Ejemplo n.º 27
0
 public void RunAndWait()
 {
     m_idec = m_model.Executive.CurrentEventController;
     m_idec.Suspend();
 }
Ejemplo n.º 28
0
            /// <summary>
            /// Called by a synch channel to indicate that it is ready to proceed. It will be
            /// allowed to do so once all clients have called this method.
            /// </summary>
            public void Synchronize()
            {
                IDetachableEventController idec = m_ds.m_exec.CurrentEventController;

                m_ds.LogSynchronization(m_sortKey, idec, this);
            }
Ejemplo n.º 29
0
 private void OnRequestAborting(IExecutive exec, IDetachableEventController idec, params object[] args)
 {
     ResourceRequestAborting?.Invoke(this, exec, idec);
 }