Exemple #1
0
        void release(Object p)
        {
            coroutine self    = find_self(this.coroutines);
            coroutine blocked = this.coroutines.Find(c => c.port == p);

            if (blocked == null)
            {
                if (self != null)
                {
                    Debug.WriteLine("[" + self.id + "] skip block");
                }
                this.skip_block.Add(p);
                return;
            }

            Debug.WriteLine("[" + blocked.id + "] unblock");
            Debug.WriteLine("[" + self.id + "] released");
            self.released = true;

            this.switch_context = () => {
                blocked.port = null;
                Debug.WriteLine("[" + self.id + "] switch from");
                Debug.WriteLine("[" + blocked.id + "] to");
                self.yield_to(blocked);
            };
        }
Exemple #2
0
        public static void finish(list <coroutine> coroutines)
        {
            coroutine self = find_self(coroutines);

            self.finished = true;
            Debug.WriteLine("[" + self.id + "] finish coroutine");
        }
Exemple #3
0
        public void block(Object p)
        {
            int skip = this.skip_block.FindIndex(o => o == p);

            if (skip != -1)
            {
                this.skip_block.RemoveAt(skip);
                return;
            }

            coroutine self = find_self(this.coroutines);

            self.port = p;
            Debug.WriteLine("[" + self.id + "] block");
            create_context();
            self.yield_to(this.coroutines.Last());
            Debug.WriteLine("[" + self.id + "] re-entered context");
            Debug.Write("routines: ");
            foreach (coroutine c in this.coroutines)
            {
                Debug.Write(c.id + " ");
            }
            Debug.WriteLine("");

            this.coroutines.RemoveAll((c) => {
                if (!c.finished)
                {
                    return(false);
                }
                Debug.WriteLine("[" + c.id + "] removing");
                c.Dispose();
                return(true);
            });
        }
Exemple #4
0
        public void collateral_block()
        {
            coroutine self = find_self(this.coroutines);

            Debug.WriteLine("[" + self.id + "] collateral_block");
            this.collateral_blocked.Add(self);
            this.coroutines.Remove(self);
            create_context();
            self.yield_to(this.coroutines.Last());
            Debug.WriteLine("[" + self.id + "] collateral_unblock");
        }
Exemple #5
0
 public void collateral_release(coroutine self)
 {
     if (this.collateral_blocked.Count != 0)
     {
         finish(coroutines);
     }
     while (this.collateral_blocked.Count != 0)
     {
         this.coroutines.Add(this.collateral_blocked[0]);
         this.collateral_blocked.RemoveAt(0);
         self.yield_to(this.coroutines.Last());
     }
 }
Exemple #6
0
        public void create_context()
        {
            this.coroutines.Add(new coroutine(() =>
            {
                try
                {
                    coroutine self = find_self(this.coroutines);
                    Debug.WriteLine("[" + self.id + "] create context");
                    while ((this.running || this.queue.Count != 0) && !self.released)
                    {
                        worker();
                        if (!self.released)
                        {
                            collateral_release(self);
                        }
                    }
                    if (self.released)
                    {
                        finish(this.coroutines);
                    }
                    if (this.switch_context != null)
                    {
                        Action switch_context = this.switch_context;
                        this.switch_context   = null;
                        switch_context();
                    }
                    if (!self.released)
                    {
                        collateral_release(self);
                    }

                    this.exit();
                }
                catch (forced_unwind) {
                    Debug.WriteLine("ignoring forced_unwind");
                }
                catch (Exception e) {
                    Console.Error.WriteLine("oops: " + e);
                    System.Environment.Exit(1);
                }
            }));
        }
Exemple #7
0
 public void call(coroutine c)
 {
     this.context.call(c.context);
 }
Exemple #8
0
 public void yield_to(coroutine c)
 {
     this.yield(c.context);
 }
Exemple #9
0
        public void run()
        {
            try {
                this.worker = () => {
                    context.lck(this, () => {
                        if (this.queue.Count == 0)
                        {
                            Monitor.Pulse(this);
                        }
                        if (this.timers.Count == 0)
                        {
                            while (this.queue.Count == 0 && running)
                            {
                                Monitor.Wait(this);
                            }
                        }
                        else
                        {
                            IEnumerator <KeyValuePair <Deadline, Action> > t = timers.OrderBy(k => k.Key).GetEnumerator();
                            t.MoveNext();
                            bool timedout = false;
                            TimeSpan wait = t.Current.Key.t - DateTime.Now;
                            while (!timedout && this.queue.Count == 0 && running && wait.Ticks > 0)
                            {
                                timedout = !Monitor.Wait(this, wait);
                            }
                        }

                        Action service_timers = () => {
                            IEnumerator <KeyValuePair <Deadline, Action> > t = timers.OrderBy(k => k.Key.t).GetEnumerator();
                            while (timers.Count != 0 && t.MoveNext() && t.Current.Key.expired())
                            {
                                if (Monitor.IsEntered(this))
                                {
                                    Monitor.Exit(this);
                                }
                                t.Current.Value();
                                Monitor.Enter(this);
                                this.timers.Remove(t.Current.Key);
                            }
                        };

                        service_timers();

                        if (this.queue.Count != 0)
                        {
                            Action f = this.queue.Dequeue();
                            Monitor.Exit(this);
                            f();
                            service_timers();
                        }
                    });
                };

                coroutine zero = new coroutine();
                this.exit = () => { Debug.WriteLine("exit"); zero.release(); };
                create_context();

                context.lck(this, () => {
                    while (this.running || this.queue.Count != 0 || this.collateral_blocked.Count != 0)
                    {
                        Monitor.Exit(this);

                        Debug.Assert(this.coroutines.Count != 0);

                        this.coroutines.Last().call(zero);

                        Monitor.Enter(this);

                        this.coroutines.RemoveAll((c) => {
                            if (!c.finished)
                            {
                                return(false);
                            }
                            Debug.WriteLine("[" + c.id + "] removing");
                            c.Dispose();
                            return(true);
                        });
                    }
                    Debug.WriteLine("finish pump");
                    Debug.Assert(this.queue.Count == 0);
                });
            }
            catch (Exception e) {
                Console.Error.WriteLine("oops: " + e);
                System.Environment.Exit(1);
            }
        }