Bug 1476405: Part 6 - Register AudioIPC threads with the profiler. r?kinetik draft
authorKris Maglione <maglione.k@gmail.com>
Wed, 18 Jul 2018 23:29:16 -0700
changeset 821045 7e62a32c5dc6382e9bba7730534952359167981b
parent 821044 cb8d820ea2d8d990742e11dbb0b3c8407e9335d5
child 821174 03ed414139161d95ab139a5da453c56847bbd6e5
push id116998
push usermaglione.k@gmail.com
push dateFri, 20 Jul 2018 20:53:25 +0000
reviewerskinetik
bugs1476405
milestone63.0a1
Bug 1476405: Part 6 - Register AudioIPC threads with the profiler. r?kinetik Presumably the Rust portion of this will have to land externally first and then be imported, but I have no idea how or where to submit it. MozReview-Commit-ID: 2gzQbRKxaZ9
dom/media/CubebUtils.cpp
media/audioipc/client/src/context.rs
media/audioipc/client/src/lib.rs
--- a/dom/media/CubebUtils.cpp
+++ b/dom/media/CubebUtils.cpp
@@ -53,16 +53,17 @@
 #endif
 
 extern "C" {
 
 struct AudioIpcInitParams {
   int mServerConnection;
   size_t mPoolSize;
   size_t mStackSize;
+  void (*mThreadCreateCallback)(const char*);
 };
 
 // These functions are provided by audioipc-server crate
 extern void* audioipc_server_start();
 extern mozilla::ipc::FileDescriptor::PlatformHandleType audioipc_server_new_client(void*);
 extern void audioipc_server_stop(void*);
 // These functions are provided by audioipc-client crate
 extern int audioipc_client_init(cubeb**, const char*, const AudioIpcInitParams*);
@@ -424,16 +425,19 @@ cubeb* GetCubebContextUnlocked()
     } else {
       MOZ_DIAGNOSTIC_ASSERT(sIPCConnection);
     }
 
     AudioIpcInitParams initParams;
     initParams.mPoolSize = sAudioIPCPoolSize;
     initParams.mStackSize = sAudioIPCStackSize;
     initParams.mServerConnection = sIPCConnection->ClonePlatformHandle().release();
+    initParams.mThreadCreateCallback = [](const char* aName) {
+      PROFILER_REGISTER_THREAD(aName);
+    };
 
     MOZ_LOG(gCubebLog, LogLevel::Debug, ("%s: %d", PREF_AUDIOIPC_POOL_SIZE, (int) initParams.mPoolSize));
     MOZ_LOG(gCubebLog, LogLevel::Debug, ("%s: %d", PREF_AUDIOIPC_STACK_SIZE, (int) initParams.mStackSize));
 
     rv = audioipc_client_init(&sCubebContext, sBrandName, &initParams);
   } else {
     rv = cubeb_init(&sCubebContext, sBrandName, sCubebBackendName.get());
   }
--- a/media/audioipc/client/src/context.rs
+++ b/media/audioipc/client/src/context.rs
@@ -15,16 +15,17 @@ use futures::Future;
 use futures_cpupool::{self, CpuPool};
 use libc;
 use std::{fmt, io, mem, ptr};
 use std::ffi::{CStr, CString};
 use std::os::raw::c_void;
 use std::os::unix::io::FromRawFd;
 use std::os::unix::net;
 use std::sync::mpsc;
+use std::thread;
 use stream;
 use tokio_core::reactor::{Handle, Remote};
 use tokio_uds::UnixStream;
 
 struct CubebClient;
 
 impl rpc::Client for CubebClient {
     type Request = ServerMessage;
@@ -94,41 +95,55 @@ impl ContextOps for ClientContext {
             let _ = tx_rpc.send(rpc);
             Some(())
         }
 
         assert_not_in_callback();
 
         let (tx_rpc, rx_rpc) = mpsc::channel();
 
+        let params = CPUPOOL_INIT_PARAMS.with(|p| {
+            p.replace(None).unwrap()
+        });
+
+        let thread_create_callback = params.thread_create_callback;
+
+        let register_thread = move || {
+            if let Some(func) = thread_create_callback {
+                let thr = thread::current();
+                let name = CString::new(thr.name().unwrap()).unwrap();
+                func(name.as_ptr());
+            }
+        };
+
         let core = t!(core::spawn_thread("AudioIPC Client RPC", move || {
             let handle = core::handle();
 
+            register_thread();
+
             open_server_stream()
                 .ok()
                 .and_then(|stream| UnixStream::from_stream(stream, &handle).ok())
                 .and_then(|stream| bind_and_send_client(stream, &handle, &tx_rpc))
                 .ok_or_else(|| {
                     io::Error::new(
                         io::ErrorKind::Other,
                         "Failed to open stream and create rpc.",
                     )
                 })
         }));
 
         let rpc = t!(rx_rpc.recv());
 
-        let cpupool = CPUPOOL_INIT_PARAMS.with(|p| {
-            let params = p.replace(None).unwrap();
-            futures_cpupool::Builder::new()
+        let cpupool = futures_cpupool::Builder::new()
                 .name_prefix("AudioIPC")
+                .after_start(register_thread)
                 .pool_size(params.pool_size)
                 .stack_size(params.stack_size)
-                .create()
-        });
+                .create();
 
         let ctx = Box::new(ClientContext {
             _ops: &CLIENT_OPS as *const _,
             rpc: rpc,
             core: core,
             cpu_pool: cpupool,
         });
         Ok(unsafe { Context::from_ptr(Box::into_raw(ctx) as *mut _) })
--- a/media/audioipc/client/src/lib.rs
+++ b/media/audioipc/client/src/lib.rs
@@ -32,29 +32,32 @@ thread_local!(static IN_CALLBACK: std::c
 thread_local!(static CPUPOOL_INIT_PARAMS: InitParamsTls = std::cell::RefCell::new(None));
 
 #[repr(C)]
 #[derive(Clone, Copy, Debug)]
 pub struct AudioIpcInitParams {
     pub server_connection: c_int,
     pub pool_size: usize,
     pub stack_size: usize,
+    pub thread_create_callback: Option<extern "C" fn(*const ::std::os::raw::c_char)>,
 }
 
 #[derive(Clone, Copy, Debug)]
 struct CpuPoolInitParams {
     pub pool_size: usize,
     pub stack_size: usize,
+    pub thread_create_callback: Option<extern "C" fn(*const ::std::os::raw::c_char)>,
 }
 
 impl CpuPoolInitParams {
     pub fn init_with(params: &AudioIpcInitParams) -> Self {
         CpuPoolInitParams {
             pool_size: params.pool_size,
             stack_size: params.stack_size,
+            thread_create_callback: params.thread_create_callback,
         }
     }
 }
 
 fn set_in_callback(in_callback: bool) {
     IN_CALLBACK.with(|b| {
         assert_eq!(*b.borrow(), !in_callback);
         *b.borrow_mut() = in_callback;