예제 #1
0
        internal static int RegisterResolutionFunction(IntPtr resolutionFunction)
        {
            if (s_lock == null)
            {
                Interlocked.CompareExchange(ref s_lock, new Lock(), null);
            }

            s_lock.Acquire();
            try
            {
                int      newResolutionFunctionId    = s_nextResolutionFunctionPointerIndex;
                IntPtr[] resolutionFunctionPointers = null;
                if (newResolutionFunctionId < s_resolutionFunctionPointers.Length)
                {
                    resolutionFunctionPointers = s_resolutionFunctionPointers;
                }
                else
                {
                    resolutionFunctionPointers = new IntPtr[s_resolutionFunctionPointers.Length * 2];
                    Array.Copy(s_resolutionFunctionPointers, resolutionFunctionPointers, s_resolutionFunctionPointers.Length);
                    s_resolutionFunctionPointers = resolutionFunctionPointers;
                }
                Volatile.Write(ref s_resolutionFunctionPointers[newResolutionFunctionId], resolutionFunction);
                s_nextResolutionFunctionPointerIndex++;
                return(newResolutionFunctionId);
            }
            finally
            {
                s_lock.Release();
            }
        }
예제 #2
0
        public static void RunTest()
        {
            var nekara = RuntimeEnvironment.Client.Api;

            int x1 = 1;
            int x2 = 2;
            int x3 = 1;

            bool flag1 = false;
            bool flag2 = false;
            bool flag3 = false;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    x1    = (x3 + 1) % 4;
                    flag1 = true;
                }
            });

            Task t2 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    x2    = x1;
                    flag2 = true;
                }
            });

            Task t3 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    x3    = x2;
                    flag3 = true;
                }
            });

            Task t4 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    if (flag1 && flag2 && flag3)
                    {
                        nekara.Assert(x1 == x2 && x2 == x3, "Bug found!");
                    }
                }
            });

            Task.WaitAll(t1, t2, t3, t4);
        }
예제 #3
0
        public Task RunCircularBuffer()
        {
            NekaraManagedClient nekara = RuntimeEnvironment.Client;

            this.Buffer     = new char[10];
            this.BufferSize = 10;
            this.First      = 0;
            this.Next       = 0;
            this.Send       = true;
            this.Receive    = false;
            int n = 7;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                for (int i = 0; i < n; i++)
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        if (this.Send)
                        {
                            InsertLogElement(i);
                            this.Send    = false;
                            this.Receive = true;
                        }
                    }
                }
            });

            Task t2 = Task.Run(() =>
            {
                for (int i = 0; i < n; i++)
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        if (this.Receive)
                        {
                            // nekara.Assert(RemoveLogElement() == i, "Bug found!");
                            if (!(RemoveLogElement() == i))
                            {
                                bugFoundCircularBuffer = true;
                            }
                            this.Receive = false;
                            this.Send    = true;
                        }
                    }
                }
            });

            return(Task.WhenAll(t1, t2));
        }
예제 #4
0
        public async Task Lock_DefaultLock()
        {
            Lock <int> l = new Lock <int>();

            var result = await l.Acquire(1, LockMode.Default);

            Assert.AreEqual(AcquireResult.Acquired, result);

            result = await l.Acquire(2, LockMode.Default);

            Assert.AreEqual(AcquireResult.Acquired, result);
        }
예제 #5
0
        public async Task Lock_UpdateBlockDefaultLock()
        {
            Lock <int> l = new Lock <int>();

            await l.Acquire(1, LockMode.Update);

            await Assert.ThrowsExceptionAsync <TimeoutException>(
                async() =>
            {
                await l.Acquire(2, LockMode.Default, timeout: TimeSpan.FromMilliseconds(10));
            }
                );
        }
