/** * Removes and returns first element, or Default if empty. */ private T UnlinkFirst() { Node <T> f = First; if (f == null) { return(Default); } Node <T> n = f.Next; T item = f.Item; f.Item = Default; f.Next = f; // help GC First = n; if (n == null) { Last = null; } else { n.Prev = null; } --Count; NotFull.SignalCondition(); return(item); }
/// <summary> /// Get & remove element from head of Q. /// </summary> /// <returns>Returns head element, or Default if queue is empty.</returns> /// throws ThreadInterruptedException. public T Pop() { T v = Default; AccessLock.WaitOne(); try { if (Head != Tail) { v = ContainerList[Head++]; Head %= MaxCapacity; if (Count > 0) { --Count; } NotFull.SignalCondition(); } } finally { AccessLock.ReleaseMutex(); } return(v); }
/** * Links node as first element, or returns false if full. */ private bool LinkFirst(T v) { // assert lock.isHeldByCurrentThread(); if (Count >= MaxCapacity) { return(false); } Node <T> f = First; Node <T> x = new Node <T>(v, null, f); First = x; if (Last == null) { Last = x; } else { f.Prev = x; } ++Count; NotEmpty.SignalCondition(); return(true); }
/// <summary> /// Add v to tail of Q. /// </summary> /// <param name="v"></param> /// <returns>Returns v, or Default if queue is full.</returns> /// throws ThreadInterruptedException. public T Push(T v) { AccessLock.WaitOne(); try { if (((Tail + 1) % MaxCapacity) == Head) { v = Default; } else { ContainerList[Tail++] = v; Tail %= MaxCapacity; if (Count < MaxCapacity) { ++Count; } NotEmpty.SignalCondition(); } } finally { AccessLock.ReleaseMutex(); } return(v); }
/// <summary> /// Release token to free list. /// </summary> /// <param name="idx"></param> /// throws ThreadInterruptedException. public void Release(int idx) { AccessLock.WaitOne(); try { if (idx < MaxCapacity) { ContainerList[idx] = FreeIndex; FreeIndex = idx; if (Count > 0) { --Count; } NotFull.SignalCondition(); } } finally { AccessLock.ReleaseMutex(); } }
/// <summary> /// Fetch a free token from list. /// </summary> /// <returns>Returns token, or Default if none free.</returns> /// throws ThreadInterruptedException. public int Allocate() { int idx = Default; AccessLock.WaitOne(); try { idx = FreeIndex; if (idx != Default) { FreeIndex = ContainerList[idx]; if (Count < MaxCapacity) { ++Count; } NotEmpty.SignalCondition(); } } finally { AccessLock.ReleaseMutex(); } return(idx); }