Livt packages

Livt.Collections

Version 1.4.2

Fixed-capacity FIFOs, queues, stacks, circular buffers, lists, and bit sets for Livt hardware.

Published files (62)

tests/queue/ConcurrentQueueTest.lvt

namespace Livt.Collections.Tests

using Livt.Collections

/**
 * Exercises shared mutation dispatch with simultaneous producers and consumers.
 */
@Test
component ConcurrentQueueTest
{
	// Shared fixture instances, signals, and observation state.
	queue: Livt.Collections.Queue<byte, 3>
	firstDone: bool
	secondDone: bool
	consumerDone: bool

	/**
	 * Uses a small queue to force backpressure and pointer wrapping.
	 */
	new()
	{
		this.queue = new Livt.Collections.Queue<byte, 3>()
	}

	/**
	 * Produces the first ordered byte stream.
	 */
	process First()
	{
		state Start {
			for (var index = 0; index < 8; index++) {
				var accepted = false

				while (!accepted) {
					accepted = this.queue.TryEnqueue((index + 1) as byte)
				}
			}

			firstDone = true
			goto Done
		}

		state Done {
			goto Done
		}
	}

	/**
	 * Produces a distinguishable second ordered stream.
	 */
	process Second()
	{
		state Start {
			for (var index = 0; index < 8; index++) {
				var accepted = false

				while (!accepted) {
					accepted = this.queue.TryEnqueue((index + 129) as byte)
				}
			}

			secondDone = true
			goto Done
		}

		state Done {
			goto Done
		}
	}

	/**
	 * Checks per-producer ordering, loss, duplication and failed-dequeue values.
	 */
	process Consumer()
	{
		state Start {
			var first = 0
			var second = 0

			while (first + second < 16) {
				var value: byte = 0xFF
				var accepted = this.queue.TryDequeue(value)

				if (accepted) {
					if (value < 0x80) {
						first++
						assert value == first as byte
					} else {
						second++
						assert value == (second + 128) as byte
					}
				} else {
					assert value == 0x00
				}
			}

			assert first == 8
			assert second == 8
			consumerDone = true
			goto Done
		}

		state Done {
			goto Done
		}
	}

	/**
	 * Bounds completion and checks final queue state without imposing interleaving.
	 */
	@Test
	fn TestConcurrentTransactions()
	{
		Simulation.Wait(7000)
		assert firstDone == true
		assert secondDone == true
		assert consumerDone == true
		assert this.queue.GetCount() == 0
		assert this.queue.GetSpace() == 3
	}
}