# HG changeset patch # User Yasumasa Suenaga # Date 1573313198 -32400 # Node ID 3a15cfb00a396bf90229fc294a5e112333075c54 # Parent 866500a172fa8fc1a703425c2a86975ed759154e Bug 3765: pthread mutex lock/unlock enhancement Reviewed-by: ykubota https://github.com/HeapStats/heapstats/pull/150 diff -r 866500a172fa -r 3a15cfb00a39 ChangeLog --- a/ChangeLog Sun Apr 08 22:03:49 2018 +0900 +++ b/ChangeLog Sun Nov 10 00:26:38 2019 +0900 @@ -1,3 +1,7 @@ +2019-11-10 Yasumasa Suenaga + + * Bug 3765: pthread mutex lock/unlock enhancement + 2018-04-08 Yasumasa Suenaga * Bug 3570: Build warning on Arm box diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/agentThread.cpp --- a/agent/src/heapstats-engines/agentThread.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/agentThread.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file agentThread.cpp * \brief This file is used to work on Jthread. - * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -107,12 +107,11 @@ * \brief Notify timing to this thread from other thread. */ void TAgentThread::notify(void) { + TMutexLocker locker(&this->mutex); + /* Send notification and count notify. */ - ENTER_PTHREAD_SECTION(&this->mutex) { - this->_numRequests++; - pthread_cond_signal(&this->mutexCond); - } - EXIT_PTHREAD_SECTION(&this->mutex) + this->_numRequests++; + pthread_cond_signal(&this->mutexCond); } /*! @@ -126,11 +125,12 @@ } /* Send notification and count notify. */ - ENTER_PTHREAD_SECTION(&this->mutex) { + { + TMutexLocker locker(&this->mutex); + this->_terminateRequest = true; pthread_cond_signal(&this->mutexCond); } - EXIT_PTHREAD_SECTION(&this->mutex) /* SpinLock for AgentThread termination. */ while (this->_isRunning) { diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/deadlockFinder.cpp --- a/agent/src/heapstats-engines/deadlockFinder.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/deadlockFinder.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file deadlockFinder.cpp * \brief This file is used by find deadlock. - * Copyright (C) 2011-2016 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -589,11 +589,17 @@ controller->_isRunning = true; /* Loop for agent run. */ - while (!controller->_terminateRequest) { + while (true) { /* Variable for notification flag. */ bool needProcess = false; - ENTER_PTHREAD_SECTION(&controller->mutex) { + { + TMutexLocker locker(&controller->mutex); + + if (controller->_terminateRequest) { + break; + } + /* If no exists request. */ if (likely(controller->_numRequests == 0)) { /* Wait for notification or termination. */ @@ -610,7 +616,6 @@ controller->timeList.pop(); } } - EXIT_PTHREAD_SECTION(&controller->mutex) /* If get notification. */ if (likely(needProcess)) { @@ -641,7 +646,9 @@ void TDeadlockFinder::notify(jlong aTime) { bool raiseException = true; /* Send notification and count notify. */ - ENTER_PTHREAD_SECTION(&this->mutex) { + { + TMutexLocker locker(&this->mutex); + try { /* Store and count data. */ timeList.push(aTime); @@ -659,7 +666,6 @@ */ } } - EXIT_PTHREAD_SECTION(&this->mutex) if (unlikely(raiseException)) { throw "Failed to TDeadlockFinder notify"; diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/fsUtil.cpp --- a/agent/src/heapstats-engines/fsUtil.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/fsUtil.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file fsUtil.cpp * \brief This file is utilities to access file system. - * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -242,8 +242,8 @@ } int raisedErrNum = -1; - /* Get mutex. */ - ENTER_PTHREAD_SECTION(&directoryMutex) { + { + TMutexLocker locker(&directoryMutex); /* Create unique directory path. */ uniqName = createUniquePath((char *)wishesName, true); @@ -258,8 +258,6 @@ } } } - /* Release mutex. */ - EXIT_PTHREAD_SECTION(&directoryMutex) /* If failed to create temporary directory. */ if (unlikely(raisedErrNum != 0)) { @@ -330,8 +328,8 @@ /* Cleanup. */ closedir(dir); - /* Get mutex. */ - ENTER_PTHREAD_SECTION(&directoryMutex) { + { + TMutexLocker locker(&directoryMutex); /* Remove directory. */ if (unlikely(rmdir(basePath) != 0)) { @@ -340,8 +338,6 @@ } } - /* Release mutex. */ - EXIT_PTHREAD_SECTION(&directoryMutex) } /*! diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/gcWatcher.cpp --- a/agent/src/heapstats-engines/gcWatcher.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/gcWatcher.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file gcWatcher.cpp * \brief This file is used to take snapshot when finish garbage collection. - * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -62,11 +62,17 @@ controller->_isRunning = true; /* Loop for agent run. */ - while (!controller->_terminateRequest) { + while (true) { /* Variable for notification flag. */ bool needProcess = false; - ENTER_PTHREAD_SECTION(&controller->mutex) { + { + TMutexLocker locker(&controller->mutex); + + if (controller->_terminateRequest) { + break; + } + /* If no exists request. */ if (likely(controller->_numRequests == 0)) { /* Wait for notification or termination. */ @@ -79,7 +85,6 @@ needProcess = true; } } - EXIT_PTHREAD_SECTION(&controller->mutex) /* If waiting finished by notification. */ if (needProcess) { diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/logMain.cpp --- a/agent/src/heapstats-engines/logMain.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/logMain.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file logmain.cpp * \brief This file is used common logging process. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -237,8 +237,8 @@ } bool isCollectLog = true; - /* Lock to use in multi-thread. */ - ENTER_PTHREAD_SECTION(&errMutex) { + { + TMutexLocker locker(&errMutex); /* If collected already and collect first only. */ if (conf->FirstCollect()->get() && conf->isFirstCollected()) { @@ -249,8 +249,6 @@ conf->setFirstCollected(true); } - /* Unlock to use in multi-thread. */ - EXIT_PTHREAD_SECTION(&errMutex) if (isCollectLog) { /* Setting collect log cause. */ diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/logManager.cpp --- a/agent/src/heapstats-engines/logManager.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/logManager.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file logManager.cpp * \brief This file is used collect log information. - * Copyright (C) 2011-2016 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -255,8 +255,8 @@ /* Params : Archive file name. */ archivePath); - /* Get mutex. */ - ENTER_PTHREAD_SECTION(&logMutex) { + { + TMutexLocker locker(&logMutex); /* Open log file. */ int fd = open(conf->HeapLogFile()->get(), O_CREAT | O_WRONLY | O_APPEND, @@ -282,8 +282,7 @@ } } } - /* Release mutex. */ - EXIT_PTHREAD_SECTION(&logMutex) + return result; } @@ -379,8 +378,8 @@ */ result = -1; - /* Get mutex. */ - ENTER_PTHREAD_SECTION(&archiveMutex) { + { + TMutexLocker locker(&archiveMutex); /* Create archive file name. */ uniqArcName = createArchiveName(nowTime); @@ -400,8 +399,6 @@ } } } - /* Release mutex. */ - EXIT_PTHREAD_SECTION(&archiveMutex) /* If failure create archive file yet. */ if (unlikely(result != 0)) { diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/snapShotContainer.cpp --- a/agent/src/heapstats-engines/snapShotContainer.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/snapShotContainer.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file snapshotContainer.cpp * \brief This file is used to add up using size every class. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -89,27 +89,26 @@ * Please call "releaseInstance" method. */ TSnapShotContainer *TSnapShotContainer::getInstance(void) { + TMutexLocker locker(&instanceLocker); + TSnapShotContainer *result = NULL; - ENTER_PTHREAD_SECTION(&instanceLocker) { - if (!stockQueue->empty()) { - /* Reuse snapshot container instance. */ - result = stockQueue->front(); - stockQueue->pop(); - } + if (!stockQueue->empty()) { + /* Reuse snapshot container instance. */ + result = stockQueue->front(); + stockQueue->pop(); + } - /* If need create new instance. */ - if (result == NULL) { - /* Create new snapshot container instance. */ - try { - result = new TSnapShotContainer(); - activeSnapShots.insert(result); - } catch (...) { - result = NULL; - } + /* If need create new instance. */ + if (result == NULL) { + /* Create new snapshot container instance. */ + try { + result = new TSnapShotContainer(); + activeSnapShots.insert(result); + } catch (...) { + result = NULL; } } - EXIT_PTHREAD_SECTION(&instanceLocker) return result; } @@ -126,10 +125,11 @@ } bool existStockSpace = false; - ENTER_PTHREAD_SECTION(&instanceLocker) { + { + TMutexLocker locker(&instanceLocker); + existStockSpace = (stockQueue->size() < MAX_STOCK_COUNT); } - EXIT_PTHREAD_SECTION(&instanceLocker) if (likely(existStockSpace)) { /* @@ -143,7 +143,9 @@ /* Clear data. */ instance->clear(false); - ENTER_PTHREAD_SECTION(&instanceLocker) { + { + TMutexLocker locker(&instanceLocker); + try { /* Store instance. */ stockQueue->push(instance); @@ -153,18 +155,17 @@ /* Maybe faield to allocate memory. So we release instance. */ } } - EXIT_PTHREAD_SECTION(&instanceLocker) } - ENTER_PTHREAD_SECTION(&instanceLocker) { + TMutexLocker locker(&instanceLocker); + if (unlikely(!existStockSpace)) { /* Deallocate instance. */ activeSnapShots.erase(instance); delete instance; } } - EXIT_PTHREAD_SECTION(&instanceLocker) } /*! @@ -572,13 +573,11 @@ */ void TSnapShotContainer::removeObjectDataFromAllSnapShots( TClassInfoSet &unloadedList) { - ENTER_PTHREAD_SECTION(&instanceLocker) - { - for (TActiveSnapShots::iterator itr = activeSnapShots.begin(); - itr != activeSnapShots.end(); itr++) { - (*itr)->removeObjectData(unloadedList); - } + TMutexLocker locker(&instanceLocker); + + for (TActiveSnapShots::iterator itr = activeSnapShots.begin(); + itr != activeSnapShots.end(); itr++) { + (*itr)->removeObjectData(unloadedList); } - EXIT_PTHREAD_SECTION(&instanceLocker) } diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/snapShotMain.cpp --- a/agent/src/heapstats-engines/snapShotMain.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/snapShotMain.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file snapShotMain.cpp * \brief This file is used to take snapshot. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -183,7 +183,9 @@ inline bool addSnapShotQueue(TSnapShotContainer *snapshot) { bool isSucceed = false; /* Push output waiting queue. */ - ENTER_PTHREAD_SECTION(&queueMutex) { + { + TMutexLocker locker(&queueMutex); + try { snapStockQueue.push(snapshot); @@ -196,7 +198,6 @@ */ } } - EXIT_PTHREAD_SECTION(&queueMutex) return isSucceed; } @@ -210,13 +211,14 @@ TSnapShotContainer *snapshot = NULL; /* Get snapshot data from waiting queue. */ - ENTER_PTHREAD_SECTION(&queueMutex) { + { + TMutexLocker locker(&queueMutex); + if (likely(!snapStockQueue.empty())) { snapshot = snapStockQueue.front(); snapStockQueue.pop(); } } - EXIT_PTHREAD_SECTION(&queueMutex) return snapshot; } @@ -589,11 +591,9 @@ /* Avoid the plural simultaneous take snapshot by dump-request. */ /* E.g. keeping pushed dump key. */ /* Because classContainer register a redundancy class in TakeSnapShot. */ - ENTER_PTHREAD_SECTION(&dumpMutex) { - /* Make snapshot. */ - TakeSnapShot(jvmti, NULL, DataDumpRequest); - } - EXIT_PTHREAD_SECTION(&dumpMutex) + TMutexLocker locker(&dumpMutex); + + TakeSnapShot(jvmti, NULL, DataDumpRequest); } /*! @@ -633,22 +633,21 @@ if (likely(snapshot != NULL)) { /* Lock to avoid doubling call JVMTI. */ - ENTER_PTHREAD_SECTION(&jvmtiMutex) { - snapshotByJvmti = snapshot; + TMutexLocker locker(&jvmtiMutex); + + snapshotByJvmti = snapshot; - /* Enable JVMTI hooking. */ - if (likely(setJvmtiHookState(true))) { - /* Count object size on heap. */ - error = jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_EITHER, - &HeapObjectCallBack, NULL); + /* Enable JVMTI hooking. */ + if (likely(setJvmtiHookState(true))) { + /* Count object size on heap. */ + error = jvmti->IterateOverHeap(JVMTI_HEAP_OBJECT_EITHER, + &HeapObjectCallBack, NULL); - /* Disable JVMTI hooking. */ - setJvmtiHookState(false); - } + /* Disable JVMTI hooking. */ + setJvmtiHookState(false); + } - snapshotByJvmti = NULL; - } - EXIT_PTHREAD_SECTION(&jvmtiMutex) + snapshotByJvmti = NULL; } if (likely(error == JVMTI_ERROR_NONE)) { diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/snapShotProcessor.cpp --- a/agent/src/heapstats-engines/snapShotProcessor.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/snapShotProcessor.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file snapShotProcessor.cpp * \brief This file is used to output ranking and call snapshot function. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -69,12 +69,18 @@ bool existRemainder = false; /* Loop for agent run or remaining work exist. */ - while (!controller->_terminateRequest || existRemainder) { + while (true) { TSnapShotContainer *snapshot = NULL; /* Is notify flag. */ bool needProcess = false; - ENTER_PTHREAD_SECTION(&controller->mutex) { + { + TMutexLocker locker(&controller->mutex); + + if (controller->_terminateRequest && !existRemainder) { + break; + } + if (likely(controller->_numRequests == 0)) { /* Wait for notification or termination. */ pthread_cond_wait(&controller->mutexCond, &controller->mutex); @@ -93,7 +99,6 @@ /* Check remaining work. */ existRemainder = (controller->_numRequests > 0); } - EXIT_PTHREAD_SECTION(&controller->mutex) /* If waiting is finished by notification. */ if (needProcess && (snapshot != NULL)) { @@ -160,7 +165,9 @@ bool raiseException = true; /* Send notification and count notify. */ - ENTER_PTHREAD_SECTION(&this->mutex) { + { + TMutexLocker locker(&this->mutex); + try { /* Store and count data. */ snapQueue.push(snapshot); @@ -178,7 +185,6 @@ */ } } - EXIT_PTHREAD_SECTION(&this->mutex) if (unlikely(raiseException)) { throw "Failed to TSnapShotProcessor notify"; diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/timer.cpp --- a/agent/src/heapstats-engines/timer.cpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/timer.cpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file timer.cpp * \brief This file is used to take interval snapshot. - * Copyright (C) 2011-2015 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -72,11 +72,17 @@ controller->_isRunning = true; /* Loop for agent run. */ - while (!controller->_terminateRequest) { + while (true) { /* Reset timer interrupt flag. */ controller->_isInterrupted = false; - ENTER_PTHREAD_SECTION(&controller->mutex) { + { + TMutexLocker locker(&controller->mutex); + + if (controller->_terminateRequest) { + break; + } + /* Create limit datetime. */ struct timespec limitTs = {0}; struct timeval nowTv = {0}; @@ -89,7 +95,6 @@ pthread_cond_timedwait(&controller->mutexCond, &controller->mutex, &limitTs); } - EXIT_PTHREAD_SECTION(&controller->mutex) /* If waiting finished by timeout. */ if (!controller->_isInterrupted) { @@ -166,11 +171,10 @@ } else { /* Set interrupt flag and notify. */ - ENTER_PTHREAD_SECTION(&this->mutex) { - this->_isInterrupted = true; - pthread_cond_signal(&this->mutexCond); - } - EXIT_PTHREAD_SECTION(&this->mutex) + TMutexLocker locker(&this->mutex); + + this->_isInterrupted = true; + pthread_cond_signal(&this->mutexCond); } } diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/trapSender.hpp --- a/agent/src/heapstats-engines/trapSender.hpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/trapSender.hpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file trapSender.hpp * \brief This file is used to send SNMP trap. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -183,55 +183,47 @@ * \param port [in] Port used by SNMP trap. */ TTrapSender(int snmp, char *pPeer, char *pCommName, int port) { - /* Lock to use in multi-thread. */ - ENTER_PTHREAD_SECTION(&senderMutex) { + TMutexLocker locker(&senderMutex); - /* Disable NETSNMP logging. */ - netsnmp_register_loghandler(NETSNMP_LOGHANDLER_NONE, LOG_EMERG); + /* Disable NETSNMP logging. */ + netsnmp_register_loghandler(NETSNMP_LOGHANDLER_NONE, LOG_EMERG); - /* If snmp target is illegal. */ - if (pPeer == NULL) { - logger->printWarnMsg("Illegal SNMP target."); - pPdu = NULL; - } else { - /* Initialize session. */ - memset(&session, 0, sizeof(netsnmp_session)); - snmp_sess_init(&session); - session.version = snmp; - session.peername = strdup(pPeer); - session.remote_port = port; - session.community = (u_char *)strdup(pCommName); - session.community_len = (pCommName != NULL) ? strlen(pCommName) : 0; + /* If snmp target is illegal. */ + if (pPeer == NULL) { + logger->printWarnMsg("Illegal SNMP target."); + pPdu = NULL; + } else { + /* Initialize session. */ + memset(&session, 0, sizeof(netsnmp_session)); + snmp_sess_init(&session); + session.version = snmp; + session.peername = strdup(pPeer); + session.remote_port = port; + session.community = (u_char *)strdup(pCommName); + session.community_len = (pCommName != NULL) ? strlen(pCommName) : 0; - /* Make a PDU */ - pPdu = snmp_pdu_create(SNMP_MSG_TRAP2); - } + /* Make a PDU */ + pPdu = snmp_pdu_create(SNMP_MSG_TRAP2); } - /* Unlock to use in multi-thread. */ - EXIT_PTHREAD_SECTION(&senderMutex) } /*! * \brief TrapSender destructor. */ ~TTrapSender(void) { - /* Lock to use in multi-thread. */ - ENTER_PTHREAD_SECTION(&senderMutex) { + TMutexLocker locker(&senderMutex); - /* Clear Allocated str. */ - clearValues(); + /* Clear Allocated str. */ + clearValues(); - /* Free SNMP pdu. */ - if (pPdu != NULL) { - snmp_free_pdu(pPdu); - } - /* Close and free SNMP session. */ - snmp_close(&session); - free(session.peername); - free(session.community); + /* Free SNMP pdu. */ + if (pPdu != NULL) { + snmp_free_pdu(pPdu); } - /* Unlock to use in multi-thread. */ - EXIT_PTHREAD_SECTION(&senderMutex) + /* Close and free SNMP session. */ + snmp_close(&session); + free(session.peername); + free(session.community); } /*! diff -r 866500a172fa -r 3a15cfb00a39 agent/src/heapstats-engines/util.hpp --- a/agent/src/heapstats-engines/util.hpp Sun Apr 08 22:03:49 2018 +0900 +++ b/agent/src/heapstats-engines/util.hpp Sun Nov 10 00:26:38 2019 +0900 @@ -1,7 +1,7 @@ /*! * \file util.hpp * \brief This file is utilities. - * Copyright (C) 2011-2017 Nippon Telegraph and Telephone Corporation + * Copyright (C) 2011-2019 Nippon Telegraph and Telephone Corporation * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -25,9 +25,11 @@ #include #include +#include #include #include #include +#include /* Branch prediction. */ @@ -41,23 +43,23 @@ */ #define unlikely(x) __builtin_expect(!!(x), 0) -/* Critical section helper macro for pthread mutex. */ - /*! - * \brief Enter critical pthread section macro. + * \brief C++ class for pthread mutex. + * C'tor acquires mutex, and d'tor releases it. */ -#define ENTER_PTHREAD_SECTION(monitor) \ - if (unlikely(pthread_mutex_lock((monitor)) != 0)) { \ - logger->printWarnMsg("Entering mutex failed!"); \ - } else { -/*! - * \brief Exit critical pthread section macro. - */ -#define EXIT_PTHREAD_SECTION(monitor) \ - if (unlikely(pthread_mutex_unlock((monitor)) != 0)) { \ - logger->printWarnMsg("Exiting mutex failed!"); \ - } \ - } +class TMutexLocker { + private: + pthread_mutex_t *_mutex; + + public: + TMutexLocker(pthread_mutex_t *mutex) : _mutex(mutex) { + assert(pthread_mutex_lock(_mutex) == 0); + } + + ~TMutexLocker() { + assert(pthread_mutex_unlock(_mutex) == 0); + } +}; /*! * \brief Calculate align macro.