| | |
| | | ./shm/shm_mm_wrapper.cpp |
| | | ./shm/mm.cpp |
| | | ./shm/hashtable.cpp |
| | | ./shm/shm_mm.cpp |
| | | |
| | | ) |
| | | |
| | | if (BUILD_SHARED_LIBS) |
| | | add_library(shm_queue SHARED ${_SOURCES_}) |
| | | else() |
| | | add_library(shm_queue SHARED ${_SOURCES_}) |
| | | add_library(shm_queue STATIC ${_SOURCES_}) |
| | | endif() |
| | | |
| | | # STATIC |
| | |
| | | # install rules |
| | | install(TARGETS shm_queue DESTINATION lib) |
| | | install(FILES |
| | | ./socket/socket_def.h |
| | | ./socket/bus_server_socket.h |
| | | ./socket/shm_socket.h |
| | | ./socket/shm_mod_socket.h |
| | | ./socket/bus_server_socket_wrapper.h |
| | | ./psem.h |
| | | ./key_def.h |
| | | ./time_util.h |
| | | ./futex_sem.h |
| | | ./bus_error.h |
| | | ./bus_def.h |
| | | ./sole.h |
| | | ./logger_factory.h |
| | | ./queue/linked_lock_free_queue.h |
| | | ./queue/array_lock_free_queue.h |
| | | ./queue/shm_queue.h |
| | | ./queue/array_lock_free_sem_queue.h |
| | | ./queue/lock_free_queue.h |
| | | ./svsem.h |
| | | ./net/net_conn_pool.h |
| | | ./net/net_mod_socket.h |
| | | ./net/net_mod_server_socket_wrapper.h |
| | | ./net/net_mod_socket_io.h |
| | | ./net/net_mod_server_socket.h |
| | | ./net/net_mod_socket_wrapper.h |
| | | ./shm/hashtable.h |
| | | ./shm/mem_pool.h |
| | | ./shm/mm.h |
| | | ./shm/shm_mm_wrapper.h |
| | | ./shm/shm_allocator.h |
| | | ./socket/socket_def.h |
| | | ./socket/bus_server_socket.h |
| | | ./socket/shm_socket.h |
| | | ./socket/shm_mod_socket.h |
| | | ./socket/bus_server_socket_wrapper.h |
| | | ./psem.h |
| | | ./pread_write_lock.h |
| | | ./key_def.h |
| | | ./time_util.h |
| | | ./sv_read_write_lock.h |
| | | ./futex_sem.h |
| | | ./bus_error.h |
| | | ./bus_def.h |
| | | ./logger_factory.h |
| | | ./sole.h |
| | | ./queue/linked_lock_free_queue.h |
| | | ./queue/array_lock_free_queue.h |
| | | ./queue/shm_queue.h |
| | | ./queue/array_lock_free_sem_queue.h |
| | | ./queue/lock_free_queue.h |
| | | ./svsem.h |
| | | ./net/net_conn_pool.h |
| | | ./net/net_mod_socket.h |
| | | ./net/net_mod_server_socket_wrapper.h |
| | | ./net/net_mod_socket_io.h |
| | | ./net/net_mod_server_socket.h |
| | | ./net/net_mod_socket_wrapper.h |
| | | ./shm/hashtable.h |
| | | ./shm/mm.h |
| | | ./shm/shm_mm_wrapper.h |
| | | ./shm/shm_allocator.h |
| | | ./shm/shm_mm.h |
| | | |
| | | |
| | | DESTINATION include) |
| | | |
| | |
| | | #ifndef _KEY_DEF_H_ |
| | | #define _KEY_DEF_H_ |
| | | |
| | | // bus中主题与订阅者对应关系的map |
| | | #define SHM_BUS_MAP_KEY 1 |
| | | |
| | | |
| | | // 队列状态标记的map |
| | | #define SHM_QUEUE_ST_KEY 3 |
| | | |
| | | // BUS key |
| | | #define SHM_BUS_KEY 8 |
| | | |
| | | // 网络代理key |
| | | #define SHM_NET_PROXY_KEY 99 |
| | | |
| | |
| | | #include <assert.h> // assert() |
| | | #include <sched.h> // sched_yield() |
| | | #include "logger_factory.h" |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "shm_allocator.h" |
| | | |
| | | /// @brief implementation of an array based lock free queue with support for |
| | |
| | | #include <assert.h> // assert() |
| | | #include <sched.h> // sched_yield() |
| | | #include "logger_factory.h" |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "shm_allocator.h" |
| | | #include "futex_sem.h" |
| | | #include "time_util.h" |
| | |
| | | |
| | | #include <usg_common.h> |
| | | #include <assert.h> // assert() |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "sem_util.h" |
| | | #include "logger_factory.h" |
| | | #include "shm_allocator.h" |
| | |
| | | |
| | | template <typename ELEM_T> SHMQueue<ELEM_T>::~SHMQueue() { |
| | | LoggerFactory::getLogger()->debug("SHMQueue destroy"); |
| | | if(owner) { |
| | | delete queue; |
| | | hashtable_remove(hashtable, mkey); |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | |
| | | #ifndef __SHM_ALLOCATOR_H__ |
| | | #define __SHM_ALLOCATOR_H__ |
| | | #include "usg_common.h" |
| | | #include "mem_pool.h" |
| | | #include "mm.h" |
| | | #include <new> |
| | | #include <cstdlib> // for exit() |
| | | #include <climits> // for UNIX_MAX |
| | |
| | | } |
| | | |
| | | |
| | | template <typename T> |
| | | T* shm_mm_attach(int key) { |
| | | void *ptr; |
| | | // T* tptr; |
| | | hashtable_t *hashtable = mm_get_hashtable(); |
| | | ptr = hashtable_get(hashtable, key); |
| | | // printf("shm_mm_malloc_by_key malloc before %d, %p\n", key, ptr); |
| | | if(ptr == NULL || ptr == (void *)1 ) { |
| | | ptr = mm_malloc(sizeof(T)); |
| | | hashtable_put(hashtable, key, ptr); |
| | | new(ptr) T; |
| | | // printf("shm_mm_malloc_by_key use new %d, %p\n", key, ptr); |
| | | } |
| | | return (T*)ptr; |
| | | } |
| | | |
| | | void shm_mm_free_by_key(int key) { |
| | | return mm_free_by_key(key); |
| | |
| | | |
| | | return mm_alloc_key(); |
| | | } |
| | | |
| | | |
| | | // extern int mm_checkheap(int verbose); |
| | | |
| | | |
| | | #endif |
| | |
| | | #ifndef __SHM_MM_H__ |
| | | #define __SHM_MM_H__ |
| | | #include "usg_common.h" |
| | | #include "shm_allocator.h" |
| | | #include "key_def.h" |
| | | |
| | | #define SHM_QUEUE_ST_OPENED 0 |
| | | |
| | | #define SHM_QUEUE_ST_CLOSED 1 |
| | | #define SHM_QUEUE_ST_RECYCLED 2 |
| | | |
| | | struct shm_queue_status_t { |
| | | |
| | |
| | | void shm_mm_free (void *ptr); |
| | | |
| | | |
| | | |
| | | template <typename T> |
| | | T* shm_mm_attach(int key) ; |
| | | T* shm_mm_attach(int key) { |
| | | void *ptr; |
| | | // T* tptr; |
| | | hashtable_t *hashtable = mm_get_hashtable(); |
| | | ptr = hashtable_get(hashtable, key); |
| | | // printf("shm_mm_malloc_by_key malloc before %d, %p\n", key, ptr); |
| | | if(ptr == NULL || ptr == (void *)1 ) { |
| | | ptr = mm_malloc(sizeof(T)); |
| | | hashtable_put(hashtable, key, ptr); |
| | | new(ptr) T; |
| | | // printf("shm_mm_malloc_by_key use new %d, %p\n", key, ptr); |
| | | } |
| | | return (T*)ptr; |
| | | } |
| | | |
| | | void shm_mm_free_by_key(int key) ; |
| | | |
| | |
| | | #include "shm_mm_wrapper.h" |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "hashtable.h" |
| | | #include "lock_free_queue.h" |
| | | #include "shm_socket.h" |
| | | |
| | | #define BUFFER_TIME 10 |
| | | #define BUFFER_TIME 1 |
| | | |
| | | |
| | | void shm_mm_wrapper_init(int size) { |
| | |
| | | LockFreeQueue<shm_packet_t> *mqueue; |
| | | while(true) { |
| | | for(auto it = shmQueueStMap->begin(); it != shmQueueStMap->end(); ++it ) { |
| | | if(it->second.status = SHM_QUEUE_ST_CLOSED && difftime(time(NULL), it->second.closeTime) > 2 ) { |
| | | mqueue = (LockFreeQueue<shm_packet_t> *)hashtable_get(hashtable, keys[i]); |
| | | if(mqueue != NULL) { |
| | | delete mqueue; |
| | | hashtable_remove(hashtable, it->first); |
| | | printf("reove queue %d\n", it->first); |
| | | // 不能 erase ,否则会出现多进程之间的同步问题, 而这正是这里要解决的问题 |
| | | // it = shmQueueStMap->erase(it); |
| | | // continue; |
| | | } |
| | | if(it->second.status == SHM_QUEUE_ST_CLOSED && difftime(time(NULL), it->second.closeTime) > BUFFER_TIME ) { |
| | | // mqueue = (LockFreeQueue<shm_packet_t> *)hashtable_get(hashtable, keys[i]); |
| | | // if(mqueue != NULL) { |
| | | // delete mqueue; |
| | | // } |
| | | |
| | | hashtable_remove(hashtable, it->first); |
| | | printf("reomved queue %d\n\n", it->first); |
| | | it->second.status = SHM_QUEUE_ST_RECYCLED; |
| | | // 不能 erase ,否则会出现多进程之间的同步问题, 而这正是这里要解决的问题 |
| | | // it = shmQueueStMap->erase(it); |
| | | // continue; |
| | | } |
| | | } |
| | | |
| | | sleep(1); |
| | | } |
| | | return 0; |
| | | } |
| | | |
| | | //删除包含在keys内的queue |
| | |
| | | int count = 0; |
| | | for(int i = 0; i< length; i++) { |
| | | // 销毁共享内存的queue |
| | | mqueue = (LockFreeQueue<shm_packet_t> *)hashtable_get(hashtable, keys[i]); |
| | | if(mqueue == NULL) { |
| | | continue; |
| | | } |
| | | if(difftime(time(NULL), mqueue->getCreateTime()) > BUFFER_TIME ) { |
| | | delete mqueue; |
| | | hashtable_remove(hashtable, keys[i]); |
| | | LoggerFactory::getLogger()->debug("remove queue %d", keys[i]); |
| | | count++; |
| | | } |
| | | hashtable_remove(hashtable, keys[i]); |
| | | LoggerFactory::getLogger()->debug("remove queue %d", keys[i]); |
| | | count++; |
| | | |
| | | } |
| | | return count; |
| | |
| | | // 100内的是bus内部自己用的 |
| | | if (!found && *keyItr > 100) { |
| | | // 销毁共享内存的queue |
| | | mqueue = (LockFreeQueue<shm_packet_t> *)hashtable_get(hashtable, *keyItr); |
| | | if(difftime(time(NULL), mqueue->getCreateTime()) > BUFFER_TIME ) { |
| | | delete mqueue; |
| | | hashtable_remove(hashtable, *keyItr); |
| | | LoggerFactory::getLogger()->debug("remove queue %d", *keyItr); |
| | | count++; |
| | | } |
| | | hashtable_remove(hashtable, *keyItr); |
| | | LoggerFactory::getLogger()->debug("remove queue %d", *keyItr); |
| | | count++; |
| | | |
| | | } |
| | | } |
| | |
| | | */ |
| | | void shm_mm_wrapper_destroy(); |
| | | |
| | | /** |
| | | * @brief 回收标记为删除的队列 |
| | | * @return 错误码 |
| | | */ |
| | | int shm_mm_wrapper_start_resycle() ; |
| | | |
| | | /** |
| | | * @brief 分配一个key给申请者 |
| | |
| | | #include "usg_common.h" |
| | | #include "shm_socket.h" |
| | | #include "shm_allocator.h" |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "hashtable.h" |
| | | #include "sem_util.h" |
| | | #include "logger_factory.h" |
| | |
| | | #include "usg_common.h" |
| | | #include "shm_socket.h" |
| | | #include "shm_allocator.h" |
| | | #include "mem_pool.h" |
| | | #include "shm_mm.h" |
| | | #include "hashtable.h" |
| | | #include "sem_util.h" |
| | | #include "logger_factory.h" |
| | |
| | | #include "bus_error.h" |
| | | #include "sole.h" |
| | | #include "shm_mm.h" |
| | | #include "key_def.h" |
| | | |
| | | static Logger *logger = LoggerFactory::getLogger(); |
| | | |
| | |
| | | } |
| | | |
| | | |
| | | int shm_socket_close(shm_socket_t *sockt) { |
| | | static int _shm_socket_close_(shm_socket_t *sockt) { |
| | | |
| | | int rv; |
| | | logger->debug("shm_socket_close\n"); |
| | |
| | | // sockt->queue = NULL; |
| | | // } |
| | | |
| | | pthread_mutex_destroy(&(sockt->mutex) ); |
| | | |
| | | // hashtable_remove(hashtable, mkey); |
| | | |
| | | free(sockt); |
| | | |
| | | auto it = shmQueueStMap.find(key); |
| | | if(it != shmQueueStMap.end()) { |
| | | it->second.status = SHM_QUEUE_ST_CLOSED |
| | | it->second.closeTime = time(NULL); |
| | | |
| | | if(sockt->key != 0) { |
| | | auto it = shmQueueStMap->find(sockt->key); |
| | | if(it != shmQueueStMap->end()) { |
| | | it->second.status = SHM_QUEUE_ST_CLOSED; |
| | | it->second.closeTime = time(NULL); |
| | | } |
| | | } |
| | | |
| | | |
| | | |
| | | pthread_mutex_destroy(&(sockt->mutex) ); |
| | | free(sockt); |
| | | return 0; |
| | | } |
| | | |
| | | |
| | | int shm_socket_close(shm_socket_t *sockt) { |
| | | return _shm_socket_close_(sockt); |
| | | } |
| | | |
| | | |
| | |
| | | return; |
| | | |
| | | logger->debug("%d destroy tmp socket\n", pthread_self()); |
| | | shm_socket_close((shm_socket_t *)tmp_socket); |
| | | _shm_socket_close_((shm_socket_t *)tmp_socket); |
| | | rv = pthread_setspecific(_perthread_socket_key_, NULL); |
| | | if ( rv != 0) { |
| | | logger->error(rv, "shm_sendandrecv : pthread_setspecific"); |
| | |
| | | return EBUS_RECVFROM_WRONG_END; |
| | | } |
| | | |
| | | shm_socket_close(tmp_socket); |
| | | _shm_socket_close_(tmp_socket); |
| | | return rv; |
| | | |
| | | } |
| | |
| | | |
| | | int rv; |
| | | shm_queue_status_t stRecord; |
| | | LockFreeQueue<shm_packet_t> *remoteQueue; |
| | | hashtable_t *hashtable = mm_get_hashtable(); |
| | | |
| | | if( sockt->queue != NULL) |
| | |
| | | // 标记key对应的状态 ,为opened |
| | | stRecord.status = SHM_QUEUE_ST_OPENED; |
| | | stRecord.createTime = time(NULL); |
| | | shmQueueStMap.insert({sockt->key, stRecord}); |
| | | shmQueueStMap->insert({sockt->key, stRecord}); |
| | | |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | // 检查key标记的状态 |
| | | auto it = shmQueueStMap.find(key); |
| | | if(it != shmQueueStMap.end()) { |
| | | auto it = shmQueueStMap->find(key); |
| | | if(it != shmQueueStMap->end()) { |
| | | if(it->second.status == SHM_QUEUE_ST_CLOSED) { |
| | | // key对应的状态是关闭的 |
| | | goto ERR_CLOSED; |
| | | } |
| | | } |
| | | |
| | | LockFreeQueue<shm_packet_t> *remoteQueue = shm_socket_attach_queue(key); |
| | | remoteQueue = shm_socket_attach_queue(key); |
| | | |
| | | if (remoteQueue == NULL ) { |
| | | goto ERR_CLOSED; |
| | |
| | | // 标记key对应的状态 ,为opened |
| | | stRecord.status = SHM_QUEUE_ST_OPENED; |
| | | stRecord.createTime = time(NULL); |
| | | shmQueueStMap.insert({sockt->key, stRecord}); |
| | | shmQueueStMap->insert({sockt->key, stRecord}); |
| | | |
| | | if ((rv = pthread_mutex_unlock(&(sockt->mutex))) != 0) |
| | | err_exit(rv, "shm_recvfrom : pthread_mutex_unlock"); |
| | |
| | | LABEL_POP: |
| | | |
| | | // 检查key标记的状态 |
| | | // auto shmQueueMapIter = shmQueueStMap.find(sockt->key); |
| | | // if(shmQueueMapIter != shmQueueStMap.end()) { |
| | | // auto shmQueueMapIter = shmQueueStMap->find(sockt->key); |
| | | // if(shmQueueMapIter != shmQueueStMap->end()) { |
| | | // stRecord = shmQueueMapIter->second; |
| | | // if(stRecord.status = SHM_QUEUE_ST_CLOSED) { |
| | | // // key对应的状态是关闭的 |
| | |
| | | ./test_net_mod_socket --fun="start_reply" --key=100 & server_pid=$! && echo "pid: ${server_pid}" |
| | | ./test_net_mod_socket --fun="start_reply" --key=101 & server_pid=$! && echo "pid: ${server_pid}" |
| | | ./test_net_mod_socket --fun="start_reply" --key=102 & server_pid=$! && echo "pid: ${server_pid}" |
| | | |
| | | # 打开回队列收进程 |
| | | ./test_net_mod_socket --fun="start_resycle" & server_pid=$! && echo "pid: ${server_pid}" |
| | | } |
| | | |
| | | # 交互式客户端 |
| | |
| | | } |
| | | |
| | | |
| | | int main(int argc, char *argv[]) { |
| | | shm_mm_wrapper_init(512); |
| | | |
| | | argument_t opt = parse_args(argc, argv); |
| | | |
| | | // port = atoi(argv[2]); |
| | | |
| | | if(opt.fun == NULL) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | if (strcmp("start_net_proxy", opt.fun) == 0 ) { |
| | | if(opt.port == 0) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_net_proxy(opt); |
| | | |
| | | } |
| | | else if (strcmp("start_bus_server", opt.fun) == 0) { |
| | | |
| | | start_bus_server(opt); |
| | | } |
| | | else if (strcmp("start_reply", opt.fun) == 0) { |
| | | if(opt.key == 0) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_reply(opt.key); |
| | | } |
| | | else if (strcmp("start_net_client", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist.\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_net_client(opt.sendlist, opt.publist); |
| | | } |
| | | else if (strcmp("one_sendto_many", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | one_sendto_many(opt.sendlist); |
| | | } |
| | | else if (strcmp("test_net_sendandrecv", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_sendandrecv(opt.sendlist); |
| | | } |
| | | else if (strcmp("test_net_pub_threads", opt.fun) == 0) { |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_pub_threads(opt.publist); |
| | | } |
| | | else if (strcmp("test_net_pub", opt.fun) == 0) { |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_pub(opt.publist); |
| | | } |
| | | else if (strcmp("start_resycle", opt.fun) == 0) { |
| | | start_resycle(); |
| | | } |
| | | |
| | | else { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | |
| | | } |
| | | |
| | | printf("==========end========\n"); |
| | | // shm_mm_wrapper_destroy(); |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | void usage(char *name) |
| | | { |
| | |
| | | } |
| | | printf("============node list end==========\n"); |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | int main(int argc, char *argv[]) { |
| | | shm_mm_wrapper_init(512); |
| | | |
| | | argument_t opt = parse_args(argc, argv); |
| | | |
| | | // port = atoi(argv[2]); |
| | | |
| | | if(opt.fun == NULL) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | if (strcmp("start_net_proxy", opt.fun) == 0 ) { |
| | | if(opt.port == 0) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_net_proxy(opt); |
| | | |
| | | } |
| | | else if (strcmp("start_bus_server", opt.fun) == 0) { |
| | | |
| | | start_bus_server(opt); |
| | | } |
| | | else if (strcmp("start_reply", opt.fun) == 0) { |
| | | if(opt.key == 0) { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_reply(opt.key); |
| | | } |
| | | else if (strcmp("start_net_client", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist.\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | start_net_client(opt.sendlist, opt.publist); |
| | | } |
| | | else if (strcmp("one_sendto_many", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | one_sendto_many(opt.sendlist); |
| | | } |
| | | else if (strcmp("test_net_sendandrecv", opt.fun) == 0) { |
| | | if(opt.sendlist == 0) { |
| | | fprintf(stderr, "Missing sendlist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_sendandrecv(opt.sendlist); |
| | | } |
| | | else if (strcmp("test_net_pub_threads", opt.fun) == 0) { |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_pub_threads(opt.publist); |
| | | } |
| | | else if (strcmp("test_net_pub", opt.fun) == 0) { |
| | | if(opt.publist == 0) { |
| | | fprintf(stderr, "Missing publist .\n"); |
| | | usage(argv[0]); |
| | | exit(1); |
| | | } |
| | | |
| | | test_net_pub(opt.publist); |
| | | } |
| | | else if (strcmp("start_resycle", opt.fun) == 0) { |
| | | start_resycle(); |
| | | } |
| | | |
| | | else { |
| | | usage(argv[0]); |
| | | exit(1); |
| | | |
| | | } |
| | | |
| | | printf("==========end========\n"); |
| | | // shm_mm_wrapper_destroy(); |
| | | |
| | | } |