예제 #6
0
        public static async void Execute()
        {
            Console.WriteLine("  Starting Deadlock Benchmark ...");
            var nekara = RuntimeEnvironment.Client.Api;

            int counter = 1;

            var a = new Lock(1);
            var b = new Lock(2);

            Task t1 = Task.Run(async() =>
            {
                nekara.ContextSwitch();
                a.Acquire();

                nekara.ContextSwitch();
                b.Acquire(); // Deadlock

                nekara.ContextSwitch();
                counter++;

                nekara.ContextSwitch();
                b.Release();

                nekara.ContextSwitch();
                a.Release();
            });

            Task t2 = Task.Run(async() =>
            {
                nekara.ContextSwitch();
                b.Acquire();

                nekara.ContextSwitch();
                a.Acquire(); // Deadlock

                nekara.ContextSwitch();
                counter--;

                nekara.ContextSwitch();
                a.Release();

                nekara.ContextSwitch();
                b.Release();
            });

            await Task.WhenAll(t1, t2);

            Console.WriteLine("  ... Finished Deadlock Benchmark");
        }
예제 #7
0
        public static void RunTest()
        {
            var nekara = RuntimeEnvironment.Client.Api;

            int x       = 1;
            int y       = 2;
            int z       = 4;
            int balance = x;

            bool depositDone  = false;
            bool withdrawDone = false;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    if (depositDone && withdrawDone)
                    {
                        nekara.Assert(balance == (x - y) - z, "Bug found!");
                    }
                }
            });

            Task t2 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    balance    += y;
                    depositDone = true;
                }
            });

            Task t3 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    balance     -= z;
                    withdrawDone = true;
                }
            });

            Task.WaitAll(t1, t2, t3);

            return;
        }
예제 #8
0
파일: Lazy.cs 프로젝트: p-org/nekara-csharp
        public void RunLazyTest()
        {
            bool bugfound = false;

            while (!bugfound)
            {
                NekaraManagedClient nekara = RuntimeEnvironment.Client;
                nekara.Api.CreateSession();

                int data = 0;

                var l = new Lock(1);

                Task t1 = Task.Run(() =>
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        data++;
                    }
                });

                Task t2 = Task.Run(() =>
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        data += 2;
                    }
                });

                Task t3 = Task.Run(() =>
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        // nekara.Api.Assert(data < 3, "Bug found!");
                        if (!(data < 3))
                        {
                            bugfound = true;
                        }
                    }
                });

                Task.WaitAll(t1, t2, t3);

                nekara.Api.WaitForMainTask();
            }
            Assert.True(bugfound);
        }
예제 #9
0
        public async Task Lock_DefaultGrantedAfterUpdateDowngrade()
        {
            Lock <int>    l = new Lock <int>();
            AcquireResult result;

            result = await l.Acquire(1, LockMode.Update);

            Assert.AreEqual(AcquireResult.Acquired, result);

            var task = l.Acquire(2, LockMode.Default);

            l.Downgrade(1);
            result = await task;
            Assert.AreEqual(AcquireResult.Acquired, result);
        }
예제 #10
0
        public async Task Lock_UpdateGrantedAfterDefaultRelease()
        {
            Lock <int>    l = new Lock <int>();
            AcquireResult result;

            result = await l.Acquire(1, LockMode.Default);

            Assert.AreEqual(AcquireResult.Acquired, result);

            var task = l.Acquire(2, LockMode.Default);

            l.Release(1);
            result = await task;
            Assert.AreEqual(AcquireResult.Acquired, result);
        }
