{"version":3,"file":"Threads.js","sourceRoot":"","sources":["../../../../../../../front_end/models/trace/handlers/Threads.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2023 The Chromium Authors. All rights reserved.\n// Use of this source code is governed by a BSD-style license that can be\n// found in the LICENSE file.\n//\nimport type * as Helpers from '../helpers/helpers.js';\nimport type * as Types from '../types/types.js';\n\nimport type {AuctionWorkletsData} from './AuctionWorkletsHandler.js';\nimport type * as Renderer from './RendererHandler.js';\nimport type {ParsedTrace} from './types.js';\n\nexport interface ThreadData {\n pid: Types.Events.ProcessID;\n tid: Types.Events.ThreadID;\n entries: readonly Types.Events.Event[];\n processIsOnMainFrame: boolean;\n tree: Helpers.TreeHelpers.TraceEntryTree;\n type: ThreadType;\n name: string|null;\n entryToNode: Map;\n}\n\nexport enum ThreadType {\n MAIN_THREAD = 'MAIN_THREAD',\n WORKER = 'WORKER',\n RASTERIZER = 'RASTERIZER',\n AUCTION_WORKLET = 'AUCTION_WORKLET',\n OTHER = 'OTHER',\n CPU_PROFILE = 'CPU_PROFILE',\n THREAD_POOL = 'THREAD_POOL',\n}\n\nfunction getThreadTypeForRendererThread(\n pid: Types.Events.ProcessID, thread: Renderer.RendererThread,\n auctionWorkletsData: AuctionWorkletsData): ThreadType {\n let threadType = ThreadType.OTHER;\n if (thread.name === 'CrRendererMain') {\n threadType = ThreadType.MAIN_THREAD;\n } else if (thread.name === 'DedicatedWorker thread') {\n threadType = ThreadType.WORKER;\n } else if (thread.name?.startsWith('CompositorTileWorker')) {\n threadType = ThreadType.RASTERIZER;\n } else if (auctionWorkletsData.worklets.has(pid)) {\n threadType = ThreadType.AUCTION_WORKLET;\n } else if (thread.name?.startsWith('ThreadPool')) {\n // TODO(paulirish): perhaps exclude ThreadPoolServiceThread entirely\n threadType = ThreadType.THREAD_POOL;\n }\n return threadType;\n}\n\nexport function threadsInRenderer(\n rendererData: Renderer.RendererHandlerData, auctionWorkletsData: AuctionWorkletsData): readonly ThreadData[] {\n const foundThreads: ThreadData[] = [];\n // If we have Renderer threads, we prefer to use those. In the event that a\n // trace is a CPU Profile trace, we will never have Renderer threads, so we\n // know if there are no Renderer threads that we can fallback to using the\n // data from the SamplesHandler.\n if (rendererData.processes.size) {\n for (const [pid, process] of rendererData.processes) {\n for (const [tid, thread] of process.threads) {\n if (!thread.tree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n const threadType = getThreadTypeForRendererThread(pid, thread, auctionWorkletsData);\n foundThreads.push({\n name: thread.name,\n pid,\n tid,\n processIsOnMainFrame: process.isOnMainFrame,\n entries: thread.entries,\n tree: thread.tree,\n type: threadType,\n entryToNode: rendererData.entryToNode,\n });\n }\n }\n }\n return foundThreads;\n}\n\nconst threadsInTraceCache = new WeakMap();\n\n/**\n * Given trace parsed data, this helper will return a high level array of\n * ThreadData. This is useful because it allows you to get a list of threads\n * regardless of if the trace is a CPU Profile or a Tracing profile. Thus you\n * can use this helper to iterate over threads in confidence that it will work\n * for both trace types.\n * The resulting data is cached per-trace, so you can safely call this multiple times.\n */\nexport function threadsInTrace(parsedTrace: ParsedTrace): readonly ThreadData[] {\n const cached = threadsInTraceCache.get(parsedTrace);\n if (cached) {\n return cached;\n }\n\n // If we have Renderer threads, we prefer to use those.\n const threadsFromRenderer = threadsInRenderer(parsedTrace.Renderer, parsedTrace.AuctionWorklets);\n if (threadsFromRenderer.length) {\n threadsInTraceCache.set(parsedTrace, threadsFromRenderer);\n return threadsFromRenderer;\n }\n\n // If it's a CPU Profile trace, there will be no Renderer threads.\n // We can fallback to using the data from the SamplesHandler.\n const foundThreads: ThreadData[] = [];\n if (parsedTrace.Samples.profilesInProcess.size) {\n for (const [pid, process] of parsedTrace.Samples.profilesInProcess) {\n for (const [tid, thread] of process) {\n if (!thread.profileTree) {\n // Drop threads where we could not create the tree; this indicates\n // unexpected data and we won't be able to support all the UI\n // filtering we need.\n continue;\n }\n\n foundThreads.push({\n pid,\n tid,\n // CPU Profile threads do not have a name.\n name: null,\n entries: thread.profileCalls,\n // There is no concept of a \"Main Frame\" in a CPU profile.\n processIsOnMainFrame: false,\n tree: thread.profileTree,\n type: ThreadType.CPU_PROFILE,\n entryToNode: parsedTrace.Samples.entryToNode,\n });\n }\n }\n }\n\n threadsInTraceCache.set(parsedTrace, foundThreads);\n return foundThreads;\n}\n"]}