diff --git a/services/hilogd/include/log_buffer.h b/services/hilogd/include/log_buffer.h index a0ad2ddd411cfd4c00602a320838211db9e5717c..e9d611f4fa2103b081a18d1b27cb45b956623e01 100644 --- a/services/hilogd/include/log_buffer.h +++ b/services/hilogd/include/log_buffer.h @@ -47,8 +47,6 @@ public: int32_t GetStatisticInfoByDomain(uint32_t domain, uint64_t& printLen, uint64_t& cacheLen, int32_t& dropped); int32_t ClearStatisticInfoByLog(uint16_t logType); int32_t ClearStatisticInfoByDomain(uint32_t domain); - void GetBufferLock(); - void ReleaseBufferLock(); private: size_t size; size_t sizeByType[LOG_TYPE_MAX]; diff --git a/services/hilogd/log_buffer.cpp b/services/hilogd/log_buffer.cpp index 7a4e68356ffef06eca30dca42505de73a323fc4c..58ef43db39f043f4c08362b73c567613a61d989f 100644 --- a/services/hilogd/log_buffer.cpp +++ b/services/hilogd/log_buffer.cpp @@ -62,36 +62,38 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) // Delete old entries when full if (eleSize + sizeByType[msg.type] >= (size_t)g_maxBufferSizeByType[msg.type]) { - hilogBufferMutex.lock(); - // Drop 5% of maximum log when full - std::list::iterator it = hilogDataList.begin(); - while (sizeByType[msg.type] > g_maxBufferSizeByType[msg.type] * (1 - DROP_RATIO) && - it != hilogDataList.end()) { - if ((*it).type != msg.type) { // Only remove old logs of the same type - ++it; - continue; - } - logReaderListMutex.lock_shared(); - for (auto &itr :logReaderList) { - if (itr.lock()->readPos == it) { - itr.lock()->readPos = std::next(it); + { + std::scoped_lock lock(hilogBufferMutex); + // Drop 5% of maximum log when full + std::list::iterator it = hilogDataList.begin(); + while (sizeByType[msg.type] > g_maxBufferSizeByType[msg.type] * (1 - DROP_RATIO) && + it != hilogDataList.end()) { + if ((*it).type != msg.type) { // Only remove old logs of the same type + ++it; + continue; } - if (itr.lock()->lastPos == it) { - itr.lock()->lastPos = std::next(it); + { + std::shared_lock readerListLock(logReaderListMutex); + for (auto &itr :logReaderList) { + if (itr.lock()->readPos == it) { + itr.lock()->readPos = std::next(it); + } + if (itr.lock()->lastPos == it) { + itr.lock()->lastPos = std::next(it); + } + } } + size_t cLen = it->len - it->tag_len; + size -= cLen; + sizeByType[(*it).type] -= cLen; + it = hilogDataList.erase(it); } - logReaderListMutex.unlock_shared(); - size_t cLen = it->len - it->tag_len; - size -= cLen; - sizeByType[(*it).type] -= cLen; - it = hilogDataList.erase(it); - } - // Re-confirm if enough elements has been removed - if (sizeByType[msg.type] >= (size_t)g_maxBufferSizeByType[msg.type]) { - std::cout << "Failed to clean old logs." << std::endl; + // Re-confirm if enough elements has been removed + if (sizeByType[msg.type] >= (size_t)g_maxBufferSizeByType[msg.type]) { + std::cout << "Failed to clean old logs." << std::endl; + } } - hilogBufferMutex.unlock(); } // Insert new log into HilogBuffer @@ -102,13 +104,14 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) // Find the place with right timestamp ++rit; for (; rit != hilogDataList.rend() && msg.tv_sec < rit->tv_sec; ++rit) { - logReaderListMutex.lock_shared(); - for (auto &itr :logReaderList) { - if (itr.lock()->readPos == std::prev(rit.base())) { - itr.lock()->oldData.emplace_front(msg); + { + std::shared_lock readerListLock(logReaderListMutex); + for (auto &itr :logReaderList) { + if (itr.lock()->readPos == std::prev(rit.base())) { + itr.lock()->oldData.emplace_front(msg); + } } } - logReaderListMutex.unlock_shared(); } hilogDataList.emplace(rit.base(), msg); } @@ -127,54 +130,53 @@ size_t HilogBuffer::Insert(const HilogMsg& msg) bool HilogBuffer::Query(std::shared_ptr reader) { - hilogBufferMutex.lock_shared(); - if (reader->GetReload()) { - reader->readPos = hilogDataList.begin(); - reader->lastPos = hilogDataList.begin(); - reader->SetReload(false); - } - - if (reader->isNotified) { - if (reader->readPos == hilogDataList.end()) { - reader->readPos = std::next(reader->lastPos); + { + std::shared_lock lock(hilogBufferMutex); + if (reader->GetReload()) { + reader->readPos = hilogDataList.begin(); + reader->lastPos = hilogDataList.begin(); + reader->SetReload(false); } - } - // Look up in oldData first - if (!reader->oldData.empty()) { - reader->SetSendId(SENDIDA); - reader->WriteData(&(reader->oldData.back())); - printLenByType[(reader->oldData.back()).type] += strlen(reader->oldData.back().content); - if (printLenByDomain.count(reader->oldData.back().domain) == 0) { - printLenByDomain.insert(pair(reader->oldData.back().domain, - strlen(reader->oldData.back().content))); - } else { - printLenByDomain[reader->oldData.back().domain] += strlen(reader->oldData.back().content); + + if (reader->isNotified) { + if (reader->readPos == hilogDataList.end()) { + reader->readPos = std::next(reader->lastPos); + } } - reader->oldData.pop_back(); - hilogBufferMutex.unlock_shared(); - return true; - } - while (reader->readPos != hilogDataList.end()) { - reader->lastPos = reader->readPos; - if (ConditionMatch(reader)) { + // Look up in oldData first + if (!reader->oldData.empty()) { reader->SetSendId(SENDIDA); - reader->WriteData(&*(reader->readPos)); - printLenByType[reader->readPos->type] += strlen(reader->readPos->content); - if (printLenByDomain.count(reader->readPos->domain) == 0) { - printLenByDomain.insert(pair(reader->readPos->domain, - strlen(reader->readPos->content))); + reader->WriteData(&(reader->oldData.back())); + printLenByType[(reader->oldData.back()).type] += strlen(reader->oldData.back().content); + if (printLenByDomain.count(reader->oldData.back().domain) == 0) { + printLenByDomain.insert(pair(reader->oldData.back().domain, + strlen(reader->oldData.back().content))); } else { - printLenByDomain[reader->readPos->domain] += strlen(reader->readPos->content); + printLenByDomain[reader->oldData.back().domain] += strlen(reader->oldData.back().content); } - reader->readPos++; - hilogBufferMutex.unlock_shared(); + reader->oldData.pop_back(); return true; } - reader->readPos++; + while (reader->readPos != hilogDataList.end()) { + reader->lastPos = reader->readPos; + if (ConditionMatch(reader)) { + reader->SetSendId(SENDIDA); + reader->WriteData(&*(reader->readPos)); + printLenByType[reader->readPos->type] += strlen(reader->readPos->content); + if (printLenByDomain.count(reader->readPos->domain) == 0) { + printLenByDomain.insert(pair(reader->readPos->domain, + strlen(reader->readPos->content))); + } else { + printLenByDomain[reader->readPos->domain] += strlen(reader->readPos->content); + } + reader->readPos++; + return true; + } + reader->readPos++; + } + reader->isNotified = false; + ReturnNoLog(reader); } - reader->isNotified = false; - ReturnNoLog(reader); - hilogBufferMutex.unlock_shared(); return false; } @@ -184,60 +186,62 @@ size_t HilogBuffer::Delete(uint16_t logType) return ERR_LOG_TYPE_INVALID; } size_t sum = 0; - hilogBufferMutex.lock(); - std::list::iterator it = hilogDataList.begin(); + { + std::scoped_lock lock(hilogBufferMutex); + std::list::iterator it = hilogDataList.begin(); - // Delete logs corresponding to queryCondition - while (it != hilogDataList.end()) { - // Only remove old logs of the same type - if ((*it).type != logType) { - ++it; - continue; - } - // Delete corresponding logs - logReaderListMutex.lock_shared(); - for (auto itr = logReaderList.begin(); itr != logReaderList.end();) { - if ((*itr).lock()->readPos == it) { - (*itr).lock()->readPos = std::next(it); + // Delete logs corresponding to queryCondition + while (it != hilogDataList.end()) { + // Only remove old logs of the same type + if ((*it).type != logType) { + ++it; + continue; + } + // Delete corresponding logs + { + std::shared_lock readerListLock(logReaderListMutex); + for (auto itr = logReaderList.begin(); itr != logReaderList.end();) { + if ((*itr).lock()->readPos == it) { + (*itr).lock()->readPos = std::next(it); + } + if ((*itr).lock()->lastPos == it) { + (*itr).lock()->lastPos = std::next(it); + } + ++itr; } - if ((*itr).lock()->lastPos == it) { - (*itr).lock()->lastPos = std::next(it); } - ++itr; + size_t cLen = it->len - it->tag_len; + sum += cLen; + sizeByType[(*it).type] -= cLen; + size -= cLen; + it = hilogDataList.erase(it); } - logReaderListMutex.unlock_shared(); - - size_t cLen = it->len - it->tag_len; - sum += cLen; - sizeByType[(*it).type] -= cLen; - size -= cLen; - it = hilogDataList.erase(it); } - - hilogBufferMutex.unlock(); return sum; } void HilogBuffer::AddLogReader(std::weak_ptr reader) { - logReaderListMutex.lock(); - // If reader not in logReaderList - logReaderList.push_back(reader); - reader.lock()->lastPos = hilogDataList.end(); - logReaderListMutex.unlock(); + { + std::scoped_lock readerListLock(logReaderListMutex); + // If reader not in logReaderList + logReaderList.push_back(reader); + reader.lock()->lastPos = hilogDataList.end(); + } } void HilogBuffer::RemoveLogReader(std::shared_ptr reader) { - logReaderListMutex.lock(); - const auto findIter = std::find_if(logReaderList.begin(), logReaderList.end(), - [&reader](const std::weak_ptr& ptr0) { - return ptr0.lock() == reader; - }); - if (findIter != logReaderList.end()) { - logReaderList.erase(findIter); + { + std::scoped_lock readerListLock(logReaderListMutex); + const auto findIter = std::find_if(logReaderList.begin(), logReaderList.end(), + [&reader](const std::weak_ptr& ptr0) { + return ptr0.lock() == reader; + }); + if (findIter != logReaderList.end()) { + logReaderList.erase(findIter); + } } - logReaderListMutex.unlock(); } bool HilogBuffer::Query(LogReader* reader) @@ -262,41 +266,43 @@ size_t HilogBuffer::SetBuffLen(uint16_t logType, uint64_t buffSize) if (buffSize <= 0 || buffSize > MAX_BUFFER_SIZE) { return ERR_BUFF_SIZE_INVALID; } - hilogBufferMutex.lock(); - if (sizeByType[logType] > buffSize) { - // Drop old log when buffsize not enough - std::list::iterator it = hilogDataList.begin(); - while (sizeByType[logType] > buffSize && it != hilogDataList.end()) { - if ((*it).type != logType) { // Only remove old logs of the same type - ++it; - continue; - } - logReaderListMutex.lock_shared(); - for (auto &itr :logReaderList) { - if (itr.lock()->readPos == it) { - itr.lock()->readPos = std::next(it); + { + std::scoped_lock lock(hilogBufferMutex); + if (sizeByType[logType] > buffSize) { + // Drop old log when buffsize not enough + std::list::iterator it = hilogDataList.begin(); + while (sizeByType[logType] > buffSize && it != hilogDataList.end()) { + if ((*it).type != logType) { // Only remove old logs of the same type + ++it; + continue; } - if (itr.lock()->lastPos == it) { - itr.lock()->lastPos = std::next(it); + { + std::shared_lock readerListLock(logReaderListMutex); + for (auto &itr :logReaderList) { + if (itr.lock()->readPos == it) { + itr.lock()->readPos = std::next(it); + } + if (itr.lock()->lastPos == it) { + itr.lock()->lastPos = std::next(it); + } + } } + size_t cLen = it->len - it->tag_len; + size -= cLen; + sizeByType[(*it).type] -= cLen; + it = hilogDataList.erase(it); } - logReaderListMutex.unlock_shared(); - size_t cLen = it->len - it->tag_len; - size -= cLen; - sizeByType[(*it).type] -= cLen; - it = hilogDataList.erase(it); - } - // Re-confirm if enough elements has been removed - if (sizeByType[logType] > (size_t)g_maxBufferSizeByType[logType] || size > (size_t)g_maxBufferSize) { - return ERR_BUFF_SIZE_EXP; + // Re-confirm if enough elements has been removed + if (sizeByType[logType] > (size_t)g_maxBufferSizeByType[logType] || size > (size_t)g_maxBufferSize) { + return ERR_BUFF_SIZE_EXP; + } + g_maxBufferSizeByType[logType] = buffSize; + g_maxBufferSize += (buffSize - sizeByType[logType]); + } else { + g_maxBufferSizeByType[logType] = buffSize; + g_maxBufferSize += (buffSize - sizeByType[logType]); } - g_maxBufferSizeByType[logType] = buffSize; - g_maxBufferSize += (buffSize - sizeByType[logType]); - } else { - g_maxBufferSizeByType[logType] = buffSize; - g_maxBufferSize += (buffSize - sizeByType[logType]); } - hilogBufferMutex.unlock(); return buffSize; } @@ -416,15 +422,5 @@ void HilogBuffer::ReturnNoLog(std::shared_ptr reader) reader->SetSendId(SENDIDN); reader->WriteData(nullptr); } - -void HilogBuffer::GetBufferLock() -{ - hilogBufferMutex.lock(); -} - -void HilogBuffer::ReleaseBufferLock() -{ - hilogBufferMutex.unlock(); -} } // namespace HiviewDFX } // namespace OHOS diff --git a/services/hilogd/log_collector.cpp b/services/hilogd/log_collector.cpp index dfb974a5279a22269999c0ff27b57c802eddbd14..11b6ee6061f5fc6430c219c5d5d413a91ad5dc75 100644 --- a/services/hilogd/log_collector.cpp +++ b/services/hilogd/log_collector.cpp @@ -99,15 +99,17 @@ size_t LogCollector::InsertLogToBuffer(const HilogMsg& msg) if (result <= 0) { return result; } - m_hilogBuffer->logReaderListMutex.lock_shared(); - auto it = m_hilogBuffer->logReaderList.begin(); - while (it != m_hilogBuffer->logReaderList.end()) { - if ((*it).lock()->GetType() != TYPE_CONTROL) { - (*it).lock()->NotifyForNewData(); + + { + std::shared_lock readerListLock(m_hilogBuffer->logReaderListMutex); + auto it = m_hilogBuffer->logReaderList.begin(); + while (it != m_hilogBuffer->logReaderList.end()) { + if ((*it).lock()->GetType() != TYPE_CONTROL) { + (*it).lock()->NotifyForNewData(); + } + ++it; } - ++it; } - m_hilogBuffer->logReaderListMutex.unlock_shared(); return result; } } // namespace HiviewDFX