diff --git a/headers/private/system/thread_defs.h b/headers/private/system/thread_defs.h index c2cc881206..e2ba2ee9fb 100644 --- a/headers/private/system/thread_defs.h +++ b/headers/private/system/thread_defs.h @@ -28,9 +28,9 @@ enum { THREAD_BLOCK_TYPE_SIGNAL = 3, THREAD_BLOCK_TYPE_MUTEX = 4, THREAD_BLOCK_TYPE_RW_LOCK = 5, + THREAD_BLOCK_TYPE_USER = 6, THREAD_BLOCK_TYPE_OTHER = 9999, - THREAD_BLOCK_TYPE_USER_BASE = 10000 }; diff --git a/src/apps/debuganalyzer/model/Model.cpp b/src/apps/debuganalyzer/model/Model.cpp index fe1119ab7d..0151d92055 100644 --- a/src/apps/debuganalyzer/model/Model.cpp +++ b/src/apps/debuganalyzer/model/Model.cpp @@ -46,6 +46,8 @@ wait_object_type_name(uint32 type) return "mutex"; case THREAD_BLOCK_TYPE_RW_LOCK: return "rw lock"; + case THREAD_BLOCK_TYPE_USER: + return "user"; case THREAD_BLOCK_TYPE_OTHER: return "other"; case THREAD_BLOCK_TYPE_SNOOZE: diff --git a/src/bin/debug/time_stats/scheduling_analysis.cpp b/src/bin/debug/time_stats/scheduling_analysis.cpp index 6069f96d4e..1b66ed0a90 100644 --- a/src/bin/debug/time_stats/scheduling_analysis.cpp +++ b/src/bin/debug/time_stats/scheduling_analysis.cpp @@ -109,6 +109,9 @@ wait_object_to_string(scheduling_analysis_wait_object* waitObject, char* buffer, else sprintf(buffer, "rwlock %p (%s)", object, waitObject->name); break; + case THREAD_BLOCK_TYPE_USER: + strcpy(buffer, "user"); + break; case THREAD_BLOCK_TYPE_OTHER: sprintf(buffer, "other %p (%s)", object, waitObject->name); break; diff --git a/src/system/kernel/scheduler/scheduler_tracing.cpp b/src/system/kernel/scheduler/scheduler_tracing.cpp index f944c17f68..d7313ee4be 100644 --- a/src/system/kernel/scheduler/scheduler_tracing.cpp +++ b/src/system/kernel/scheduler/scheduler_tracing.cpp @@ -79,6 +79,9 @@ ScheduleThread::AddDump(TraceOutput& out) case THREAD_BLOCK_TYPE_RW_LOCK: out.Print("rwlock %p", fPreviousWaitObject); break; + case THREAD_BLOCK_TYPE_USER: + out.Print("_user_block_thread()"); + break; case THREAD_BLOCK_TYPE_OTHER: out.Print("other (%p)", fPreviousWaitObject); // We could print the string, but it might come from a diff --git a/src/system/kernel/thread.cpp b/src/system/kernel/thread.cpp index 77820c8961..bcbde99b96 100644 --- a/src/system/kernel/thread.cpp +++ b/src/system/kernel/thread.cpp @@ -1699,6 +1699,10 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("rwlock %p ", thread->wait.object); break; + case THREAD_BLOCK_TYPE_USER: + kprintf("user%*s", B_PRINTF_POINTER_WIDTH + 11, ""); + break; + case THREAD_BLOCK_TYPE_OTHER: kprintf("other%*s", B_PRINTF_POINTER_WIDTH + 10, ""); break; @@ -1782,6 +1786,10 @@ _dump_thread_info(Thread *thread, bool shortInfo) kprintf("rwlock %p\n", thread->wait.object); break; + case THREAD_BLOCK_TYPE_USER: + kprintf("user\n"); + break; + case THREAD_BLOCK_TYPE_OTHER: kprintf("other (%s)\n", (char*)thread->wait.object); break; @@ -2976,7 +2984,13 @@ user_unblock_thread(thread_id threadID, status_t status) if (thread->user_thread->wait_status > 0) { thread->user_thread->wait_status = status; clear_ac(); - thread_unblock_locked(thread, status); + + // Even if the user_thread->wait_status was > 0, it may be the + // case that this thread is actually blocked on something else. + if (thread->state == B_THREAD_WAITING + && thread->wait.type == THREAD_BLOCK_TYPE_USER) { + thread_unblock_locked(thread, status); + } } else clear_ac(); @@ -3715,7 +3729,7 @@ _user_block_thread(uint32 flags, bigtime_t timeout) clear_ac(); // nope, so wait - thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_OTHER, "user"); + thread_prepare_to_block(thread, flags, THREAD_BLOCK_TYPE_USER, NULL); threadLocker.Unlock();