예제 #11
0
        public Task Run()
        {
            this.Buffer     = new char[10];
            this.BufferSize = 10;
            this.First      = 0;
            this.Next       = 0;
            this.Send       = true;
            this.Receive    = false;
            int n = 7;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                for (int i = 0; i < n; i++)
                {
                    nekara.ContextSwitch();
                    using (l.Acquire())
                    {
                        if (this.Send)
                        {
                            InsertLogElement(i);
                            this.Send    = false;
                            this.Receive = true;
                        }
                    }
                }
            });

            Task t2 = Task.Run(() =>
            {
                for (int i = 0; i < n; i++)
                {
                    nekara.ContextSwitch();
                    using (l.Acquire())
                    {
                        if (this.Receive)
                        {
                            nekara.Assert(RemoveLogElement() == i, "Bug found!");
                            this.Receive = false;
                            this.Send    = true;
                        }
                    }
                }
            });

            return(Task.WhenAll(t1, t2));
        }
예제 #12
0
        public void RegisterDynamicThreadStaticsInfo(RuntimeTypeHandle runtimeTypeHandle, uint offsetValue, int storageSize)
        {
            bool registered = false;

            Debug.Assert(offsetValue != 0 && storageSize > 0 && runtimeTypeHandle.IsDynamicType());

            _threadStaticsLock.Acquire();
            try
            {
                // Sanity check to make sure we do not register thread statics for the same type more than once
                uint temp;
                Debug.Assert(!_dynamicGenericsThreadStatics.TryGetValue(runtimeTypeHandle, out temp) && storageSize > 0);

                _dynamicGenericsThreadStatics.Add(runtimeTypeHandle, offsetValue);
                _dynamicGenericsThreadStaticSizes.Add(offsetValue, storageSize);
                registered = true;
            }
            finally
            {
                if (!registered)
                {
                    _dynamicGenericsThreadStatics.Remove(runtimeTypeHandle);
                    _dynamicGenericsThreadStaticSizes.Remove(offsetValue);
                }

                _threadStaticsLock.Release();
            }
        }
 // do the acquire operation
 public AcquireResult Acquire(AcquireArgs acquireArgs)
 {
     _lock.Acquire();
     try {
         while (!CanAcquire(acquireArgs))
         {
             enqueue the current thread on the "waitQueue" sensible to posterior wakeups;
             int depth = _lock.ReleaseAll();
             block current thread until it is waked up by a releaser thread;
             _lock.ReAcquire(depth);
         }
         return(AcquireSideEffect(acquireArgs));
     } finally {
         _lock.Release();
     }
 }
        public void RegisterDynamicThreadStaticsInfo(RuntimeTypeHandle runtimeTypeHandle, uint offsetValue, IntPtr gcDesc)
        {
            bool registered = false;

            Debug.Assert(offsetValue != 0 && runtimeTypeHandle.IsDynamicType());

            IntPtr typeManager = runtimeTypeHandle.GetTypeManager().GetIntPtrUNSAFE();

            _threadStaticsLock.Acquire();
            try
            {
                if (!_dynamicGenericsThreadStaticDescs.TryGetValue(typeManager, out LowLevelDictionary <uint, IntPtr> gcDescs))
                {
                    _dynamicGenericsThreadStaticDescs.Add(typeManager, gcDescs = new LowLevelDictionary <uint, IntPtr>());
                }
                gcDescs.Add(offsetValue, gcDesc);
                registered = true;
            }
            finally
            {
                if (!registered)
                {
                    if (_dynamicGenericsThreadStaticDescs.TryGetValue(typeManager, out LowLevelDictionary <uint, IntPtr> gcDescs))
                    {
                        gcDescs.Remove(offsetValue);
                    }
                }

                _threadStaticsLock.Release();
            }
        }
예제 #15
0
        public async Task Lock_UpdateBlockedAndCancelled()
        {
            Lock <int> l = new Lock <int>();

            await l.Acquire(1, LockMode.Update);

            await Assert.ThrowsExceptionAsync <OperationCanceledException>(
                async() =>
            {
                CancellationTokenSource tokenSource = new CancellationTokenSource();
                var task = l.Acquire(2, LockMode.Default, cancellationToken: tokenSource.Token);
                tokenSource.Cancel();
                await task;
            }
                );
        }
    public async Task <ILock> LockAsync(string ck, int ttl = 20000, int retry = 20, int retryDelay = 1000)
    {
        var l   = new SystemDistributedLock(ck, TimeSpan.FromMilliseconds(retryDelay));
        var lck = new Lock(ck, l, ttl, TimeSpan.FromMilliseconds(retry * retryDelay));
        await lck.Acquire();

        return(lck);
    }
