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(); } }
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); }
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)); }
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); }
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)); } ); }
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"); }
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; }
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); }
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); }
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); }
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)); }
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(); } }
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); }
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)); }
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); }
public void Withdraw(int amount) { lk.Acquire(); /* may block execution */ int b = Balance; if (amount > b) { throw new WithdrawTooLargeException(); } Balance = b; lk.Release(); }
// 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(); } }
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); }
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); }
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); }
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); }
// 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(); } }
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"); }
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); }
// 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(); } }
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)); }
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(); } }