From f42ddf22907c681d8b08eeceef160d4566dba437 Mon Sep 17 00:00:00 2001
From: wangzhengquan <wangzhengquan85@126.com>
Date: 星期二, 07 七月 2020 18:05:06 +0800
Subject: [PATCH] update

---
 squeue/include/queue_factory.h          |    5 
 squeue/mm.c                             |   29 +++-
 test/test_timeout                       |    0 
 squeue/include/linked_lock_free_queue.h |    2 
 test/multiple_queue_consumer            |    0 
 test/multiple_queue_productor           |    0 
 /dev/null                               |  273 ---------------------------------------------
 test/test_queue                         |    0 
 squeue/include/array_lock_free_queue.h  |    6 
 squeue/include/lock_free_queue.h        |    7 
 test/test.h                             |    2 
 test/single_consumer                    |    0 
 squeue/logger_factory.h                 |   17 ++
 test/single_productor                   |    0 
 14 files changed, 52 insertions(+), 289 deletions(-)

diff --git a/squeue/include/array_lock_free_queue.h b/squeue/include/array_lock_free_queue.h
index 89f7f45..9a345e2 100644
--- a/squeue/include/array_lock_free_queue.h
+++ b/squeue/include/array_lock_free_queue.h
@@ -1,9 +1,9 @@
-#ifndef __LOCK_FREE_QUEUE_IMPL_MULTIPLE_PRODUCER_H__
-#define __LOCK_FREE_QUEUE_IMPL_MULTIPLE_PRODUCER_H__
+#ifndef __ARRAY_LOCK_FREE_QUEUE_IMPL_MULTIPLE_PRODUCER_H__
+#define __ARRAY_LOCK_FREE_QUEUE_IMPL_MULTIPLE_PRODUCER_H__
 
 #include <assert.h> // assert()
 #include <sched.h>  // sched_yield()
-
+#include "logger_factory.h"
 
 /// @brief implementation of an array based lock free queue with support for 
 ///        multiple producers
diff --git a/squeue/include/linked_lock_free_queue.h b/squeue/include/linked_lock_free_queue.h
index f1aaf98..c0a886a 100644
--- a/squeue/include/linked_lock_free_queue.h
+++ b/squeue/include/linked_lock_free_queue.h
@@ -98,7 +98,7 @@
 template <typename T>
 LinkedLockFreeQueue<T>::~LinkedLockFreeQueue()
 {
-    std::cerr << "LinkedLockFreeQueue destory" << std::endl;
+    LoggerFactory::getLogger().debug("LinkedLockFreeQueue destory");
     Node<T> * nodeptr;
     Pointer<T> tmp = Head.load(std::memory_order_relaxed);
     while((nodeptr = tmp.ptr) != NULL) {
diff --git a/squeue/include/lock_free_queue.h b/squeue/include/lock_free_queue.h
index 8245d8e..751db5f 100644
--- a/squeue/include/lock_free_queue.h
+++ b/squeue/include/lock_free_queue.h
@@ -1,5 +1,5 @@
-#ifndef _LOCK_FREE_QUEUE_H__
-#define _LOCK_FREE_QUEUE_H__
+#ifndef __LOCK_FREE_QUEUE_H__
+#define __LOCK_FREE_QUEUE_H__
 
 #include <stdint.h>     // uint32_t
 #include <atomic>
@@ -7,6 +7,7 @@
 #include <assert.h> // assert()
 #include "mm.h" 
 #include "sem_util.h"
+#include "logger_factory.h"
 
 // default Queue size
 #define LOCK_FREE_Q_DEFAULT_SIZE 16
@@ -150,7 +151,7 @@
     template <typename T> class Q_TYPE>
 LockFreeQueue<ELEM_T, Q_TYPE>::~LockFreeQueue()
 {
-    std::cerr << "LockFreeQueue desctroy" << std::endl;
+    LoggerFactory::getLogger().debug("LockFreeQueue desctroy");
     SemUtil::remove(slots);
     SemUtil::remove(items);
 }
diff --git a/squeue/include/queue_factory.h b/squeue/include/queue_factory.h
index ca88de6..b8857f7 100644
--- a/squeue/include/queue_factory.h
+++ b/squeue/include/queue_factory.h
@@ -32,7 +32,7 @@
 			hashtable_put(hashtable,  key, (void *)queue);
 		}
 
-		std::cout << "createQueue reference===" << queue->reference << std::endl;
+		
 		return queue;
 	}
 