예제 #17
0
        public Task Run()
        {
            int size = 10;

            int[] stack = new int[size];
            bool  flag  = false;

            var l = new Lock(0);

            Task t1 = Task.Run(() =>
            {
                for (int i = 0; i < size; i++)
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        this.Push(stack, i);
                        flag = true;
                    }
                    nekara.Api.ContextSwitch();
                }
            });

            Task t2 = Task.Run(() =>
            {
                for (int i = 0; i < size; i++)
                {
                    nekara.Api.ContextSwitch();
                    using (l.Acquire())
                    {
                        nekara.Api.ContextSwitch();
                        if (flag)
                        {
                            // nekara.Assert(this.Pop(stack) != -2, "Bug found!");
                            if (!(this.Pop(stack) != -2))
                            {
                                bugFound = true;
                            }
                        }
                    }
                }
            });

            return(Task.WhenAll(t1, t2));
        }
예제 #18
0
        public async Task Lock_DefaultUpgradeNotDowngraded()
        {
            Lock <int>    l = new Lock <int>();
            AcquireResult result;

            result = await l.Acquire(1, LockMode.Default);

            Assert.AreEqual(AcquireResult.Acquired, result);
            Assert.AreEqual(l.LockMode, LockMode.Default);

            result = await l.Acquire(1, LockMode.Update);

            Assert.AreEqual(AcquireResult.Owned, result);
            Assert.AreEqual(l.LockMode, LockMode.Update);

            result = await l.Acquire(1, LockMode.Default);

            Assert.AreEqual(AcquireResult.Owned, result);
            Assert.AreEqual(l.LockMode, LockMode.Update);
        }
예제 #19
0
        public void Withdraw(int amount)
        {
            lk.Acquire(); /* may block execution */
            int b = Balance;

            if (amount > b)
            {
                throw new WithdrawTooLargeException();
            }
            Balance = b;
            lk.Release();
        }
예제 #20
0
 // generic acquire operation
 public AcquireResult Acquire(AcquireArgs acquireArgs)
 {
     _lock.Acquire();
     try {
         if (reqQueue.Count == 0 && CanAcquire(acquireArgs))
         {
             return(AcquireSideEffect(acquireArgs));
         }
         Request request = new Request(acquireArgs);
         reqQueue.AddLast(request);          // enqueue the "request" at the end of the request queue
         do
         {
             enqueue current thread on the "waitQueue" sensible to posterior wakeups done by "_lock" owners;
             int depth = _lock.ReleaseAll();
             block current thread until it is waked up by a releaser thread;
             _lock.ReAcquire(depth);
         } while (!request.done);
         // the requested acquire operation completed successfully
         return(request.acquireResult);
     } finally {
         _lock.Release();
     }
 }
예제 #21
0
        public static void RunTest()
        {
            var nekara = RuntimeEnvironment.Client.Api;

            int data = 0;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    data++;
                }
            });

            Task t2 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    data += 2;
                }
            });

            Task t3 = Task.Run(() =>
            {
                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    nekara.Assert(data < 3, "Bug found!");
                }
            });

            Task.WaitAll(t1, t2, t3);
        }
