rust-lang / libs-team

The home of the library team
Apache License 2.0
110 stars 18 forks source link

Feature: A separate type for measuring thread time in std::time module #345

Open artech-git opened 4 months ago

artech-git commented 4 months ago

Had this thought regarding if we can infer the time it takes for object to be executed in a given OS thread context, instead of relying on the std::time::Instant to obtain the time elapsed which won't take into account things such as context switch etc etc, therefore I would like to propose a thought ThreadTime a type which may keep track of the time spent by itself on a given thread context excluding all the context switching mechanism..

internally it may look like so

pub struct ThreadTime { 
    duration: ThreadDuration, 
    thread: SomeThreadTypeRecorder
}

through this we can avoid using ThreadLocal<T> types directly which may wrap duration between itself, and then maybe we continue the computation, this can be especially useful if you wish to use it in the some struct where you wish to track time in precision. and should have !Sync enabled, let me know is it a useful idea ?

Iam not sure though whether this can be made platform agnostic ? and also O.S agnostic too.

BurntSushi commented 4 months ago

I'm not sure I understand the use case for something like this, nor do I understand the mechanism for which something like this would be implemented. Can you flesh both of those things out a bit more please? Real world examples would help. It would also help to describe why a thread local is an inappropriate solution.

joboet commented 4 months ago

I assume you mean something like CLOCK_THREAD_CPUTIME_ID? This is definitely possible to implement, at least on UNIX. Do you have a concrete problem in mind that you would like to use this for?

the8472 commented 4 months ago

There's the cpu-time crate and possibly others.

What would be the value of having this in std instead of a crate?

artech-git commented 4 months ago

Yup @BurntSushi & @joboet , I discovered this problem recently where let's say either Iam using std::thread::spawn or some green thread flavor let's consider tokio::spawn for doing some local computation scope to that thread, through

The current scenario might be somewhere similar to this, if we have to use ThreadLocal types

let's imagine that we are writing a proxy server for server, now we need a way to estimate the amount of time it takes for connection to perform some task per thread and we want to overlook the context switching time here thread parks etc.

use thread_local::ThreadLocal; 
...
pub struct ConnectedThread {
  thread_time: ThreadLocal<Duration>,
  ..
}
let conn = ConnectedThread::new(); 

let handle = std::thread::spawn(move || { 
   conn.do_some_jobs(); 
   let inst = Instant::now(); // instant at thread: 0

   conn.pass_time(inst); // maybe like this
});

handle.park(); // condition 1: 
// some very Compute heavy work ignoring the fact as mentioned above 

Disadvantages:

Probably better type would be to have something

a object and I wish to track time only via some type lets say that name to be std::time::ThreadTime and initialize it and forget afterwards the concerns which I faced earlier.

use thread_local::ThreadLocal; 
...
pub struct ConnectedThread {
  pub thread_time: ThreadTime,
  ..
}
...
let conn = ConnectedThread::new(); 

let handle = std::thread::spawn(move || { 

   conn.thread_time.record_thread_time(); 
   conn.do_some_jobs(); 

   conn.thread_time.stop_thread_time_recording(); 
   conn.thread_time.get_time()
});

Benefits I see this from having it is obviously we can mitigate the above issue which I see can make things complicated but also can make this convenient too. This was roughly the idea in my head which was going on.

artech-git commented 4 months ago

There's the cpu-time crate and possibly others.

What would be the value of having this in std instead of a crate?

Good question, I think maybe we can create a more user controlled api design where we can also have control available for things such as parking and ignore context switching if the developer needs to have those!

let's say we want to ignore time recording for parking situation

let timer = ThreadTime::new()
                    .ignore_parking()
                    .build();                    

and have better thoughtful implementations of Auto traits as well.

perhaps we can even have a extendible API which can be extended from the current Instant object, something like this


let instant = Instant::now();
...
// Moved curr_instant some other thread.

let thread_time = instant.local_thread_time(); // Return ThreadTime here

so even if we create a Instant maybe we can have a ability to create it incase we need to record it for that thread.