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