예제 #22
0
        public void Lock_RaceToAcquire_Fail()
        {
            var           waitToStart = new ManualResetEventSlim(false);
            var           waitToEnd   = new ManualResetEventSlim(false);
            AcquireResult?resultA     = null;
            AcquireResult?resultB     = null;
            Lock <int>    l           = new Lock <int>();

            Thread a = new Thread(state =>
            {
                l.Acquire(1, LockMode.Default, 100, new CancellationToken(false)).Wait();
                resultA = l.Acquire(1, LockMode.Default, 100, new CancellationToken(false)).Result;
                waitToStart.Set(); //run b

                waitToEnd.Wait();  //wait for b
                Thread.Sleep(110); //keep the lock for 110ms
                l.Release(1);
            });

            Thread b = new Thread(state =>
            {
                waitToStart.Wait();
                waitToEnd.Set();                                                                   //continue a
                resultB = l.Acquire(2, LockMode.Update, 100, new CancellationToken(false)).Result; //wait for the lock for 100ms
            });

            a.Start();
            b.Start();

            a.Join();
            b.Join();

            Assert.IsTrue(resultA.HasValue);
            Assert.IsTrue(resultB.HasValue);
            Assert.AreEqual(AcquireResult.Owned, resultA.Value);
            Assert.AreEqual(AcquireResult.Denied, resultB.Value);
        }
예제 #23
0
        public static void RunTest()
        {
            var nekara = RuntimeEnvironment.Client.Api;

            int iNum1     = 1;
            int iNum2     = 7;
            int dataValue = 0;

            var dataLock = new Lock(1);
            var thisLock = new Lock(2);

            Task[] num1Pool = new Task[iNum1];
            Task[] num2Pool = new Task[iNum2];

            for (int i = 0; i < iNum1; i++)
            {
                num1Pool[i] = Task.Run(() =>
                {
                    nekara.ContextSwitch();
                    using (dataLock.Acquire())
                    {
                        nekara.ContextSwitch();
                        int x = dataValue;

                        nekara.ContextSwitch();
                        dataValue++;

                        nekara.ContextSwitch();
                        nekara.Assert(dataValue == (x + 1), "Bug Found!");
                    }
                });
            }

            for (int i = 0; i < iNum2; i++)
            {
                num2Pool[i] = Task.Run(() =>
                {
                    nekara.ContextSwitch();
                    using (thisLock.Acquire())
                    {
                        nekara.ContextSwitch();
                        dataValue++;
                    }
                });
            }

            Task.WaitAll(num1Pool);
            Task.WaitAll(num2Pool);
        }
예제 #24
0
        public static async void Run()
        {
            var nekara = RuntimeEnvironment.Client.Api;

            int n    = 7;
            int phil = 0;

            var countLock = new Lock(0);

            Lock[] locks = new Lock[n];
            for (int i = 0; i < n; i++)
            {
                locks[i] = new Lock(1 + i);
            }

            Task[] tasks = new Task[n];
            for (int i = 0; i < n; i++)
            {
                int id = i;

                tasks[i] = Task.Run(() =>
                {
                    int left  = id % n;
                    int right = (id + 1) % n;

                    nekara.ContextSwitch();
                    var releaserR = locks[right].Acquire();

                    nekara.ContextSwitch();
                    var releaserL = locks[left].Acquire();

                    nekara.ContextSwitch();
                    releaserL.Dispose();

                    nekara.ContextSwitch();
                    releaserR.Dispose();

                    using (countLock.Acquire())
                    {
                        ++phil;
                        nekara.Assert(phil != n, "Bug found!");
                    }
                });
            }

            await Task.WhenAll(tasks);
        }
