Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
pavelsavara committed Feb 18, 2024
1 parent d7acf9c commit c930a99
Showing 28 changed files with 264 additions and 217 deletions.
3 changes: 2 additions & 1 deletion src/mono/browser/runtime/assets.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import type { AssetEntryInternal } from "./types/internal";

import cwraps from "./cwraps";
import { mono_wasm_load_icu_data } from "./icu";
import { Module, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
import { mono_log_info, mono_log_debug, parseSymbolMapFile } from "./logging";
import { mono_wasm_load_bytes_into_heap } from "./memory";
import { endMeasure, MeasuredBlock, startMeasure } from "./profiler";
import { AssetEntryInternal } from "./types/internal";
import { AssetEntry } from "./types";
import { VoidPtr } from "./types/emscripten";
import { setSegmentationRulesFromJson } from "./hybrid-globalization/grapheme-segmenter";
3 changes: 1 addition & 2 deletions src/mono/browser/runtime/cwraps.ts
Original file line number Diff line number Diff line change
@@ -6,13 +6,12 @@ import WasmEnableThreads from "consts:wasmEnableThreads";
import type {
MonoAssembly, MonoClass,
MonoMethod, MonoObject,
MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments
MonoType, MonoObjectRef, MonoStringRef, JSMarshalerArguments, PThreadPtr
} from "./types/internal";
import type { VoidPtr, CharPtrPtr, Int32Ptr, CharPtr, ManagedPointer } from "./types/emscripten";
import { Module, runtimeHelpers } from "./globals";
import { mono_log_error } from "./logging";
import { mono_assert } from "./globals";
import { PThreadPtr } from "./pthreads/shared/types";

type SigLine = [lazyOrSkip: boolean | (() => boolean), name: string, returnType: string | null, argTypes?: string[], opts?: any];

1 change: 1 addition & 0 deletions src/mono/browser/runtime/debug.ts
Original file line number Diff line number Diff line change
@@ -2,6 +2,7 @@
// The .NET Foundation licenses this file to you under the MIT license.

import BuildConfiguration from "consts:configuration";

import { INTERNAL, Module, loaderHelpers, runtimeHelpers } from "./globals";
import { toBase64StringImpl } from "./base64";
import cwraps from "./cwraps";
4 changes: 2 additions & 2 deletions src/mono/browser/runtime/diagnostics/browser/controller.ts
Original file line number Diff line number Diff line change
@@ -7,10 +7,10 @@ import { threads_c_functions as cwraps } from "../../cwraps";
import { INTERNAL, mono_assert } from "../../globals";
import { mono_log_info, mono_log_debug, mono_log_warn } from "../../logging";
import { withStackAlloc, getI32 } from "../../memory";
import { Thread, waitForThread } from "../../pthreads/browser";
import { waitForThread } from "../../pthreads/browser";
import { isDiagnosticMessage, makeDiagnosticServerControlCommand } from "../shared/controller-commands";
import monoDiagnosticsMock from "consts:monoDiagnosticsMock";
import { PThreadPtr } from "../../pthreads/shared/types";
import { PThreadPtr, Thread } from "../../types/internal";

/// An object that can be used to control the diagnostic server.
export interface ServerController {
9 changes: 3 additions & 6 deletions src/mono/browser/runtime/diagnostics/index.ts
Original file line number Diff line number Diff line change
@@ -37,12 +37,9 @@ let diagnosticsServerEnabled = false;
let diagnosticsInitialized = false;

export async function mono_wasm_init_diagnostics(): Promise<void> {
if (diagnosticsInitialized)
return;
if (!WasmEnableThreads) {
mono_log_warn("ignoring diagnostics options because this runtime does not support diagnostics");
return;
}
if (!WasmEnableThreads) return;
if (diagnosticsInitialized) return;

const options = diagnostic_options_from_environment();
if (!options)
return;
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import type { MonoThreadMessage } from "../../pthreads/shared";
import { isMonoThreadMessage } from "../../pthreads/shared";
import type { MonoThreadMessage } from "../../types/internal";

// Messages from the main thread to the diagnostic server thread
export interface DiagnosticMessage extends MonoThreadMessage {
4 changes: 4 additions & 0 deletions src/mono/browser/runtime/dotnet.d.ts
Original file line number Diff line number Diff line change
@@ -190,6 +190,10 @@ type MonoConfig = {
* initial number of workers to add to the emscripten pthread pool
*/
pthreadPoolSize?: number;
/**
* initial number of unused workers keep in the emscripten pthread pool after startup
*/
pthreadPoolReady?: number;
/**
* If true, a list of the methods optimized by the interpreter will be saved and used for faster startup
* on future runs of the application
10 changes: 7 additions & 3 deletions src/mono/browser/runtime/exports-internal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import WasmEnableThreads from "consts:wasmEnableThreads";

import { MonoObjectNull, type MonoObject } from "./types/internal";
import cwraps, { profiler_c_functions } from "./cwraps";
import { mono_wasm_send_dbg_command_with_parms, mono_wasm_send_dbg_command, mono_wasm_get_dbg_command_info, mono_wasm_get_details, mono_wasm_release_object, mono_wasm_call_function_on, mono_wasm_debugger_resume, mono_wasm_detach_debugger, mono_wasm_raise_debug_event, mono_wasm_change_debugger_log_level, mono_wasm_debugger_attached } from "./debug";
import { http_wasm_supports_streaming_request, http_wasm_supports_streaming_response, http_wasm_create_controller, http_wasm_abort_request, http_wasm_abort_response, http_wasm_transform_stream_write, http_wasm_transform_stream_close, http_wasm_fetch, http_wasm_fetch_stream, http_wasm_fetch_bytes, http_wasm_get_response_header_names, http_wasm_get_response_header_values, http_wasm_get_response_bytes, http_wasm_get_response_length, http_wasm_get_streamed_response_bytes, http_wasm_get_response_type, http_wasm_get_response_status } from "./http";
@@ -17,16 +20,17 @@ import { loadLazyAssembly } from "./lazyLoading";
import { loadSatelliteAssemblies } from "./satelliteAssemblies";
import { forceDisposeProxies } from "./gc-handles";
import { mono_wasm_get_func_id_to_name_mappings } from "./logging";
import { MonoObject, MonoObjectNull } from "./types/internal";
import { monoStringToStringUnsafe } from "./strings";
import { thread_available } from "./pthreads/browser";
import { mono_wasm_bind_cs_function } from "./invoke-cs";

import { dumpThreads, thread_available } from "./pthreads/browser";

export function export_internal(): any {
return {
// tests
mono_wasm_exit: (exit_code: number) => { Module.err("early exit " + exit_code); },
forceDisposeProxies,
dumpThreads: WasmEnableThreads ? dumpThreads : undefined,

// with mono_wasm_debugger_log and mono_wasm_trace_logger
logging: undefined,
@@ -57,7 +61,7 @@ export function export_internal(): any {
get_global_this,
get_dotnet_instance: () => exportedRuntimeAPI,
dynamic_import,
thread_available,
thread_available: WasmEnableThreads ? thread_available : undefined,
mono_wasm_bind_cs_function,

// BrowserWebSocket
4 changes: 4 additions & 0 deletions src/mono/browser/runtime/exports.ts
Original file line number Diff line number Diff line change
@@ -70,6 +70,10 @@ function initializeExports(globalObjects: GlobalObjects): RuntimeAPI {
runtimeList = globalThisAny.getDotnetRuntime.__list;
}

if (BuildConfiguration === "Debug") {
globalThisAny.INTERNAL = globals.internal;
}

return exportedRuntimeAPI;
}

1 change: 1 addition & 0 deletions src/mono/browser/runtime/interp-pgo.ts
Original file line number Diff line number Diff line change
@@ -198,6 +198,7 @@ export async function getCacheKey(prefix: string): Promise<string | null> {
delete inputs.dumpThreadsOnNonZeroExit;
delete inputs.logExitCode;
delete inputs.pthreadPoolSize;
delete inputs.pthreadPoolReady;
delete inputs.asyncFlushOnExit;
delete inputs.remoteSources;
delete inputs.ignorePdbLoadErrors;
22 changes: 21 additions & 1 deletion src/mono/browser/runtime/loader/assets.ts
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@

import WasmEnableThreads from "consts:wasmEnableThreads";

import type { AssetEntryInternal, PromiseAndController } from "../types/internal";
import { PThreadPtrNull, type AssetEntryInternal, type PThreadWorker, type PromiseAndController } from "../types/internal";
import type { AssetBehaviors, AssetEntry, LoadingResource, ResourceList, SingleAssetBehaviors as SingleAssetBehaviors, WebAssemblyBootResourceType } from "../types";
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_SHELL, ENVIRONMENT_IS_WEB, loaderHelpers, mono_assert, runtimeHelpers } from "./globals";
import { createPromiseController } from "./promise-controller";
@@ -733,4 +733,24 @@ export async function streamingCompileWasm() {
catch (err) {
loaderHelpers.wasmCompilePromise.promise_control.reject(err);
}
}

export function preloadWorkers() {
if (!WasmEnableThreads) return;
const jsModuleWorker = resolve_single_asset_path("js-module-threads");
for (let i = 0; i < loaderHelpers.config.pthreadPoolSize!; i++) {
const workerNumber = loaderHelpers.workerNextNumber++;
const worker: Partial<PThreadWorker> = new Worker(jsModuleWorker.resolvedUrl!, {
name: "dotnet-worker-" + workerNumber.toString().padStart(3, "0"),
});
worker.info = {
workerNumber,
pthreadId: PThreadPtrNull,
reuseCount: 0,
updateCount: 0,
threadPrefix: " - ",
threadName: "emscripten-pool",
} as any;
loaderHelpers.loadingWorkers.push(worker as any);
}
}
5 changes: 4 additions & 1 deletion src/mono/browser/runtime/loader/config.ts
Original file line number Diff line number Diff line change
@@ -187,10 +187,13 @@ export function normalizeConfig() {
config.cachedResourcesPurgeDelay = 10000;
}

// ActiveIssue https://github.com/dotnet/runtime/issues/75602
if (WasmEnableThreads && !Number.isInteger(config.pthreadPoolSize)) {
// ActiveIssue https://github.com/dotnet/runtime/issues/75602
config.pthreadPoolSize = 7;
}
if (WasmEnableThreads && !Number.isInteger(config.pthreadPoolReady)) {
config.pthreadPoolReady = 3;
}

// this is how long the Mono GC will try to wait for all threads to be suspended before it gives up and aborts the process
if (WasmEnableThreads && config.environmentVariables["MONO_SLEEP_ABORT_LIMIT"] === undefined) {
2 changes: 2 additions & 0 deletions src/mono/browser/runtime/loader/globals.ts
Original file line number Diff line number Diff line change
@@ -92,6 +92,8 @@ export function setLoaderGlobals(
loadedFiles: [],
loadedAssemblies: [],
libraryInitializers: [],
loadingWorkers: [],
workerNextNumber: 1,
actual_downloaded_assets_count: 0,
actual_instantiated_assets_count: 0,
expected_downloaded_assets_count: 0,
3 changes: 2 additions & 1 deletion src/mono/browser/runtime/loader/run.ts
Original file line number Diff line number Diff line change
@@ -10,7 +10,7 @@ import { ENVIRONMENT_IS_WEB, ENVIRONMENT_IS_WORKER, emscriptenModule, exportedRu
import { deep_merge_config, deep_merge_module, mono_wasm_load_config } from "./config";
import { installUnhandledErrorHandler, mono_exit, registerEmscriptenExitHandlers } from "./exit";
import { setup_proxy_console, mono_log_info, mono_log_debug } from "./logging";
import { mono_download_assets, prepareAssets, prepareAssetsWorker, resolve_single_asset_path, streamingCompileWasm } from "./assets";
import { mono_download_assets, preloadWorkers, prepareAssets, prepareAssetsWorker, resolve_single_asset_path, streamingCompileWasm } from "./assets";
import { detect_features_and_polyfill } from "./polyfills";
import { runtimeHelpers, loaderHelpers } from "./globals";
import { init_globalization } from "./icu";
@@ -487,6 +487,7 @@ async function createEmscriptenMain(): Promise<RuntimeAPI> {
setTimeout(async () => {
try {
init_globalization();
preloadWorkers();
await mono_download_assets();
}
catch (err) {
11 changes: 6 additions & 5 deletions src/mono/browser/runtime/loader/worker.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

import { MonoConfigInternal, WorkerToMainMessageType, monoMessageSymbol } from "../types/internal";
import { MonoConfigInternal, PThreadInfo, WorkerToMainMessageType, monoMessageSymbol } from "../types/internal";
import { MonoConfig } from "../types";
import { deep_merge_config, normalizeConfig } from "./config";
import { ENVIRONMENT_IS_WEB, loaderHelpers } from "./globals";
import { ENVIRONMENT_IS_WEB, loaderHelpers, runtimeHelpers } from "./globals";
import { mono_log_debug } from "./logging";

export function setupPreloadChannelToMainThread() {
@@ -13,7 +13,8 @@ export function setupPreloadChannelToMainThread() {
const mainPort = channel.port2;
workerPort.addEventListener("message", (event) => {
const config = JSON.parse(event.data.config) as MonoConfig;
onMonoConfigReceived(config);
const monoThreadInfo = JSON.parse(event.data.monoThreadInfo) as PThreadInfo;
onMonoConfigReceived(config, monoThreadInfo);
workerPort.close();
mainPort.close();
}, { once: true });
@@ -30,13 +31,13 @@ export function setupPreloadChannelToMainThread() {
let workerMonoConfigReceived = false;

// called when the main thread sends us the mono config
function onMonoConfigReceived(config: MonoConfigInternal): void {
function onMonoConfigReceived(config: MonoConfigInternal, monoThreadInfo: PThreadInfo): void {
if (workerMonoConfigReceived) {
mono_log_debug("mono config already received");
return;
}

deep_merge_config(loaderHelpers.config, config);
runtimeHelpers.monoThreadInfo = monoThreadInfo;
normalizeConfig();
mono_log_debug("mono config received");
workerMonoConfigReceived = true;
9 changes: 7 additions & 2 deletions src/mono/browser/runtime/polyfills.ts
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@ import WasmEnableThreads from "consts:wasmEnableThreads";
import type { EmscriptenReplacements } from "./types/internal";
import type { TypedArray } from "./types/emscripten";
import { ENVIRONMENT_IS_NODE, ENVIRONMENT_IS_WORKER, INTERNAL, Module, loaderHelpers, runtimeHelpers } from "./globals";
import { replaceEmscriptenPThreadLibrary } from "./pthreads/shared/emscripten-replacements";
import { replaceEmscriptenPThreadUI } from "./pthreads/browser/replacements";
import { replaceEmscriptenPThreadWorker } from "./pthreads/worker/replacements";

const dummyPerformance = {
now: function () {
@@ -34,7 +35,11 @@ export function initializeReplacements(replacements: EmscriptenReplacements): vo

// threads
if (WasmEnableThreads && replacements.modulePThread) {
replaceEmscriptenPThreadLibrary(replacements.modulePThread);
if (ENVIRONMENT_IS_WORKER) {
replaceEmscriptenPThreadWorker(replacements.modulePThread);
} else {
replaceEmscriptenPThreadUI(replacements.modulePThread);
}
}
}

Loading

0 comments on commit c930a99

Please sign in to comment.