Path: blob/main/system/lib/pthread/thread_profiler.c
6171 views
/*1* Copyright 2021 The Emscripten Authors. All rights reserved.2* Emscripten is available under two separate licenses, the MIT license and the3* University of Illinois/NCSA Open Source License. Both these licenses can be4* found in the LICENSE file.5*/67#include <assert.h>8#include <string.h>9#include <stdbool.h>10#include "pthread_impl.h"11#include <emscripten/threading.h>12#include <emscripten/heap.h>1314static bool enabled = false;1516#ifndef NDEBUG1718void _emscripten_thread_profiler_init(pthread_t thread) {19assert(thread);20if (!enabled) {21return;22}23thread->profilerBlock = emscripten_builtin_malloc(sizeof(thread_profiler_block));24memset(thread->profilerBlock, 0, sizeof(thread_profiler_block));25thread->profilerBlock->currentStatusStartTime = emscripten_get_now();26}2728// Sets the current thread status, but only if it was in the given expected29// state before. This is used to allow high-level control flow "override" the30// thread status before low-level (futex wait) operations set it.31static void set_status_conditional(int expectedStatus, int newStatus) {32if (!enabled) {33return;34}35pthread_t thread = pthread_self();36if (!thread) return; // AudioWorklets do not have a pthread block, but if user calls emscripten_futex_wait() in an AudioWorklet, it will call here via emscripten_set_current_thread_status().37int prevStatus = thread->profilerBlock->threadStatus;3839if (prevStatus != newStatus && (prevStatus == expectedStatus || expectedStatus == -1)) {40double now = emscripten_get_now();41double startState = thread->profilerBlock->currentStatusStartTime;42double duration = now - startState;4344thread->profilerBlock->timeSpentInStatus[prevStatus] += duration;45thread->profilerBlock->threadStatus = newStatus;46thread->profilerBlock->currentStatusStartTime = now;47}48}4950void emscripten_conditional_set_current_thread_status(int expectedStatus, int newStatus) {51set_status_conditional(expectedStatus, newStatus);52}5354void emscripten_set_current_thread_status(int newStatus) {55set_status_conditional(-1, newStatus);56}5758void _emscripten_thread_profiler_enable() {59enabled = true;60_emscripten_thread_profiler_init(pthread_self());61emscripten_set_thread_name(pthread_self(), "Browser main thread");62}6364#endif6566void emscripten_set_thread_name(pthread_t thread, const char* name) {67if (!enabled) {68return;69}70strncpy(thread->profilerBlock->name, name, EM_THREAD_NAME_MAX-1);71}727374