From 14b62ae4dafb0bed95849aedef783268aa278a66 Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Sat, 27 Jul 2019 15:23:44 -0400 Subject: [PATCH] BFS: Make the log-flusher thread persistent. Previously, a new log-flush thread was created every time there was an idle transaction. Now we just release a semaphore for an already-existing thread. Change-Id: If788dbe17ef8e069ce12aa7b778626d051cce2d0 --- .../kernel/file_systems/bfs/Journal.cpp | 31 ++++++++++++++----- src/add-ons/kernel/file_systems/bfs/Journal.h | 5 ++- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.cpp b/src/add-ons/kernel/file_systems/bfs/Journal.cpp index 255ba42c4b..5377f30ae1 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.cpp +++ b/src/add-ons/kernel/file_systems/bfs/Journal.cpp @@ -409,6 +409,12 @@ Journal::Journal(Volume* volume) { recursive_lock_init(&fLock, "bfs journal"); mutex_init(&fEntriesLock, "bfs journal entries"); + + fLogFlusherSem = create_sem(0, "bfs log flusher"); + fLogFlusher = spawn_kernel_thread(&Journal::_LogFlusher, "bfs log flusher", + B_NORMAL_PRIORITY, this); + if (fLogFlusher > 0) + resume_thread(fLogFlusher); } @@ -418,6 +424,11 @@ Journal::~Journal() recursive_lock_destroy(&fLock); mutex_destroy(&fEntriesLock); + + sem_id logFlusher = fLogFlusherSem; + fLogFlusherSem = -1; + delete_sem(logFlusher); + wait_for_thread(fLogFlusher, NULL); } @@ -685,20 +696,24 @@ Journal::_TransactionWritten(int32 transactionID, int32 event, void* _logEntry) /*static*/ void Journal::_TransactionIdle(int32 transactionID, int32 event, void* _journal) { - // The current transaction seems to be idle - flush it. We can't do this - // in this thread, as flushing the log can produce new transaction events. - thread_id id = spawn_kernel_thread(&Journal::_FlushLog, "bfs log flusher", - B_NORMAL_PRIORITY, _journal); - if (id > 0) - resume_thread(id); + // The current transaction seems to be idle - flush it. (We can't do this + // in this thread, as flushing the log can produce new transaction events.) + Journal* journal = (Journal*)_journal; + release_sem(journal->fLogFlusherSem); } /*static*/ status_t -Journal::_FlushLog(void* _journal) +Journal::_LogFlusher(void* _journal) { Journal* journal = (Journal*)_journal; - return journal->_FlushLog(false, false); + while (journal->fLogFlusherSem >= 0) { + if (acquire_sem(journal->fLogFlusherSem) != B_OK) + continue; + + journal->_FlushLog(false, false); + } + return B_OK; } diff --git a/src/add-ons/kernel/file_systems/bfs/Journal.h b/src/add-ons/kernel/file_systems/bfs/Journal.h index 6e22ad0a81..3d71a42ac4 100644 --- a/src/add-ons/kernel/file_systems/bfs/Journal.h +++ b/src/add-ons/kernel/file_systems/bfs/Journal.h @@ -60,7 +60,7 @@ private: int32 event, void* _logEntry); static void _TransactionIdle(int32 transactionID, int32 event, void* _journal); - static status_t _FlushLog(void* _journal); + static status_t _LogFlusher(void* _journal); private: Volume* fVolume; @@ -76,6 +76,9 @@ private: int32 fTransactionID; bool fHasSubtransaction; bool fSeparateSubTransactions; + + thread_id fLogFlusher; + sem_id fLogFlusherSem; };