예제 #25
0
            // Get the event registration token table for an event.  These are indexed by the remove method of the event.
            private static EventCacheEntry GetEventRegistrationTokenTableInternal(object instance, Action <EventRegistrationToken> removeMethod, bool createIfNotFound)
            {
                Debug.Assert(instance != null);
                Debug.Assert(removeMethod != null);
                Debug.Assert(s_eventRegistrations != null);

                EventCacheKey eventCacheKey;

                eventCacheKey.target = instance;
#if false
                eventCacheKey.method = removeMethod.Method;
#endif
                RuntimeTypeHandle thDummy;
                eventCacheKey.method = removeMethod.GetFunctionPointer(out thDummy);

                try
                {
                    s_eventRegistrationsLock.Acquire();

                    EventCacheEntry eventCacheEntry;

                    if (!s_eventRegistrations.TryGetValue(eventCacheKey, out eventCacheEntry))
                    {
                        if (!createIfNotFound)
                        {
                            // No need to create an entry in this case
                            return(null);
                        }
#if false
                        BCLDebug.Log("INTEROP", "[WinRT_Eventing] Adding (" + instance + "," + removeMethod.Method + ") into cache" + "\n");
#endif
                        eventCacheEntry = new EventCacheEntry();
                        eventCacheEntry.registrationTable = new ConditionalWeakTable <object, EventRegistrationTokenListWithCount>();
                        eventCacheEntry.tokenListCount    = new TokenListCount(eventCacheKey);
                        eventCacheEntry._lock             = new Lock();

                        s_eventRegistrations.Add(eventCacheKey, eventCacheEntry);
                    }

                    return(eventCacheEntry);
                }
                finally
                {
                    s_eventRegistrationsLock.Release();
                }
            }
예제 #26
0
파일: CompileTest.cs 프로젝트: naman/Nekara
        static void Foo()
        {
            Console.WriteLine("Foo/Acquire()");
            lck.Acquire();

            Console.WriteLine("Foo/ContextSwitch()");
            int lx1 = x;

            Console.WriteLine("Foo/ContextSwitch()");
            int lx2 = x;

            Console.WriteLine("Foo/Release()");
            lck.Release();

            nekara.Assert(lx1 == lx2, "Race!");

            Console.WriteLine("Foo EndTask");
        }
예제 #27
0
        public static Task[] Dine(int n)
        {
            phil = 0;

            var countLock = new Lock(0);

            Lock[] locks = new Lock[n];
            for (int i = 0; i < n; i++)
            {
                locks[i] = new Lock(1 + i);
            }

            Task[] tasks = new Task[n];
            for (int i = 0; i < n; i++)
            {
                int id = i;

                tasks[i] = Task.Run(() =>
                {
                    int left  = id % n;
                    int right = (id + 1) % n;

                    nekara.ContextSwitch();
                    var releaserR = locks[right].Acquire();

                    nekara.ContextSwitch();
                    var releaserL = locks[left].Acquire();

                    using (countLock.Acquire())
                    {
                        phil++;
                        // Console.WriteLine("Philosopher {0} eats. Incrementing phil: {1}", id, phil);
                    }

                    nekara.ContextSwitch();
                    releaserR.Dispose();

                    nekara.ContextSwitch();
                    releaserL.Dispose();
                });
            }

            return(tasks);
        }
예제 #28
0
            // Get the event registration token table for an event.  These are indexed by the remove method of the event.
            private static System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> GetEventRegistrationTokenTable(object instance, Action <EventRegistrationToken> removeMethod)
            {
                Debug.Assert(instance != null);
                Debug.Assert(removeMethod != null);
                Debug.Assert(s_eventRegistrations != null);

                try
                {
                    s_eventRegistrationsLock.Acquire();

                    System.Collections.Generic.Internal.Dictionary <IntPtr, System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> > instanceMap = null;

                    if (!s_eventRegistrations.TryGetValue(instance, out instanceMap))
                    {
                        instanceMap = new System.Collections.Generic.Internal.Dictionary <IntPtr, System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> >();
                        s_eventRegistrations.Add(instance, instanceMap);
                    }

                    System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList> tokens = null;

                    // Because this code already is tied to a specific instance, the type handle associated with the
                    // delegate is not needed.
                    RuntimeTypeHandle thDummy;

                    if (!instanceMap.TryGetValue(removeMethod.GetFunctionPointer(out thDummy), out tokens))
                    {
                        tokens = new System.Collections.Generic.Internal.Dictionary <object, EventRegistrationTokenList>(true);
                        instanceMap.Add(removeMethod.GetFunctionPointer(out thDummy), tokens);
                    }

                    return(tokens);
                }
                finally
                {
                    s_eventRegistrationsLock.Release();
                }
            }
