From 8eccfaad1ab0096ea4b8caf84378c6deda9e1363 Mon Sep 17 00:00:00 2001 From: Claudio Scheer Date: Fri, 17 Apr 2020 14:53:35 -0300 Subject: [PATCH] Change queue to different types of list --- src/Test.java | 104 ------------ src/TestMonitor.java | 57 ------- src/enums/ListOperationType.java | 5 + src/enums/ProducerConsumerType.java | 5 - src/interfaces/GenericListInterface.java | 12 ++ src/lists/CoarseList.java | 173 ++++++++++++++++++++ src/lists/FineList.java | 199 +++++++++++++++++++++++ src/lists/GenericOperator.java | 58 +++++++ src/lists/IntegerListOperator.java | 28 ++++ src/lists/LazyList.java | 178 ++++++++++++++++++++ src/lists/LockFreeList.java | 182 +++++++++++++++++++++ src/lists/OptimisticList.java | 173 ++++++++++++++++++++ src/main/Consumer.java | 20 --- src/main/Monitor.java | 77 --------- src/main/MonitorSynchronized.java | 57 ------- src/main/Producer.java | 20 --- src/main/ProducerConsumer.java | 40 ----- src/main/Test.java | 94 +++++++++++ src/main/TestGuided.java | 21 +++ src/utils/RandomNumbers.java | 12 ++ test/no-warm-up.pdf | Bin 43179 -> 0 bytes test/output/100000-1000000-0-1-11.txt | 16 -- test/output/100000-1000000-0-11-1.txt | 16 -- test/output/100000-1000000-0-4-8.txt | 16 -- test/output/100000-1000000-0-8-4.txt | 16 -- test/output/100000-1000000-1-1-11.txt | 17 -- test/output/100000-1000000-1-11-1.txt | 17 -- test/output/100000-1000000-1-4-8.txt | 17 -- test/output/100000-1000000-1-8-4.txt | 17 -- test/output/100000-300000-0-1-11.txt | 16 -- test/output/100000-300000-0-11-1.txt | 16 -- test/output/100000-300000-0-4-8.txt | 16 -- test/output/100000-300000-0-8-4.txt | 16 -- test/output/100000-300000-1-1-11.txt | 17 -- test/output/100000-300000-1-11-1.txt | 17 -- test/output/100000-300000-1-4-8.txt | 17 -- test/output/100000-300000-1-8-4.txt | 17 -- test/output/100000-500000-0-1-11.txt | 16 -- test/output/100000-500000-0-11-1.txt | 16 -- test/output/100000-500000-0-4-8.txt | 16 -- test/output/100000-500000-0-8-4.txt | 16 -- test/output/100000-500000-1-1-11.txt | 17 -- test/output/100000-500000-1-11-1.txt | 17 -- test/output/100000-500000-1-4-8.txt | 17 -- test/output/100000-500000-1-8-4.txt | 17 -- test/output/200000-1000000-0-1-11.txt | 16 -- test/output/200000-1000000-0-11-1.txt | 16 -- test/output/200000-1000000-0-4-8.txt | 16 -- test/output/200000-1000000-0-8-4.txt | 16 -- test/output/200000-1000000-1-1-11.txt | 17 -- test/output/200000-1000000-1-11-1.txt | 17 -- test/output/200000-1000000-1-4-8.txt | 17 -- test/output/200000-1000000-1-8-4.txt | 17 -- test/output/200000-300000-0-1-11.txt | 16 -- test/output/200000-300000-0-11-1.txt | 16 -- test/output/200000-300000-0-4-8.txt | 16 -- test/output/200000-300000-0-8-4.txt | 16 -- test/output/200000-300000-1-1-11.txt | 17 -- test/output/200000-300000-1-11-1.txt | 17 -- test/output/200000-300000-1-4-8.txt | 17 -- test/output/200000-300000-1-8-4.txt | 17 -- test/output/200000-500000-0-1-11.txt | 16 -- test/output/200000-500000-0-11-1.txt | 16 -- test/output/200000-500000-0-4-8.txt | 16 -- test/output/200000-500000-0-8-4.txt | 16 -- test/output/200000-500000-1-1-11.txt | 17 -- test/output/200000-500000-1-11-1.txt | 17 -- test/output/200000-500000-1-4-8.txt | 17 -- test/output/200000-500000-1-8-4.txt | 17 -- test/output/300000-1000000-0-1-11.txt | 16 -- test/output/300000-1000000-0-11-1.txt | 16 -- test/output/300000-1000000-0-4-8.txt | 16 -- test/output/300000-1000000-0-8-4.txt | 16 -- test/output/300000-1000000-1-1-11.txt | 17 -- test/output/300000-1000000-1-11-1.txt | 17 -- test/output/300000-1000000-1-4-8.txt | 17 -- test/output/300000-1000000-1-8-4.txt | 17 -- test/output/300000-300000-0-1-11.txt | 16 -- test/output/300000-300000-0-11-1.txt | 16 -- test/output/300000-300000-0-4-8.txt | 16 -- test/output/300000-300000-0-8-4.txt | 16 -- test/output/300000-300000-1-1-11.txt | 17 -- test/output/300000-300000-1-11-1.txt | 17 -- test/output/300000-300000-1-4-8.txt | 17 -- test/output/300000-300000-1-8-4.txt | 17 -- test/output/300000-500000-0-1-11.txt | 16 -- test/output/300000-500000-0-11-1.txt | 16 -- test/output/300000-500000-0-4-8.txt | 16 -- test/output/300000-500000-0-8-4.txt | 16 -- test/output/300000-500000-1-1-11.txt | 17 -- test/output/300000-500000-1-11-1.txt | 17 -- test/output/300000-500000-1-4-8.txt | 17 -- test/output/300000-500000-1-8-4.txt | 17 -- test/run-tests.sh | 16 +- test/warm-up.pdf | Bin 43306 -> 0 bytes 95 files changed, 1141 insertions(+), 1578 deletions(-) delete mode 100644 src/Test.java delete mode 100644 src/TestMonitor.java create mode 100644 src/enums/ListOperationType.java delete mode 100644 src/enums/ProducerConsumerType.java create mode 100644 src/interfaces/GenericListInterface.java create mode 100644 src/lists/CoarseList.java create mode 100644 src/lists/FineList.java create mode 100644 src/lists/GenericOperator.java create mode 100644 src/lists/IntegerListOperator.java create mode 100644 src/lists/LazyList.java create mode 100644 src/lists/LockFreeList.java create mode 100644 src/lists/OptimisticList.java delete mode 100644 src/main/Consumer.java delete mode 100644 src/main/Monitor.java delete mode 100644 src/main/MonitorSynchronized.java delete mode 100644 src/main/Producer.java delete mode 100644 src/main/ProducerConsumer.java create mode 100644 src/main/Test.java create mode 100644 src/main/TestGuided.java create mode 100644 src/utils/RandomNumbers.java delete mode 100644 test/no-warm-up.pdf delete mode 100644 test/output/100000-1000000-0-1-11.txt delete mode 100644 test/output/100000-1000000-0-11-1.txt delete mode 100644 test/output/100000-1000000-0-4-8.txt delete mode 100644 test/output/100000-1000000-0-8-4.txt delete mode 100644 test/output/100000-1000000-1-1-11.txt delete mode 100644 test/output/100000-1000000-1-11-1.txt delete mode 100644 test/output/100000-1000000-1-4-8.txt delete mode 100644 test/output/100000-1000000-1-8-4.txt delete mode 100644 test/output/100000-300000-0-1-11.txt delete mode 100644 test/output/100000-300000-0-11-1.txt delete mode 100644 test/output/100000-300000-0-4-8.txt delete mode 100644 test/output/100000-300000-0-8-4.txt delete mode 100644 test/output/100000-300000-1-1-11.txt delete mode 100644 test/output/100000-300000-1-11-1.txt delete mode 100644 test/output/100000-300000-1-4-8.txt delete mode 100644 test/output/100000-300000-1-8-4.txt delete mode 100644 test/output/100000-500000-0-1-11.txt delete mode 100644 test/output/100000-500000-0-11-1.txt delete mode 100644 test/output/100000-500000-0-4-8.txt delete mode 100644 test/output/100000-500000-0-8-4.txt delete mode 100644 test/output/100000-500000-1-1-11.txt delete mode 100644 test/output/100000-500000-1-11-1.txt delete mode 100644 test/output/100000-500000-1-4-8.txt delete mode 100644 test/output/100000-500000-1-8-4.txt delete mode 100644 test/output/200000-1000000-0-1-11.txt delete mode 100644 test/output/200000-1000000-0-11-1.txt delete mode 100644 test/output/200000-1000000-0-4-8.txt delete mode 100644 test/output/200000-1000000-0-8-4.txt delete mode 100644 test/output/200000-1000000-1-1-11.txt delete mode 100644 test/output/200000-1000000-1-11-1.txt delete mode 100644 test/output/200000-1000000-1-4-8.txt delete mode 100644 test/output/200000-1000000-1-8-4.txt delete mode 100644 test/output/200000-300000-0-1-11.txt delete mode 100644 test/output/200000-300000-0-11-1.txt delete mode 100644 test/output/200000-300000-0-4-8.txt delete mode 100644 test/output/200000-300000-0-8-4.txt delete mode 100644 test/output/200000-300000-1-1-11.txt delete mode 100644 test/output/200000-300000-1-11-1.txt delete mode 100644 test/output/200000-300000-1-4-8.txt delete mode 100644 test/output/200000-300000-1-8-4.txt delete mode 100644 test/output/200000-500000-0-1-11.txt delete mode 100644 test/output/200000-500000-0-11-1.txt delete mode 100644 test/output/200000-500000-0-4-8.txt delete mode 100644 test/output/200000-500000-0-8-4.txt delete mode 100644 test/output/200000-500000-1-1-11.txt delete mode 100644 test/output/200000-500000-1-11-1.txt delete mode 100644 test/output/200000-500000-1-4-8.txt delete mode 100644 test/output/200000-500000-1-8-4.txt delete mode 100644 test/output/300000-1000000-0-1-11.txt delete mode 100644 test/output/300000-1000000-0-11-1.txt delete mode 100644 test/output/300000-1000000-0-4-8.txt delete mode 100644 test/output/300000-1000000-0-8-4.txt delete mode 100644 test/output/300000-1000000-1-1-11.txt delete mode 100644 test/output/300000-1000000-1-11-1.txt delete mode 100644 test/output/300000-1000000-1-4-8.txt delete mode 100644 test/output/300000-1000000-1-8-4.txt delete mode 100644 test/output/300000-300000-0-1-11.txt delete mode 100644 test/output/300000-300000-0-11-1.txt delete mode 100644 test/output/300000-300000-0-4-8.txt delete mode 100644 test/output/300000-300000-0-8-4.txt delete mode 100644 test/output/300000-300000-1-1-11.txt delete mode 100644 test/output/300000-300000-1-11-1.txt delete mode 100644 test/output/300000-300000-1-4-8.txt delete mode 100644 test/output/300000-300000-1-8-4.txt delete mode 100644 test/output/300000-500000-0-1-11.txt delete mode 100644 test/output/300000-500000-0-11-1.txt delete mode 100644 test/output/300000-500000-0-4-8.txt delete mode 100644 test/output/300000-500000-0-8-4.txt delete mode 100644 test/output/300000-500000-1-1-11.txt delete mode 100644 test/output/300000-500000-1-11-1.txt delete mode 100644 test/output/300000-500000-1-4-8.txt delete mode 100644 test/output/300000-500000-1-8-4.txt delete mode 100644 test/warm-up.pdf diff --git a/src/Test.java b/src/Test.java deleted file mode 100644 index 66d1150..0000000 --- a/src/Test.java +++ /dev/null @@ -1,104 +0,0 @@ -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.TimeUnit; - -import main.Consumer; -import main.Monitor; -import main.Producer; -import main.ProducerConsumer; -import enums.ProducerConsumerType; - -public class Test { - - private static List getAllProducersConsumers(int numberProducers, int numberConsumers, - Monitor monitor) { - List producersConsumers = new ArrayList<>(); - for (int i = 0; i < numberConsumers; i++) { - producersConsumers.add(new Consumer(monitor)); - } - for (int i = 0; i < numberProducers; i++) { - producersConsumers.add(new Producer(monitor)); - } - return producersConsumers; - } - - private static int getOperationsCountSum(List producerConsumers, ProducerConsumerType type) { - int sum = 0; - for (ProducerConsumer producerConsumer : producerConsumers) { - if (producerConsumer.getType() == type) { - sum += producerConsumer.getOperationsCount(); - } - } - return sum; - } - - public static void main(String[] args) { - int listInitialSize = Integer.parseInt(args[0]); - int listMaximumSize = Integer.parseInt(args[1]); - boolean warmUp = args[2].equals("1"); - int producers = Integer.parseInt(args[3]); - int consumers = Integer.parseInt(args[4]); - - System.out.println(); - System.out.println(String.format("Initial list size: %s", listInitialSize)); - System.out.println(String.format("Maximum list size: %s", listMaximumSize)); - System.out.println(String.format("Use warm-up: %s", warmUp)); - System.out.println(String.format("Number of producers: %s", producers)); - System.out.println(String.format("Number of consumers: %s", consumers)); - System.out.println(); - System.out.println("Starting test..."); - - // Start the monitor. - Monitor monitor = new Monitor(listMaximumSize); - for (int i = 0; i < listInitialSize; i++) { - try { - monitor.enq(Math.random()); - } catch (InterruptedException e) { - } - } - - ProducerConsumer.countingOperations = !warmUp; - - System.out.println("Starting producers and consumers..."); - List producersConsumers = getAllProducersConsumers(producers, consumers, monitor); - for (ProducerConsumer producerConsumer : producersConsumers) { - producerConsumer.startThread(); - } - - // Use a period of warm-up. During this period, operations are not counted. - if (warmUp) { - System.out.println("Warming-up..."); - try { - TimeUnit.SECONDS.sleep(15); - } catch (InterruptedException e) { - } - ProducerConsumer.countingOperations = true; - } - - try { - System.out.println("Producing and consuming..."); - TimeUnit.SECONDS.sleep(60); - } catch (InterruptedException e) { - } - - System.out.println("Interrupting threads..."); - System.out.println(); - for (ProducerConsumer producerConsumer : producersConsumers) { - try { - producerConsumer.interrupt(); - producerConsumer.join(); - } catch (InterruptedException e) { - } - } - - int currentMonitorSize = monitor.getCurrentSize(); - int enqOperationsCount = getOperationsCountSum(producersConsumers, ProducerConsumerType.producer); - int deqOperationsCount = getOperationsCountSum(producersConsumers, ProducerConsumerType.consumer); - - System.out.println(String.format("Current monitor size: %s", currentMonitorSize)); - System.out.println(String.format("Number of enqueues: %s", enqOperationsCount)); - System.out.println(String.format("Number of dequeues: %s", deqOperationsCount)); - - System.out.println("Finished."); - } -} diff --git a/src/TestMonitor.java b/src/TestMonitor.java deleted file mode 100644 index 3b97e1b..0000000 --- a/src/TestMonitor.java +++ /dev/null @@ -1,57 +0,0 @@ -import main.Monitor; -import main.MonitorSynchronized; - -public class TestMonitor { - - public static void main(String[] args) { - int maxSize = 100000000; - int operations = 100000000; - - System.out.println("Monitor..."); - Monitor monitor = new Monitor(maxSize); - long startTimeEnq = System.nanoTime(); - for (int i = 0; i < operations; i++) { - try { - monitor.enq(Math.random()); - } catch (InterruptedException e) { - } - } - long endTimeEnq = System.nanoTime(); - double durationEnq = (endTimeEnq - startTimeEnq) / 1_000_000_000d; - System.out.println(String.format("Enqueue: %s", durationEnq)); - long startTimeDeq = System.nanoTime(); - for (int i = 0; i < operations; i++) { - try { - Double d = monitor.deq(); - } catch (InterruptedException e) { - } - } - long endTimeDeq = System.nanoTime(); - double durationDeq = (endTimeDeq - startTimeDeq) / 1_000_000_000d; - System.out.println(String.format("Dequeue: %s", durationDeq)); - - System.out.println(); - System.out.println("MonitorSynchronized..."); - MonitorSynchronized monitorSynchronized = new MonitorSynchronized(maxSize); - long startTimeEnq2 = System.nanoTime(); - for (int i = 0; i < operations; i++) { - try { - monitorSynchronized.enq(Math.random()); - } catch (InterruptedException e) { - } - } - long endTimeEnq2 = System.nanoTime(); - double durationEnq2 = (endTimeEnq2 - startTimeEnq2) / 1_000_000_000d; - System.out.println(String.format("Enqueue: %s", durationEnq2)); - long startTimeDeq2 = System.nanoTime(); - for (int i = 0; i < operations; i++) { - try { - Double d = monitorSynchronized.deq(); - } catch (InterruptedException e) { - } - } - long endTimeDeq2 = System.nanoTime(); - double durationDeq2 = (endTimeDeq2 - startTimeDeq2) / 1_000_000_000d; - System.out.println(String.format("Dequeue: %s", durationDeq2)); - } -} diff --git a/src/enums/ListOperationType.java b/src/enums/ListOperationType.java new file mode 100644 index 0000000..f13b2ca --- /dev/null +++ b/src/enums/ListOperationType.java @@ -0,0 +1,5 @@ +package enums; + +public enum ListOperationType { + add, remove, contains, listSize +} \ No newline at end of file diff --git a/src/enums/ProducerConsumerType.java b/src/enums/ProducerConsumerType.java deleted file mode 100644 index 49ce5a3..0000000 --- a/src/enums/ProducerConsumerType.java +++ /dev/null @@ -1,5 +0,0 @@ -package enums; - -public enum ProducerConsumerType { - producer, consumer, -} \ No newline at end of file diff --git a/src/interfaces/GenericListInterface.java b/src/interfaces/GenericListInterface.java new file mode 100644 index 0000000..162188f --- /dev/null +++ b/src/interfaces/GenericListInterface.java @@ -0,0 +1,12 @@ +package interfaces; + +public interface GenericListInterface { + + public boolean add(T item); + + public boolean remove(T item); + + public boolean contains(T item); + + public int size(); +} \ No newline at end of file diff --git a/src/lists/CoarseList.java b/src/lists/CoarseList.java new file mode 100644 index 0000000..857088b --- /dev/null +++ b/src/lists/CoarseList.java @@ -0,0 +1,173 @@ +/* +* CoarseList.java +* +* Created on January 3, 2006, 5:02 PM +* Updated on April 14, 2020, 1:13 PM, by Claudio Scheer +* +* From "Multiprocessor Synchronization and Concurrent Data Structures", by Maurice Herlihy and Nir Shavit. +* Copyright 2006 Elsevier Inc. All rights reserved. +*/ +package lists; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import interfaces.GenericListInterface; + +/** + * List using coarse-grained synchronization. + * + * @param T Item type. + * @author Maurice Herlihy + */ +public class CoarseList implements GenericListInterface { + // First list Node. + private Node head; + // Last list Node. + private Node tail; + // Synchronizes access to list. + private Lock lock = new ReentrantLock(); + + public CoarseList() { + // Add sentinels to start and end. + this.head = new Node(Integer.MIN_VALUE); + this.tail = new Node(Integer.MAX_VALUE); + head.next = this.tail; + } + + /** + * Add an element. + * + * @param item Element to add. + * @return True iff element was not there already. + */ + @Override + public boolean add(T item) { + Node pred, curr; + int key = item.hashCode(); + lock.lock(); + try { + pred = this.head; + curr = pred.next; + while (curr.key < key) { + pred = curr; + curr = curr.next; + } + if (key == curr.key) { + // Element already present. + return false; + } else { + // Add element. + Node node = new Node(item); + node.next = curr; + pred.next = node; + return true; + } + } finally { + lock.unlock(); + } + } + + /** + * Remove an element. + * + * @param item Element to remove. + * @return True iff element was present. + */ + @Override + public boolean remove(T item) { + Node pred, curr; + int key = item.hashCode(); + lock.lock(); + try { + pred = this.head; + curr = pred.next; + while (curr.key < key) { + pred = curr; + curr = curr.next; + } + if (key == curr.key) { + // Element is present. + pred.next = curr.next; + return true; + } else { + // Element is not present. + return false; + } + } finally { + lock.unlock(); + } + } + + /** + * Test whether element is present. + * + * @param item Element to test. + * @return True iff element is present. + */ + @Override + public boolean contains(T item) { + Node pred, curr; + int key = item.hashCode(); + lock.lock(); + try { + pred = this.head; + curr = pred.next; + while (curr.key < key) { + pred = curr; + curr = curr.next; + } + return (key == curr.key); + } finally { + lock.unlock(); + } + } + + @Override + public int size() { + Node pred, curr; + lock.lock(); + try { + int count = 0; + pred = this.head; + curr = pred.next; + while (curr.item != null) { + ++count; + pred = curr; + curr = curr.next; + } + return count; + } finally { + lock.unlock(); + } + } + + private class Node { + // Actual item. + T item; + // Item's hash code. + int key; + // Next Node in list. + Node next; + + /** + * Constructor for usual Node. + * + * @param item Element in list. + */ + Node(T item) { + this.item = item; + this.key = item.hashCode(); + } + + /** + * Constructor for sentinel Node. + * + * @param key Should be min or max int value. + */ + Node(int key) { + this.item = null; + this.key = key; + } + } +} diff --git a/src/lists/FineList.java b/src/lists/FineList.java new file mode 100644 index 0000000..ba6c6ea --- /dev/null +++ b/src/lists/FineList.java @@ -0,0 +1,199 @@ +/* + * FineList.java + * + * Created on January 3, 2006, 6:50 PM + * + * From "Multiprocessor Synchronization and Concurrent Data Structures", + * by Maurice Herlihy and Nir Shavit. + * Copyright 2006 Elsevier Inc. All rights reserved. + */ +package lists; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +import interfaces.GenericListInterface; + +/** + * Fine-grained synchronization: lock coupling (hand-over-hand locking). + * + * @param T Item type. + * @author Maurice Herlihy + */ +public class FineList implements GenericListInterface { + /** + * First list entry + */ + private Node head; + private int count; + + /** + * Constructor + */ + public FineList() { + // Add sentinels to start and end + head = new Node(Integer.MIN_VALUE); + head.next = new Node(Integer.MAX_VALUE); + } + + /** + * Add an element. + * + * @param item element to add + * @return true iff element was not there already + */ + @Override + public boolean add(T item) { + int key = item.hashCode(); + head.lock(); + Node pred = head; + try { + Node curr = pred.next; + curr.lock(); + try { + while (curr.key < key) { + pred.unlock(); + pred = curr; + curr = curr.next; + curr.lock(); + } + if (curr.key == key) { + return false; + } + Node newNode = new Node(item); + newNode.next = curr; + pred.next = newNode; + ++this.count; + return true; + } finally { + curr.unlock(); + } + } finally { + pred.unlock(); + } + } + + /** + * Remove an element. + * + * @param item element to remove + * @return true iff element was present + */ + @Override + public boolean remove(T item) { + Node pred = null, curr = null; + int key = item.hashCode(); + head.lock(); + try { + pred = head; + curr = pred.next; + curr.lock(); + try { + while (curr.key < key) { + pred.unlock(); + pred = curr; + curr = curr.next; + curr.lock(); + } + if (curr.key == key) { + pred.next = curr.next; + --this.count; + return true; + } + return false; + } finally { + curr.unlock(); + } + } finally { + pred.unlock(); + } + } + + @Override + public boolean contains(T item) { + Node last = null, pred = null, curr = null; + int key = item.hashCode(); + head.lock(); + try { + pred = head; + curr = pred.next; + curr.lock(); + try { + while (curr.key < key) { + pred.unlock(); + pred = curr; + curr = curr.next; + curr.lock(); + } + return (curr.key == key); + } finally { + curr.unlock(); + } + } finally { + pred.unlock(); + } + } + + @Override + public int size() { + return this.count; + } + + /** + * list Node + */ + private class Node { + /** + * actual item + */ + T item; + /** + * item's hash code + */ + int key; + /** + * next Node in list + */ + Node next; + /** + * synchronizes individual Node + */ + Lock lock; + + /** + * Constructor for usual Node + * + * @param item element in list + */ + Node(T item) { + this.item = item; + this.key = item.hashCode(); + this.lock = new ReentrantLock(); + } + + /** + * Constructor for sentinel Node + * + * @param key should be min or max int value + */ + Node(int key) { + this.item = null; + this.key = key; + this.lock = new ReentrantLock(); + } + + /** + * Lock Node + */ + void lock() { + lock.lock(); + } + + /** + * Unlock Node + */ + void unlock() { + lock.unlock(); + } + } +} diff --git a/src/lists/GenericOperator.java b/src/lists/GenericOperator.java new file mode 100644 index 0000000..0f281ea --- /dev/null +++ b/src/lists/GenericOperator.java @@ -0,0 +1,58 @@ +package lists; + +import java.util.concurrent.ThreadLocalRandom; + +import enums.ListOperationType; + +public abstract class GenericOperator extends Thread { + + protected abstract boolean operateAdd(); + + protected abstract boolean operateRemove(); + + protected abstract boolean operateContains(); + + public volatile static boolean warmingUp = true; + private int[] operationsCount; + + public GenericOperator() { + this.operationsCount = new int[ListOperationType.values().length]; + } + + @Override + public void run() { + while (!this.isInterrupted()) { + ListOperationType operation = this.getRandomOperation(); + this.operate(operation); + } + } + + public void operate(ListOperationType operation) { + switch (operation) { + case add: + this.operateAdd(); + break; + case remove: + this.operateRemove(); + break; + case contains: + this.operateContains(); + break; + case listSize: + return; + } + if (!GenericOperator.warmingUp) { + operationsCount[operation.ordinal()] += 1; + } + } + + protected ListOperationType getRandomOperation() { + // Generate random according to a distribuition frequency. + int index = ThreadLocalRandom.current().nextInt(0, 2); + return ListOperationType.values()[index]; + } + + public int[] getOperationsCount() { + return operationsCount; + } +} \ No newline at end of file diff --git a/src/lists/IntegerListOperator.java b/src/lists/IntegerListOperator.java new file mode 100644 index 0000000..e5989bc --- /dev/null +++ b/src/lists/IntegerListOperator.java @@ -0,0 +1,28 @@ +package lists; + +import interfaces.GenericListInterface; +import utils.RandomNumbers; + +public class IntegerListOperator extends GenericOperator { + + private final GenericListInterface list; + + public IntegerListOperator(GenericListInterface list) { + this.list = list; + } + + @Override + public boolean operateAdd() { + return this.list.add(RandomNumbers.getRandomInt()); + } + + @Override + public boolean operateRemove() { + return this.list.remove(RandomNumbers.getRandomInt()); + } + + @Override + public boolean operateContains() { + return this.list.contains(RandomNumbers.getRandomInt()); + } +} \ No newline at end of file diff --git a/src/lists/LazyList.java b/src/lists/LazyList.java new file mode 100644 index 0000000..075878c --- /dev/null +++ b/src/lists/LazyList.java @@ -0,0 +1,178 @@ +/* + * LazyList.java + * + * Created on January 4, 2006, 1:41 PM + * + * From "Multiprocessor Synchronization and Concurrent Data Structures", + * by Maurice Herlihy and Nir Shavit. + * Copyright 2006 Elsevier Inc. All rights reserved. + */ + +package lists; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +/** + * Lazy list implementation: lock-free contains method. + * @param T Item type. + * @author Maurice Herlihy + */ +public class LazyList { + /** + * First list Node + */ + private Node head; + /** + * Constructor + */ + public LazyList() { + // Add sentinels to start and end + this.head = new Node(Integer.MIN_VALUE); + this.head.next = new Node(Integer.MAX_VALUE); + } + + /** + * Check that prev and curr are still in list and adjacent + */ + private boolean validate(Node pred, Node curr) { + return !pred.marked && !curr.marked && pred.next == curr; + } + /** + * Add an element. + * @param item element to add + * @return true iff element was not there already + */ + public boolean add(T item) { + int key = item.hashCode(); + while (true) { + Node pred = this.head; + Node curr = head.next; + while (curr.key < key) { + pred = curr; curr = curr.next; + } + pred.lock(); + try { + curr.lock(); + try { + if (validate(pred, curr)) { + if (curr.key == key) { // present + return false; + } else { // not present + Node Node = new Node(item); + Node.next = curr; + pred.next = Node; + return true; + } + } + } finally { // always unlock + curr.unlock(); + } + } finally { // always unlock + pred.unlock(); + } + } + } + /** + * Remove an element. + * @param item element to remove + * @return true iff element was present + */ + public boolean remove(T item) { + int key = item.hashCode(); + while (true) { + Node pred = this.head; + Node curr = head.next; + while (curr.key < key) { + pred = curr; curr = curr.next; + } + pred.lock(); + try { + curr.lock(); + try { + if (validate(pred, curr)) { + if (curr.key != key) { // present + return false; + } else { // absent + curr.marked = true; // logically remove + pred.next = curr.next; // physically remove + return true; + } + } + } finally { // always unlock curr + curr.unlock(); + } + } finally { // always unlock pred + pred.unlock(); + } + } + } + /** + * Test whether element is present + * @param item element to test + * @return true iff element is present + */ + public boolean contains(T item) { + int key = item.hashCode(); + Node curr = this.head; + while (curr.key < key) + curr = curr.next; + return curr.key == key && !curr.marked; + } + /** + * list Node + */ + private class Node { + /** + * actual item + */ + T item; + /** + * item's hash code + */ + int key; + /** + * next Node in list + */ + Node next; + /** + * If true, Node is logically deleted. + */ + boolean marked; + /** + * Synchronizes Node. + */ + Lock lock; + /** + * Constructor for usual Node + * @param item element in list + */ + Node(T item) { // usual constructor + this.item = item; + this.key = item.hashCode(); + this.next = null; + this.marked = false; + this.lock = new ReentrantLock(); + } + /** + * Constructor for sentinel Node + * @param key should be min or max int value + */ + Node(int key) { // sentinel constructor + this.item = null; + this.key = key; + this.next = null; + this.marked = false; + this.lock = new ReentrantLock(); + } + /** + * Lock Node + */ + void lock() {lock.lock();} + /** + * Unlock Node + */ + void unlock() {lock.unlock();} + } +} + diff --git a/src/lists/LockFreeList.java b/src/lists/LockFreeList.java new file mode 100644 index 0000000..88bdc83 --- /dev/null +++ b/src/lists/LockFreeList.java @@ -0,0 +1,182 @@ +/* + * LockFreeList.java + * + * Created on January 4, 2006, 2:41 PM + * + * From "Multiprocessor Synchronization and Concurrent Data Structures", + * by Maurice Herlihy and Nir Shavit. + * Copyright 2006 Elsevier Inc. All rights reserved. + */ + +package lists; + +import java.util.concurrent.atomic.AtomicMarkableReference; + +/** + * Lock-free List based on M. Michael's algorithm. + * @param T Item type. + * @author Maurice Herlihy + */ +public class LockFreeList { + /** + * First list node + */ + Node head; + /** + * Constructor + */ + public LockFreeList() { + this.head = new Node(Integer.MIN_VALUE); + Node tail = new Node(Integer.MAX_VALUE); + while (!head.next.compareAndSet(null, tail, false, false)); + } + /** + * Add an element. + * @param item element to add + * @return true iff element was not there already + */ + public boolean add(T item) { + int key = item.hashCode(); + boolean splice; + while (true) { + // find predecessor and curren entries + Window window = find(head, key); + Node pred = window.pred, curr = window.curr; + // is the key present? + if (curr.key == key) { + return false; + } else { + // splice in new node + Node node = new Node(item); + node.next = new AtomicMarkableReference(curr, false); + if (pred.next.compareAndSet(curr, node, false, false)) { + return true; + } + } + } + } + /** + * Remove an element. + * @param item element to remove + * @return true iff element was present + */ + public boolean remove(T item) { + int key = item.hashCode(); + boolean snip; + while (true) { + // find predecessor and curren entries + Window window = find(head, key); + Node pred = window.pred, curr = window.curr; + // is the key present? + if (curr.key != key) { + return false; + } else { + // snip out matching node + Node succ = curr.next.getReference(); + snip = curr.next.attemptMark(succ, true); + if (!snip) + continue; + pred.next.compareAndSet(curr, succ, false, false); + return true; + } + } + } + /** + * Test whether element is present + * @param item element to test + * @return true iff element is present + */ + public boolean contains(T item) { + int key = item.hashCode(); + // find predecessor and curren entries + Window window = find(head, key); + Node pred = window.pred, curr = window.curr; + return (curr.key == key); + } + /** + * list node + */ + private class Node { + /** + * actual item + */ + T item; + /** + * item's hash code + */ + int key; + /** + * next node in list + */ + AtomicMarkableReference next; + /** + * Constructor for usual node + * @param item element in list + */ + Node(T item) { // usual constructor + this.item = item; + this.key = item.hashCode(); + this.next = new AtomicMarkableReference(null, false); + } + /** + * Constructor for sentinel node + * @param key should be min or max int value + */ + Node(int key) { // sentinel constructor + this.item = null; + this.key = key; + this.next = new AtomicMarkableReference(null, false); + } + } + + /** + * Pair of adjacent list entries. + */ + class Window { + /** + * Earlier node. + */ + public Node pred; + /** + * Later node. + */ + public Node curr; + /** + * Constructor. + */ + Window(Node pred, Node curr) { + this.pred = pred; this.curr = curr; + } + } + + /** + * If element is present, returns node and predecessor. If absent, returns + * node with least larger key. + * @param head start of list + * @param key key to search for + * @return If element is present, returns node and predecessor. If absent, returns + * node with least larger key. + */ + public Window find(Node head, int key) { + Node pred = null, curr = null, succ = null; + boolean[] marked = {false}; // is curr marked? + boolean snip; + retry: while (true) { + pred = head; + curr = pred.next.getReference(); + while (true) { + succ = curr.next.get(marked); + while (marked[0]) { // replace curr if marked + snip = pred.next.compareAndSet(curr, succ, false, false); + if (!snip) continue retry; + curr = pred.next.getReference(); + succ = curr.next.get(marked); + } + if (curr.key >= key) + return new Window(pred, curr); + pred = curr; + curr = succ; + } + } + } +} diff --git a/src/lists/OptimisticList.java b/src/lists/OptimisticList.java new file mode 100644 index 0000000..b898e1d --- /dev/null +++ b/src/lists/OptimisticList.java @@ -0,0 +1,173 @@ +/* + * OptimisticList.java + * + * Created on January 4, 2006, 1:49 PM + * + * From "Multiprocessor Synchronization and Concurrent Data Structures", + * by Maurice Herlihy and Nir Shavit. + * Copyright 2006 Elsevier Inc. All rights reserved. + */ +package lists; + +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +/** + * Optimistic List implementation. + * @param T Item type. + * @author Maurice Herlihy + */ +public class OptimisticList { + /** + * First list entry + */ + private Entry head; + /** + * Constructor + */ + public OptimisticList() { + this.head = new Entry(Integer.MIN_VALUE); + this.head.next = new Entry(Integer.MAX_VALUE); + } + /** + * Add an element. + * @param item element to add + * @return true iff element was not there already + */ + public boolean add(T item) { + int key = item.hashCode(); + while (true) { + Entry pred = this.head; + Entry curr = pred.next; + while (curr.key <= key) { + pred = curr; curr = curr.next; + } + pred.lock(); curr.lock(); + try { + if (validate(pred, curr)) { + if (curr.key == key) { // present + return false; + } else { // not present + Entry entry = new Entry(item); + entry.next = curr; + pred.next = entry; + return true; + } + } + } finally { // always unlock + pred.unlock(); curr.unlock(); + } + } + } + /** + * Remove an element. + * @param item element to remove + * @return true iff element was present + */ + public boolean remove(T item) { + int key = item.hashCode(); + while (true) { + Entry pred = this.head; + Entry curr = pred.next; + while (curr.key < key) { + pred = curr; curr = curr.next; + } + pred.lock(); curr.lock(); + try { + if (validate(pred, curr)) { + if (curr.key == key) { // present in list + pred.next = curr.next; + return true; + } else { // not present in list + return false; + } + } + } finally { // always unlock + pred.unlock(); curr.unlock(); + } + } + } + /** + * Test whether element is present + * @param item element to test + * @return true iff element is present + */ + public boolean contains(T item) { + int key = item.hashCode(); + while (true) { + Entry pred = this.head; // sentinel node; + Entry curr = pred.next; + while (curr.key < key) { + pred = curr; curr = curr.next; + } + try { + pred.lock(); curr.lock(); + if (validate(pred, curr)) { + return (curr.key == key); + } + } finally { // always unlock + pred.unlock(); curr.unlock(); + } + } + } + /** + * Check that prev and curr are still in list and adjacent + * @param pred predecessor node + * @param curr current node + * @return whther predecessor and current have changed + */ + private boolean validate(Entry pred, Entry curr) { + Entry entry = head; + while (entry.key <= pred.key) { + if (entry == pred) + return pred.next == curr; + entry = entry.next; + } + return false; + } + /** + * list entry + */ + private class Entry { + /** + * actual item + */ + T item; + /** + * item's hash code + */ + int key; + /** + * next entry in list + */ + Entry next; + /** + * Synchronizes entry. + */ + Lock lock; + /** + * Constructor for usual entry + * @param item element in list + */ + Entry(T item) { + this.item = item; + this.key = item.hashCode(); + lock = new ReentrantLock(); + } + /** + * Constructor for sentinel entry + * @param key should be min or max int value + */ + Entry(int key) { + this.key = key; + lock = new ReentrantLock(); + } + /** + * Lock entry + */ + void lock() {lock.lock();} + /** + * Unlock entry + */ + void unlock() {lock.unlock();} + } +} diff --git a/src/main/Consumer.java b/src/main/Consumer.java deleted file mode 100644 index e47eb0c..0000000 --- a/src/main/Consumer.java +++ /dev/null @@ -1,20 +0,0 @@ -package main; - -import enums.ProducerConsumerType; - -public class Consumer extends ProducerConsumer { - - public Consumer(Monitor monitor) { - super(monitor); - } - - @Override - public void operate() throws InterruptedException { - this.monitor.deq(); - } - - @Override - public ProducerConsumerType getType() { - return ProducerConsumerType.consumer; - } -} \ No newline at end of file diff --git a/src/main/Monitor.java b/src/main/Monitor.java deleted file mode 100644 index 9f0dfae..0000000 --- a/src/main/Monitor.java +++ /dev/null @@ -1,77 +0,0 @@ -package main; - -import java.util.concurrent.locks.Condition; -import java.util.concurrent.locks.Lock; -import java.util.concurrent.locks.ReentrantLock; - -/* - This monitor implementation follows the book The Art of Multiprocessor Programming, Figure 8.5 (section 8.2.2, chapter 8), and section A.2.2 (Apendix A). -*/ -public class Monitor { - // Only one process can enqueue/dequeue at a time. - private final Lock lock = new ReentrantLock(); - // Wait while the queue is full. - private final Condition notFull = lock.newCondition(); - // Wait while the queue is empty. - private final Condition notEmpty = lock.newCondition(); - private final T[] items; - private int tail, head, count = 0; - - @SuppressWarnings("unchecked") - public Monitor(int maxCapacity) { - items = (T[]) new Object[maxCapacity]; - } - - public int getCurrentSize() { - return count; - } - - public void enq(T x) throws InterruptedException { - lock.lock(); - try { - // Wait while the queue is full. - while (count == items.length) { - notFull.await(); - } - // If the queue is not full, put the item in the tail position. - items[tail] = x; - /* - * It is a circular list. If tail is at the end on the list, it will need to go - * to the first position in the list. - */ - if (++tail == items.length) { - tail = 0; - } - ++count; - // Notifies that the queue is not empty. - notEmpty.signal(); - } finally { - lock.unlock(); - } - } - - public T deq() throws InterruptedException { - lock.lock(); - try { - // Wait while the queue is empty. - while (count == 0) { - notEmpty.await(); - } - // If the list is not empty, get the item in the head position. - T x = items[head]; - /* - * It is a circular list. If head is at the end on the list, it will need to go - * to the first position in the list. - */ - if (++head == items.length) { - head = 0; - } - --count; - // Notifies that the queue is not full. - notFull.signal(); - return x; - } finally { - lock.unlock(); - } - } -} \ No newline at end of file diff --git a/src/main/MonitorSynchronized.java b/src/main/MonitorSynchronized.java deleted file mode 100644 index 46f7341..0000000 --- a/src/main/MonitorSynchronized.java +++ /dev/null @@ -1,57 +0,0 @@ -package main; - -/* - This monitor implementation follows the book The Art of Multiprocessor Programming, Figure 8.5 (section 8.2.2, chapter 8), and section A.2.2 (Apendix A). -*/ -public class MonitorSynchronized { - private final T[] items; - private int tail, head, count = 0; - - @SuppressWarnings("unchecked") - public MonitorSynchronized(int maxCapacity) { - items = (T[]) new Object[maxCapacity]; - } - - public int getCurrentSize() { - return count; - } - - public synchronized void enq(T x) throws InterruptedException { - // Wait while the queue is full. - while (count == items.length) { - wait(); - } - // If the queue is not full, put the item in the tail position. - items[tail] = x; - /* - * It is a circular list. If tail is at the end on the list, it will need to go - * to the first position in the list. - */ - if (++tail == items.length) { - tail = 0; - } - ++count; - // Notifies that the queue is not empty. - notifyAll(); - } - - public synchronized T deq() throws InterruptedException { - // Wait while the queue is empty. - while (count == 0) { - wait(); - } - // If the list is not empty, get the item in the head position. - T x = items[head]; - /* - * It is a circular list. If head is at the end on the list, it will need to go - * to the first position in the list. - */ - if (++head == items.length) { - head = 0; - } - --count; - // Notifies that the queue is not full. - notifyAll(); - return x; - } -} \ No newline at end of file diff --git a/src/main/Producer.java b/src/main/Producer.java deleted file mode 100644 index a3c5ba6..0000000 --- a/src/main/Producer.java +++ /dev/null @@ -1,20 +0,0 @@ -package main; - -import enums.ProducerConsumerType; - -public class Producer extends ProducerConsumer { - - public Producer(Monitor monitor) { - super(monitor); - } - - @Override - public void operate() throws InterruptedException { - this.monitor.enq(Math.random()); - } - - @Override - public ProducerConsumerType getType() { - return ProducerConsumerType.producer; - } -} \ No newline at end of file diff --git a/src/main/ProducerConsumer.java b/src/main/ProducerConsumer.java deleted file mode 100644 index e59b25b..0000000 --- a/src/main/ProducerConsumer.java +++ /dev/null @@ -1,40 +0,0 @@ -package main; - -import enums.ProducerConsumerType; - -public abstract class ProducerConsumer extends Thread { - - public abstract void operate() throws InterruptedException; - - public abstract ProducerConsumerType getType(); - - public volatile static boolean countingOperations = true; - protected final Monitor monitor; - private int operationsCount = 0; - - public ProducerConsumer(Monitor monitor) { - this.monitor = monitor; - } - - @Override - public void run() { - while (!this.isInterrupted()) { - try { - this.operate(); - if (ProducerConsumer.countingOperations) { - ++operationsCount; - } - } catch (InterruptedException e) { - break; - } - } - } - - public void startThread() { - this.start(); - } - - public int getOperationsCount() { - return operationsCount; - } -} \ No newline at end of file diff --git a/src/main/Test.java b/src/main/Test.java new file mode 100644 index 0000000..a923652 --- /dev/null +++ b/src/main/Test.java @@ -0,0 +1,94 @@ +package main; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import enums.ListOperationType; +import interfaces.GenericListInterface; +import lists.CoarseList; +import lists.IntegerListOperator; +import utils.RandomNumbers; + +public class Test { + + private static List getAllThreads(int numberThreads, GenericListInterface list) { + List threads = new ArrayList<>(); + for (int i = 0; i < numberThreads; i++) { + threads.add(new IntegerListOperator(list)); + } + return threads; + } + + private static int[] getOperationsCountSum(List threads) { + int[] count = new int[ListOperationType.values().length]; + for (IntegerListOperator thread : threads) { + for (int i = 0; i < count.length; i++) { + count[i] += thread.getOperationsCount()[i]; + } + } + return count; + } + + public static void main(String[] args) { + int listInitialSize = 10000;// Integer.parseInt(args[0]); + int listMaximumSize = 300;// Integer.parseInt(args[1]); + int numberThreads = 12;// Integer.parseInt(args[2]); + + System.out.println(); + System.out.println(String.format("Initial list size: %s", listInitialSize)); + System.out.println(String.format("Maximum list size: %s", listMaximumSize)); + System.out.println(String.format("Number of threads: %s", numberThreads)); + System.out.println(); + System.out.println("Starting test..."); + + // It is necessary to limit the size of the list. + GenericListInterface list = new CoarseList(); + for (int i = 0; i < listInitialSize; i++) { + list.add(RandomNumbers.getRandomInt()); + } + + System.out.println("Starting producers and consumers..."); + List threads = getAllThreads(numberThreads, list); + for (IntegerListOperator thread : threads) { + thread.start(); + } + + // Use a period of warm-up. During this period, operations are not counted. + System.out.println("Warming-up..."); + try { + TimeUnit.SECONDS.sleep(1); + } catch (InterruptedException e) { + } + IntegerListOperator.warmingUp = false; + + try { + System.out.println("Producing and consuming..."); + TimeUnit.SECONDS.sleep(5); + } catch (InterruptedException e) { + } + + System.out.println("Interrupting threads..."); + System.out.println(); + for (IntegerListOperator thread : threads) { + try { + thread.interrupt(); + thread.join(); + } catch (InterruptedException e) { + } + } + + int currentMonitorSize = list.size(); + int[] operationsCount = getOperationsCountSum(threads); + + System.out.println(String.format("Current monitor size: %s", currentMonitorSize)); + System.out.println(String.format("Number of adds: %s", operationsCount[ListOperationType.add.ordinal()])); + System.out.println(String.format("Number of removes: %s", operationsCount[ListOperationType.remove.ordinal()])); + System.out.println( + String.format("Number of contains: %s", operationsCount[ListOperationType.contains.ordinal()])); + System.out + .println(String.format("Number of counts: %s", operationsCount[ListOperationType.listSize.ordinal()])); + + System.out.println("Finished."); + } +} \ No newline at end of file diff --git a/src/main/TestGuided.java b/src/main/TestGuided.java new file mode 100644 index 0000000..f0eb40b --- /dev/null +++ b/src/main/TestGuided.java @@ -0,0 +1,21 @@ +package main; + +import interfaces.GenericListInterface; +import lists.CoarseList; +import lists.IntegerListOperator; + +public class TestGuided { + + public static void main(String[] args) { + IntegerListOperator.warmingUp = false; + GenericListInterface list = new CoarseList(); + list.add(Math.random()); + double a = Math.random(); + list.add(a); + list.remove(a); + + int currentMonitorSize = list.size(); + + System.out.println(String.format("Current monitor size: %s", currentMonitorSize)); + } +} diff --git a/src/utils/RandomNumbers.java b/src/utils/RandomNumbers.java new file mode 100644 index 0000000..a9efb5c --- /dev/null +++ b/src/utils/RandomNumbers.java @@ -0,0 +1,12 @@ +package utils; + +import java.util.Random; + +public final class RandomNumbers { + public static int getRandomInt() { + int max = Integer.MAX_VALUE; + Random rand = new Random(); + int randomNum = rand.nextInt(max); + return randomNum; + } +} \ No newline at end of file diff --git a/test/no-warm-up.pdf b/test/no-warm-up.pdf deleted file mode 100644 index 71933b1048716b7695aa22596308fb80e98ca54e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43179 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 diff --git a/test/output/100000-1000000-0-1-11.txt b/test/output/100000-1000000-0-1-11.txt deleted file mode 100644 index 0eff8c2..0000000 --- a/test/output/100000-1000000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 148 -Number of enqueues: 72941156 -Number of dequeues: 73041008 -Finished. diff --git a/test/output/100000-1000000-0-11-1.txt b/test/output/100000-1000000-0-11-1.txt deleted file mode 100644 index 493c3eb..0000000 --- a/test/output/100000-1000000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 181159698 -Number of dequeues: 180259698 -Finished. diff --git a/test/output/100000-1000000-0-4-8.txt b/test/output/100000-1000000-0-4-8.txt deleted file mode 100644 index 278fb2f..0000000 --- a/test/output/100000-1000000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 524 -Number of enqueues: 265699177 -Number of dequeues: 265798653 -Finished. diff --git a/test/output/100000-1000000-0-8-4.txt b/test/output/100000-1000000-0-8-4.txt deleted file mode 100644 index d78f8f7..0000000 --- a/test/output/100000-1000000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 4721 -Number of enqueues: 251492913 -Number of dequeues: 251588192 -Finished. diff --git a/test/output/100000-1000000-1-1-11.txt b/test/output/100000-1000000-1-1-11.txt deleted file mode 100644 index f54a295..0000000 --- a/test/output/100000-1000000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 138 -Number of enqueues: 81331763 -Number of dequeues: 81331649 -Finished. diff --git a/test/output/100000-1000000-1-11-1.txt b/test/output/100000-1000000-1-11-1.txt deleted file mode 100644 index 18ba559..0000000 --- a/test/output/100000-1000000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 143323457 -Number of dequeues: 143323204 -Finished. diff --git a/test/output/100000-1000000-1-4-8.txt b/test/output/100000-1000000-1-4-8.txt deleted file mode 100644 index c2526b2..0000000 --- a/test/output/100000-1000000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2550 -Number of enqueues: 341154431 -Number of dequeues: 341152022 -Finished. diff --git a/test/output/100000-1000000-1-8-4.txt b/test/output/100000-1000000-1-8-4.txt deleted file mode 100644 index ac900b0..0000000 --- a/test/output/100000-1000000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 425357393 -Number of dequeues: 425357393 -Finished. diff --git a/test/output/100000-300000-0-1-11.txt b/test/output/100000-300000-0-1-11.txt deleted file mode 100644 index 43fdd82..0000000 --- a/test/output/100000-300000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 110 -Number of enqueues: 64816594 -Number of dequeues: 64916484 -Finished. diff --git a/test/output/100000-300000-0-11-1.txt b/test/output/100000-300000-0-11-1.txt deleted file mode 100644 index 26f6b66..0000000 --- a/test/output/100000-300000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 121890104 -Number of dequeues: 121690104 -Finished. diff --git a/test/output/100000-300000-0-4-8.txt b/test/output/100000-300000-0-4-8.txt deleted file mode 100644 index 4bf1463..0000000 --- a/test/output/100000-300000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2800 -Number of enqueues: 306236045 -Number of dequeues: 306333245 -Finished. diff --git a/test/output/100000-300000-0-8-4.txt b/test/output/100000-300000-0-8-4.txt deleted file mode 100644 index 15b2950..0000000 --- a/test/output/100000-300000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 352858350 -Number of dequeues: 352658350 -Finished. diff --git a/test/output/100000-300000-1-1-11.txt b/test/output/100000-300000-1-1-11.txt deleted file mode 100644 index ce30f5c..0000000 --- a/test/output/100000-300000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 191 -Number of enqueues: 76947340 -Number of dequeues: 76947149 -Finished. diff --git a/test/output/100000-300000-1-11-1.txt b/test/output/100000-300000-1-11-1.txt deleted file mode 100644 index 4f1ca5d..0000000 --- a/test/output/100000-300000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 151617549 -Number of dequeues: 151463388 -Finished. diff --git a/test/output/100000-300000-1-4-8.txt b/test/output/100000-300000-1-4-8.txt deleted file mode 100644 index bf31432..0000000 --- a/test/output/100000-300000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2291 -Number of enqueues: 329332600 -Number of dequeues: 329330498 -Finished. diff --git a/test/output/100000-300000-1-8-4.txt b/test/output/100000-300000-1-8-4.txt deleted file mode 100644 index 436b25d..0000000 --- a/test/output/100000-300000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 440146190 -Number of dequeues: 440145219 -Finished. diff --git a/test/output/100000-500000-0-1-11.txt b/test/output/100000-500000-0-1-11.txt deleted file mode 100644 index eaf6e1c..0000000 --- a/test/output/100000-500000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 188 -Number of enqueues: 70931942 -Number of dequeues: 71031754 -Finished. diff --git a/test/output/100000-500000-0-11-1.txt b/test/output/100000-500000-0-11-1.txt deleted file mode 100644 index d13cad1..0000000 --- a/test/output/100000-500000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 110077668 -Number of dequeues: 109677668 -Finished. diff --git a/test/output/100000-500000-0-4-8.txt b/test/output/100000-500000-0-4-8.txt deleted file mode 100644 index 2aa0a2d..0000000 --- a/test/output/100000-500000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1075 -Number of enqueues: 270526490 -Number of dequeues: 270625415 -Finished. diff --git a/test/output/100000-500000-0-8-4.txt b/test/output/100000-500000-0-8-4.txt deleted file mode 100644 index 26f1c6c..0000000 --- a/test/output/100000-500000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 494950 -Number of enqueues: 407199696 -Number of dequeues: 406804746 -Finished. diff --git a/test/output/100000-500000-1-1-11.txt b/test/output/100000-500000-1-1-11.txt deleted file mode 100644 index 48c2384..0000000 --- a/test/output/100000-500000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 147 -Number of enqueues: 76653780 -Number of dequeues: 76653633 -Finished. diff --git a/test/output/100000-500000-1-11-1.txt b/test/output/100000-500000-1-11-1.txt deleted file mode 100644 index 001a10a..0000000 --- a/test/output/100000-500000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 153373529 -Number of dequeues: 153373529 -Finished. diff --git a/test/output/100000-500000-1-4-8.txt b/test/output/100000-500000-1-4-8.txt deleted file mode 100644 index 28afd70..0000000 --- a/test/output/100000-500000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1881 -Number of enqueues: 298009337 -Number of dequeues: 298007850 -Finished. diff --git a/test/output/100000-500000-1-8-4.txt b/test/output/100000-500000-1-8-4.txt deleted file mode 100644 index feba52c..0000000 --- a/test/output/100000-500000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 100000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 408916 -Number of enqueues: 417188563 -Number of dequeues: 417213375 -Finished. diff --git a/test/output/200000-1000000-0-1-11.txt b/test/output/200000-1000000-0-1-11.txt deleted file mode 100644 index bbfc2c5..0000000 --- a/test/output/200000-1000000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 135 -Number of enqueues: 82466878 -Number of dequeues: 82666743 -Finished. diff --git a/test/output/200000-1000000-0-11-1.txt b/test/output/200000-1000000-0-11-1.txt deleted file mode 100644 index c0d0caa..0000000 --- a/test/output/200000-1000000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 135033414 -Number of dequeues: 134233414 -Finished. diff --git a/test/output/200000-1000000-0-4-8.txt b/test/output/200000-1000000-0-4-8.txt deleted file mode 100644 index fb83f52..0000000 --- a/test/output/200000-1000000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 3034 -Number of enqueues: 301689364 -Number of dequeues: 301886330 -Finished. diff --git a/test/output/200000-1000000-0-8-4.txt b/test/output/200000-1000000-0-8-4.txt deleted file mode 100644 index d5ee5db..0000000 --- a/test/output/200000-1000000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 757190 -Number of enqueues: 439862696 -Number of dequeues: 439305506 -Finished. diff --git a/test/output/200000-1000000-1-1-11.txt b/test/output/200000-1000000-1-1-11.txt deleted file mode 100644 index 1b88987..0000000 --- a/test/output/200000-1000000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 172 -Number of enqueues: 90308121 -Number of dequeues: 90307949 -Finished. diff --git a/test/output/200000-1000000-1-11-1.txt b/test/output/200000-1000000-1-11-1.txt deleted file mode 100644 index bd5d648..0000000 --- a/test/output/200000-1000000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 154007797 -Number of dequeues: 154007797 -Finished. diff --git a/test/output/200000-1000000-1-4-8.txt b/test/output/200000-1000000-1-4-8.txt deleted file mode 100644 index 9f83212..0000000 --- a/test/output/200000-1000000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1332 -Number of enqueues: 275991096 -Number of dequeues: 275990191 -Finished. diff --git a/test/output/200000-1000000-1-8-4.txt b/test/output/200000-1000000-1-8-4.txt deleted file mode 100644 index 538fdc0..0000000 --- a/test/output/200000-1000000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 15369 -Number of enqueues: 437818907 -Number of dequeues: 438440197 -Finished. diff --git a/test/output/200000-300000-0-1-11.txt b/test/output/200000-300000-0-1-11.txt deleted file mode 100644 index ffb1ca4..0000000 --- a/test/output/200000-300000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 147 -Number of enqueues: 70179384 -Number of dequeues: 70379237 -Finished. diff --git a/test/output/200000-300000-0-11-1.txt b/test/output/200000-300000-0-11-1.txt deleted file mode 100644 index 3c781e9..0000000 --- a/test/output/200000-300000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 168095942 -Number of dequeues: 167995942 -Finished. diff --git a/test/output/200000-300000-0-4-8.txt b/test/output/200000-300000-0-4-8.txt deleted file mode 100644 index 3eb3a60..0000000 --- a/test/output/200000-300000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 3156 -Number of enqueues: 340421480 -Number of dequeues: 340618324 -Finished. diff --git a/test/output/200000-300000-0-8-4.txt b/test/output/200000-300000-0-8-4.txt deleted file mode 100644 index b7424cb..0000000 --- a/test/output/200000-300000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 404208720 -Number of dequeues: 404108720 -Finished. diff --git a/test/output/200000-300000-1-1-11.txt b/test/output/200000-300000-1-1-11.txt deleted file mode 100644 index 3a096a4..0000000 --- a/test/output/200000-300000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 102 -Number of enqueues: 74589093 -Number of dequeues: 74588991 -Finished. diff --git a/test/output/200000-300000-1-11-1.txt b/test/output/200000-300000-1-11-1.txt deleted file mode 100644 index b62506b..0000000 --- a/test/output/200000-300000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 164297660 -Number of dequeues: 164297082 -Finished. diff --git a/test/output/200000-300000-1-4-8.txt b/test/output/200000-300000-1-4-8.txt deleted file mode 100644 index ba86053..0000000 --- a/test/output/200000-300000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2395 -Number of enqueues: 331151194 -Number of dequeues: 331148840 -Finished. diff --git a/test/output/200000-300000-1-8-4.txt b/test/output/200000-300000-1-8-4.txt deleted file mode 100644 index 587e19e..0000000 --- a/test/output/200000-300000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 293416 -Number of enqueues: 498774854 -Number of dequeues: 498781196 -Finished. diff --git a/test/output/200000-500000-0-1-11.txt b/test/output/200000-500000-0-1-11.txt deleted file mode 100644 index bdc5556..0000000 --- a/test/output/200000-500000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 60 -Number of enqueues: 78532509 -Number of dequeues: 78732449 -Finished. diff --git a/test/output/200000-500000-0-11-1.txt b/test/output/200000-500000-0-11-1.txt deleted file mode 100644 index 4269d1d..0000000 --- a/test/output/200000-500000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 136868390 -Number of dequeues: 136568390 -Finished. diff --git a/test/output/200000-500000-0-4-8.txt b/test/output/200000-500000-0-4-8.txt deleted file mode 100644 index 6273a26..0000000 --- a/test/output/200000-500000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2147 -Number of enqueues: 279794570 -Number of dequeues: 279992423 -Finished. diff --git a/test/output/200000-500000-0-8-4.txt b/test/output/200000-500000-0-8-4.txt deleted file mode 100644 index d68b6f1..0000000 --- a/test/output/200000-500000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 396758052 -Number of dequeues: 396458052 -Finished. diff --git a/test/output/200000-500000-1-1-11.txt b/test/output/200000-500000-1-1-11.txt deleted file mode 100644 index 8a19b8e..0000000 --- a/test/output/200000-500000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 72 -Number of enqueues: 76081425 -Number of dequeues: 76081353 -Finished. diff --git a/test/output/200000-500000-1-11-1.txt b/test/output/200000-500000-1-11-1.txt deleted file mode 100644 index be348d1..0000000 --- a/test/output/200000-500000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 169051512 -Number of dequeues: 169051512 -Finished. diff --git a/test/output/200000-500000-1-4-8.txt b/test/output/200000-500000-1-4-8.txt deleted file mode 100644 index 01f6f31..0000000 --- a/test/output/200000-500000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 3661 -Number of enqueues: 329321679 -Number of dequeues: 329318052 -Finished. diff --git a/test/output/200000-500000-1-8-4.txt b/test/output/200000-500000-1-8-4.txt deleted file mode 100644 index f2d9505..0000000 --- a/test/output/200000-500000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 200000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 31080 -Number of enqueues: 466082624 -Number of dequeues: 466051544 -Finished. diff --git a/test/output/300000-1000000-0-1-11.txt b/test/output/300000-1000000-0-1-11.txt deleted file mode 100644 index aeecf4c..0000000 --- a/test/output/300000-1000000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 119 -Number of enqueues: 68198713 -Number of dequeues: 68498594 -Finished. diff --git a/test/output/300000-1000000-0-11-1.txt b/test/output/300000-1000000-0-11-1.txt deleted file mode 100644 index 1558939..0000000 --- a/test/output/300000-1000000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 164304782 -Number of dequeues: 163604782 -Finished. diff --git a/test/output/300000-1000000-0-4-8.txt b/test/output/300000-1000000-0-4-8.txt deleted file mode 100644 index 52e838f..0000000 --- a/test/output/300000-1000000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 982 -Number of enqueues: 267390758 -Number of dequeues: 267689776 -Finished. diff --git a/test/output/300000-1000000-0-8-4.txt b/test/output/300000-1000000-0-8-4.txt deleted file mode 100644 index 368f832..0000000 --- a/test/output/300000-1000000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 998862 -Number of enqueues: 395303669 -Number of dequeues: 394604807 -Finished. diff --git a/test/output/300000-1000000-1-1-11.txt b/test/output/300000-1000000-1-1-11.txt deleted file mode 100644 index 3808a6f..0000000 --- a/test/output/300000-1000000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 240 -Number of enqueues: 81364006 -Number of dequeues: 81364012 -Finished. diff --git a/test/output/300000-1000000-1-11-1.txt b/test/output/300000-1000000-1-11-1.txt deleted file mode 100644 index 4608e44..0000000 --- a/test/output/300000-1000000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1000000 -Number of enqueues: 195998471 -Number of dequeues: 195993548 -Finished. diff --git a/test/output/300000-1000000-1-4-8.txt b/test/output/300000-1000000-1-4-8.txt deleted file mode 100644 index f8d33c9..0000000 --- a/test/output/300000-1000000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 1160 -Number of enqueues: 289882115 -Number of dequeues: 289880955 -Finished. diff --git a/test/output/300000-1000000-1-8-4.txt b/test/output/300000-1000000-1-8-4.txt deleted file mode 100644 index dc9db60..0000000 --- a/test/output/300000-1000000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 1000000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 115706 -Number of enqueues: 460563031 -Number of dequeues: 461437179 -Finished. diff --git a/test/output/300000-300000-0-1-11.txt b/test/output/300000-300000-0-1-11.txt deleted file mode 100644 index 194b50a..0000000 --- a/test/output/300000-300000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 84 -Number of enqueues: 75037704 -Number of dequeues: 75337620 -Finished. diff --git a/test/output/300000-300000-0-11-1.txt b/test/output/300000-300000-0-11-1.txt deleted file mode 100644 index 8911511..0000000 --- a/test/output/300000-300000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 155069063 -Number of dequeues: 155069063 -Finished. diff --git a/test/output/300000-300000-0-4-8.txt b/test/output/300000-300000-0-4-8.txt deleted file mode 100644 index 3e1ca3e..0000000 --- a/test/output/300000-300000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 3149 -Number of enqueues: 292287060 -Number of dequeues: 292583911 -Finished. diff --git a/test/output/300000-300000-0-8-4.txt b/test/output/300000-300000-0-8-4.txt deleted file mode 100644 index 80cb8f3..0000000 --- a/test/output/300000-300000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 300000 -Number of enqueues: 461306944 -Number of dequeues: 461306944 -Finished. diff --git a/test/output/300000-300000-1-1-11.txt b/test/output/300000-300000-1-1-11.txt deleted file mode 100644 index 25f13f1..0000000 --- a/test/output/300000-300000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 93 -Number of enqueues: 72542949 -Number of dequeues: 72542856 -Finished. diff --git a/test/output/300000-300000-1-11-1.txt b/test/output/300000-300000-1-11-1.txt deleted file mode 100644 index 1f694b7..0000000 --- a/test/output/300000-300000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 298481 -Number of enqueues: 180593799 -Number of dequeues: 180595318 -Finished. diff --git a/test/output/300000-300000-1-4-8.txt b/test/output/300000-300000-1-4-8.txt deleted file mode 100644 index 00a0f62..0000000 --- a/test/output/300000-300000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 2739 -Number of enqueues: 347239706 -Number of dequeues: 347236967 -Finished. diff --git a/test/output/300000-300000-1-8-4.txt b/test/output/300000-300000-1-8-4.txt deleted file mode 100644 index 0f87417..0000000 --- a/test/output/300000-300000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 300000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 280749 -Number of enqueues: 469839568 -Number of dequeues: 469837617 -Finished. diff --git a/test/output/300000-500000-0-1-11.txt b/test/output/300000-500000-0-1-11.txt deleted file mode 100644 index 117d2a9..0000000 --- a/test/output/300000-500000-0-1-11.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 33 -Number of enqueues: 56419284 -Number of dequeues: 56719251 -Finished. diff --git a/test/output/300000-500000-0-11-1.txt b/test/output/300000-500000-0-11-1.txt deleted file mode 100644 index 20df7ea..0000000 --- a/test/output/300000-500000-0-11-1.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 137925406 -Number of dequeues: 137725406 -Finished. diff --git a/test/output/300000-500000-0-4-8.txt b/test/output/300000-500000-0-4-8.txt deleted file mode 100644 index 8c48872..0000000 --- a/test/output/300000-500000-0-4-8.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 3197 -Number of enqueues: 308868356 -Number of dequeues: 309165159 -Finished. diff --git a/test/output/300000-500000-0-8-4.txt b/test/output/300000-500000-0-8-4.txt deleted file mode 100644 index 96e02a8..0000000 --- a/test/output/300000-500000-0-8-4.txt +++ /dev/null @@ -1,16 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: false -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 393870087 -Number of dequeues: 393670087 -Finished. diff --git a/test/output/300000-500000-1-1-11.txt b/test/output/300000-500000-1-1-11.txt deleted file mode 100644 index 76f80b4..0000000 --- a/test/output/300000-500000-1-1-11.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 1 -Number of consumers: 11 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 44 -Number of enqueues: 78451839 -Number of dequeues: 78451795 -Finished. diff --git a/test/output/300000-500000-1-11-1.txt b/test/output/300000-500000-1-11-1.txt deleted file mode 100644 index 6f5ca5c..0000000 --- a/test/output/300000-500000-1-11-1.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 11 -Number of consumers: 1 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 500000 -Number of enqueues: 137730695 -Number of dequeues: 137730695 -Finished. diff --git a/test/output/300000-500000-1-4-8.txt b/test/output/300000-500000-1-4-8.txt deleted file mode 100644 index a80a17f..0000000 --- a/test/output/300000-500000-1-4-8.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 4 -Number of consumers: 8 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 103741 -Number of enqueues: 317856929 -Number of dequeues: 317753196 -Finished. diff --git a/test/output/300000-500000-1-8-4.txt b/test/output/300000-500000-1-8-4.txt deleted file mode 100644 index 5bf5ec3..0000000 --- a/test/output/300000-500000-1-8-4.txt +++ /dev/null @@ -1,17 +0,0 @@ - -Initial list size: 300000 -Maximum list size: 500000 -Use warm-up: true -Number of producers: 8 -Number of consumers: 4 - -Starting test... -Starting producers and consumers... -Warming-up... -Producing and consuming... -Interrupting threads... - -Current monitor size: 499459 -Number of enqueues: 416224010 -Number of dequeues: 416224256 -Finished. diff --git a/test/run-tests.sh b/test/run-tests.sh index 3bd70d5..1f953a8 100755 --- a/test/run-tests.sh +++ b/test/run-tests.sh @@ -6,17 +6,13 @@ ant cd - mkdir output -warm_up=(0 1) initial_sizes=(100000 200000 300000) maximum_sizes=(300000 500000 1000000) -producers=(1 4 8 11) # the sum of producers and consumers must be 12 -for w in "${warm_up[@]}"; do - for i in "${initial_sizes[@]}"; do - for m in "${maximum_sizes[@]}"; do - for p in "${producers[@]}"; do - c=$((12 - p)) - java -cp ../bin Test $i $m $w $p $c > output/$i-$m-$w-$p-$c.txt - done - done +threads=(6 12) +for ((i = 0; i < 3; i++)); do + for t in "${threads[@]}"; do + initial_size=${initial_sizes[i]} + maximum_size=${maximum_sizes[i]} + java -cp ../bin main/Test $initial_size $maximum_size $t > output/$initial_size-$maximum_size-$t.txt done done \ No newline at end of file diff --git a/test/warm-up.pdf b/test/warm-up.pdf deleted file mode 100644 index 283af251f99fc49e3fb26ba0fe1d2474f6f85081..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43306 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 HHDUh;sya{3 -- GitLab