@@ -43,6 +43,7 @@
 	LockFreeQueue<T>* createQueue(int key, size_t size = 16) {
 		LockFreeQueue<T> *queue = _createQueue<T>(key, size);
 		queue->reference++; 
+		LoggerFactory::getLogger().debug("createQueue reference===%d", queue->reference.load());
 		return queue;
 	}
 
@@ -56,7 +57,7 @@
 			return;
 
 		queue->reference--;
-std::cout << "dropQueue reference===" << queue->reference << std::endl;
+		LoggerFactory::getLogger().debug("dropQueue reference===%d", queue->reference.load());
 		if(queue->reference == 0) {
 			delete queue;
 			hashtable_t *hashtable = getHashTable();
diff --git a/squeue/include/squeue1.h b/squeue/include/squeue1.h
deleted file mode 100644
index 1eee5b0..0000000
--- a/squeue/include/squeue1.h
+++ /dev/null
@@ -1,273 +0,0 @@
-// queue.h -- interface for a queue
-#ifndef SQUEUE_H_
-#define SQUEUE_H_
-#include "common.h" 
-#include "mm.h" 
-#include "pcsem.h"
-
-template <typename T>
-class Node {
-public:
-    T item; 
-    Node<T> * next;
-    void *operator new(size_t size){
-        return mm_malloc(size);
-    }
-
-    void operator delete(void *p) {
-        return mm_free(p);
-    }
-};
-
-template <typename T>
-class SQueue
-{
-private:
-// class scope definitions
-    // Node is a nested structure definition local to this class
-    void *shmp;
-    int first;
-    
-    enum {Q_SIZE = 10};
-    
-    int slots;
-    int items;
-// private class members
-    Node<T> * front;       // pointer to front of Queue
-    Node<T> * rear;        // pointer to rear of Queue
-    size_t count;          // current number of size in Queue
-    const size_t qsize;    // maximum number of size in Queue
-    // preemptive definitions to prevent public copying
-    SQueue(const SQueue & q) : qsize(0) { }
-    SQueue & operator=(const SQueue & q) { return *this;}
-    bool _enqueue(const T &item); // add item to end
-    bool _dequeue(T &item);       // remove item from front
-public:
-    SQueue(size_t qs = Q_SIZE); // create queue with a qs limit
-    ~SQueue();
-    bool isempty() const;
-    bool isfull() const;
-    int size() const;
-    bool enqueue(const T &item); // add item to end
-    bool enqueue_nowait(const T &item);
-    bool enqueue_timeout(const T &item, struct timespec *timeout);
-    bool dequeue(T &item);
-    bool dequeue_nowait(T &item);
-    bool dequeue_timeout(T &item, struct timespec * timeout);
-    
-
-
-    T& operator[](int i);
-};
-
-
-
-
-// Queue methods
-template <typename T>
-SQueue<T>::SQueue(size_t qs) : qsize(qs)
-{
-    front = rear = NULL;    // or nullptr
-    count = 0;
-
-//std::cout << "=====qsize ==" << qsize << std::endl;
-    slots = pcsem::init(145, qsize);
-    items = pcsem::init(146, 0);
-   
-}
-
-template <typename T>
-SQueue<T>::~SQueue()
-{
-    std::cout << "squeue destory" << std::endl;
-    pcsem::remove(slots);
-    pcsem::remove(items);
-    Node<T> * temp;
-    while (front != NULL)   // while queue is not yet empty
-    {
-        temp = front;       // save address of front item
-        front = front->next;// reset pointer to next item
-        delete temp;        // delete former front
-    }
-    
-}
-
-template <typename T>
-bool SQueue<T>::isempty() const
-{
-    return count == 0;
-}
-
-template <typename T>
-bool SQueue<T>::isfull() const
-{
-    return count == qsize;
-}
-
-template <typename T>
-int SQueue<T>::size() const
-{
-    return count;
-}
-
-// Add item to queue
-template <typename T>
-bool SQueue<T>::_enqueue(const T & item)
-{
-    if (isfull())
-        return false;
-    
-    Node<T> * add = new Node<T>;  // create node
-    
-// on failure, new throws std::bad_alloc exception
-    add->item = item;       // set node pointers
-    add->next = NULL;       // or nullptr;
-    count++;
-    if (front == NULL)      // if queue is empty,
-        front = add;        // place item at front
-    else
-        rear->next = add;   // else place at rear
-    rear = add;
-               
-    return true;
-}
-
-template <typename T>
-bool SQueue<T>::enqueue(const T & item)
-{
-    if (pcsem::dec(slots) == -1) {
-        err_exit(errno, "enqueue");
-    }
-
-    if (SQueue<T>::_enqueue(item)) {
-        pcsem::inc(items);      
-        return true;
-    }
-    return false;
-    
-}
-
-template <typename T>
-bool SQueue<T>::enqueue_nowait(const T & item)
-{
-    if (pcsem::dec_nowait(slots) == -1) {
-        if (errno == EAGAIN)
-            return false;
-        else
-            err_exit(errno, "enqueue_nowait");
-    }
-
-    if (SQueue<T>::_enqueue(item)) {
-        pcsem::inc(items);     
-        return true;
-    }
-    return false;
-    
-}
-
-template <typename T>
-bool SQueue<T>::enqueue_timeout(const T & item, struct timespec * timeout)
-{
-    if (pcsem::dec_timeout(slots, timeout) == -1) {
-        if (errno == EAGAIN)
-            return false;
-        else 
-            err_exit(errno, "enqueue_timeout");
-    }
-
-    if (SQueue<T>::_enqueue(item)){
-        pcsem::inc(items);       
-        return true;
-    }
-    return false;
-    
-}
-
-
-// Place front item into item variable and remove from queue
-template <typename T>
-bool SQueue<T>::_dequeue(T & item)
-{
-    if (isempty())
-        return false;
-    item = front->item;     // set item to first item in queue
-    count--;
-    Node<T> * temp = front;    // save location of first item
-    front = front->next;    // reset front to next item
-    delete temp;            // delete former first item
-    if (count == 0)
-        rear = NULL;
-    
-    return true;
-}
-
-template <typename T>
-bool SQueue<T>::dequeue(T & item)
-{
-    if (pcsem::dec(items) == -1) {
-        err_exit(errno, "dequeue");
-    }
-
-    if (SQueue<T>::_dequeue(item)) {
-        pcsem::inc(slots);      
-        return true;
-    }
-    return false;
-    
-}
-
-template <typename T>
-bool SQueue<T>::dequeue_nowait(T & item)
-{
-    if (pcsem::dec_nowait(items) == -1) {
-        if (errno == EAGAIN)
-            return false;
-        else
-            err_exit(errno, "dequeue_nowait");
-    }
-
-    if (SQueue<T>::_dequeue(item)) {
-        pcsem::inc(slots);     
-        return true;
-    }
-    return false;
-    
-}
-
-template <typename T>
-bool SQueue<T>::dequeue_timeout(T & item, struct timespec * timeout)
-{
-    if (pcsem::dec_timeout(items, timeout) == -1) {
-        if (errno == EAGAIN)
-            return false;
-        else 
-            err_exit(errno, "dequeue_timeout");
-    }
-
-    if (SQueue<T>::_dequeue(item)) {
-        pcsem::inc(slots);       
-        return true;
-    }
-    return false;
-    
-}
-
- 
-template <class T>
-T& SQueue<T>::operator[](int i)
-{
-    if (i < 0 || i >= count)
-    {
-        std::cerr << "Error in array limits: " << i << " is out of range\n";
-        std::exit(EXIT_FAILURE);
-    }
-
-    Node<T> * temp = front;
-    while(i-->0) {
-        temp = temp->next;
-    }
-    return temp->item;
-}
-
-
-#endif
diff --git a/squeue/logger_factory.h b/squeue/logger_factory.h
new file mode 100644
index 0000000..1ff8110
--- /dev/null
+++ b/squeue/logger_factory.h
@@ -0,0 +1,17 @@
+#ifndef __LOGGER_FACTORY_H__
+#define __LOGGER_FACTORY_H__
+#include "logger.h"
+
+class LoggerFactory {
+public:
+
+	static Logger getLogger() {
+
+		static Logger logger(Logger::ALL);
+		return logger;
+	}
+};
+
+#endif
+
+
diff --git a/squeue/mm.c b/squeue/mm.c
index c48347a..34480ea 100644
--- a/squeue/mm.c
+++ b/squeue/mm.c
@@ -3,7 +3,7 @@
  */
 #include "mm.h"
 #include "sem_util.h"
-
+#include "logger_factory.h"
 
 /* $begin mallocmacros */
 /* single word (4) or double word (8) alignment */
@@ -279,12 +279,29 @@
  
 
 void mm_destroy(void) {
-
+  struct shmid_ds shmid_ds;
+  //detache
   if (shmdt(shmp) == -1)
-    err_exit(errno, "mm_init shmdt");
-  if (shmctl(shmid, IPC_RMID, 0) == -1)
-    err_exit(errno, "mm_init shmctl IPC_RMID");
-  SemUtil::remove(mutex);
+    err_exit(errno, "mm_destroy shmdt");
+
+  
+  if(shmctl(shmid, IPC_STAT, &shmid_ds) == -1) {
+    err_exit(errno, "mm_destroy shmctl IPC_STAT");
+  } else {
+    //LoggerFactory::getLogger().debug("shm_nattch=%d\n", shmid_ds.shm_nattch);
+    if(shmid_ds.shm_nattch == 0) {
+      //remove shared memery
+       if (shmctl(shmid, IPC_RMID, 0) == -1)
+        err_exit(errno, "mm_destroy shmctl IPC_RMID");
+       else 
+         LoggerFactory::getLogger().debug("shared memory destroy\n");
+
+       SemUtil::remove(mutex);
+
+    }
+  }
+ 
+  
 }
 /*
  * extend_heap - Extend heap with free block and return its block pointer
diff --git a/test/multiple_queue_consumer b/test/multiple_queue_consumer
index 75cfc18..b9e6948 100755
--- a/test/multiple_queue_consumer
+++ b/test/multiple_queue_consumer
Binary files differ
diff --git a/test/multiple_queue_productor b/test/multiple_queue_productor
index 4d57808..0655491 100755
--- a/test/multiple_queue_productor
+++ b/test/multiple_queue_productor
Binary files differ
diff --git a/test/single_consumer b/test/single_consumer
index 35f1951..f6760a4 100755
--- a/test/single_consumer
+++ b/test/single_consumer
Binary files differ
diff --git a/test/single_productor b/test/single_productor
index 31ff4a0..603cf65 100755
--- a/test/single_productor
+++ b/test/single_productor
Binary files differ
diff --git a/test/test.h b/test/test.h
index e03e0f4..153eb6a 100644
--- a/test/test.h
+++ b/test/test.h
@@ -26,7 +26,7 @@
 	// delete queue;
 
 	QueueFactory::dropQueue<struct Item>(key);
-    //mm_destroy();
+    mm_destroy();
     
 
 }
diff --git a/test/test_queue b/test/test_queue
old mode 100755
new mode 100644
index 56758c2..95aab00
--- a/test/test_queue
+++ b/test/test_queue
Binary files differ
diff --git a/test/test_timeout b/test/test_timeout
index 8a37ff1..0a2c9b8 100755
--- a/test/test_timeout
+++ b/test/test_timeout
Binary files differ

--
Gitblit v1.8.0