예제 #29
0
        public Task Run()
        {
            this.Size = 20;
            int[] storedElements = new int[this.Size];

            QType queue = new QType
            {
                Element = new int[this.Size],
                Head    = 0,
                Tail    = 0,
                Amount  = 0
            };

            bool enqueue = true;
            bool dequeue = false;

            var l = new Lock(1);

            Task t1 = Task.Run(() =>
            {
                int value;

                nekara.ContextSwitch();
                using (l.Acquire())
                {
                    nekara.ContextSwitch();
                    value = 0;

                    nekara.ContextSwitch();
                    storedElements[0] = value;
                }

                for (int i = 0; i < (this.Size - 1); i++)
                {
                    nekara.ContextSwitch();
                    using (l.Acquire())
                    {
                        nekara.ContextSwitch();
                        if (enqueue)
                        {
                            nekara.ContextSwitch();
                            value++;

                            nekara.ContextSwitch();
                            this.Enqueue(queue, value);

                            nekara.ContextSwitch();
                            storedElements[i + 1] = value;

                            nekara.ContextSwitch();
                            enqueue = false;

                            nekara.ContextSwitch();
                            dequeue = true;
                        }
                    }
                }
            });

            Task t2 = Task.Run(() =>
            {
                for (int i = 0; i < this.Size; i++)
                {
                    nekara.ContextSwitch();
                    using (l.Acquire())
                    {
                        nekara.ContextSwitch();
                        if (dequeue)
                        {
                            nekara.Assert(this.Dequeue(queue) == storedElements[i], "<Queue> Bug found!");
                            nekara.ContextSwitch();
                            dequeue = false;

                            nekara.ContextSwitch();
                            enqueue = true;
                        }
                    }
                }
            });

            return(Task.WhenAll(t1, t2));
        }
예제 #30
0
        private static unsafe Entry CacheMiss(IntPtr context, IntPtr signature, RuntimeObjectFactory factory, object contextObject = null)
        {
            IntPtr result = IntPtr.Zero, auxResult = IntPtr.Zero;
            bool   previouslyCached = false;

            //
            // Try to find the entry in the previous version of the cache that is kept alive by weak reference
            //
            if (s_previousCache.IsAllocated)
            {
                Entry[] previousCache = (Entry[])s_previousCache.Target;
                if (previousCache != null)
                {
                    Entry previousEntry = LookupInCache(previousCache, context, signature);
                    if (previousEntry != null)
                    {
                        result           = previousEntry.Result;
                        auxResult        = previousEntry.AuxResult;
                        previouslyCached = true;
                    }
                }
            }

            //
            // Call into the type loader to compute the target
            //
            if (!previouslyCached)
            {
                result = factory(context, signature, contextObject, ref auxResult);
            }

            //
            // Update the cache under the lock
            //
            if (s_lock == null)
            {
                Interlocked.CompareExchange(ref s_lock, new Lock(), null);
            }

            s_lock.Acquire();
            try
            {
                // Avoid duplicate entries
                Entry existingEntry = LookupInCache(s_cache, context, signature);
                if (existingEntry != null)
                {
                    return(existingEntry);
                }

                // Resize cache as necessary
                Entry[] cache = ResizeCacheForNewEntryAsNecessary();

                int key = ((context.GetHashCode() >> 4) ^ signature.GetHashCode()) & (cache.Length - 1);

                Entry newEntry = new Entry()
                {
                    Context = context, Signature = signature, Result = result, AuxResult = auxResult, Next = cache[key]
                };
                cache[key] = newEntry;
                return(newEntry);
            }
            finally
            {
                s_lock.Release();
            }
        }