-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
threads: add new mp_thread abstraction #12709
Conversation
Download the artifacts for this pull request: |
c2bbfa6
to
425b4c0
Compare
I wanted to mention it before you started your work but: is it worth it when we could just switch to pl_thread in the future? |
I was thinking about it. This would be very good idea, and I initially wanted to do that. Problem is the pl_thread is internal utility header of libplacebo. (also is less capable, than mp_thread currently, but can be extended) Unless it is exported in public API, we cannot feasibly use it. And I don't see why would libplacebo export this in API. In general this is quit lightweight wrapper tailored for our needs. |
cd7ca89
to
e79eb35
Compare
Rebase only, no additional changes. |
9871082
to
24ad34c
Compare
because its sole purpose is to interrupt a thread waiting via pthread_cond_wait() | ||
are not variables that signal a condition. mp_cond does not have any | ||
state per-se. Maybe mp_cond would better be named mp_interrupt, | ||
because its sole purpose is to interrupt a thread waiting via mp_cond_wait() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have our own interface, we aren't bound to copy pthread's naming. So this "maybe" can be turned into reality.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is not an interrupt. It is a way to signal that a new condition exists and that threads waiting for that condition can continue.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Frankly speaking I have not read this tech-overview.txt
. mp_thread
is a thin pthread wrapper, which with all intention and purpose should work in similar way. Obviously it is limited to a subset of pthread and with higher level abstraction, like offloading the clock conversion from the caller.
I can take a look into updating this docs, but I was surprised in the first place that we have something like that in mpv, it is not really related specifically to mpv and mostly standard threading stuff that we are no place to explain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have our own interface, we aren't bound to copy pthread's naming. So this "maybe" can be turned into reality.
I frankly don't agree with this mp_interrupt
commentary. Also cond
or conditional variable
naming is standardized, not only by pthread, but anything else really. Including C++ std::condition_variable
and so on. This make easier to understand what mp_cond
represents. And it definitely is NOT interrupt.
DOCS/tech-overview.txt
Outdated
@@ -555,13 +555,13 @@ Condition variables | |||
------------------- | |||
|
|||
They're used whenever a thread needs to wait for something, without nonsense | |||
like sleep calls or busy waiting. mpv uses the standard pthread API for this. | |||
like sleep calls or busy waiting. mpv uses the mp_thread API for this. | |||
There's a lot of literature on it. Read it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't lots of literature on mp_thread
API :)
Which brings up another point, we probably need some documentation on this new interface, i.e what type of guarantees it makes and doesn't make etc. We can go two routes:
- Start fresh. Make the absolute minimum amount of guarantees that mpv code expects/needs and cut the churn.
- Make it "based on pthreads" and document deviations.
The latter is probably easier to start off with, but pthreads have lots of subtle details that can be easy to overlook and/or get wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As it is more or less pthreads document it based on that.
After this extra layer is here just because windows is missing it and somewhat difficult to implement in a good way directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latter is probably easier to start off with, but pthreads have lots of subtle details that can be easy to overlook and/or get wrong.
The functionality that mpv uses is pretty basic, we just have mutex/condvar and thread, that's all.
After this extra layer is here just because windows is missing it and somewhat difficult to implement in a good way directly.
@DanOscarsson: Sorry, I don't understand what you mean. You mean that this extra layer is here only for windows, because it is hard to implement otherwise or you mean the new interface is hard to implement on windows directly. Both old and new version was implemented for win32.
And no, this is not a wrapper for Windows. The main point is to abstract implementation details of pthread and clock used. Use mp_time
as an internal clock and convert only when needed. Of course there are some adjustment to make Windows wrapper lightweight without the need of tracking thread pids. The main difference that with pthread you can get current thread handle, but not pid and on Windows is the other way around, you can get current thread pid and not handle.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There isn't lots of literature on mp_thread API :)
Updated this line. I've also skimmed through the rest of the threading overview and it flows nicely. Our API is basic ans uses pretty standard primitives and nor the API, nor the users of it cares about small intricacies. I still don't feel like mpv's technical overview is the place to teach threading and in the same time while we define custom mp_thread now, all primitives of it are pretty standardized and knowledge transferable. I don't think we have to do full description of it and developers would be better of it they learn pthreads or std::thread or even win32 threads first... and then usage of this mp_thread is quite standard.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like not hijacking global symbols so overall pretty good. Just minor things. I also noticed that a few of the <pthread.h>
removals were in some commits after the use new mp_thread abstraction
, so maybe some of the comments I initially made were taken care of later. I would be nicer if all of those were in the use new mp_thread abstraction
commit though.
Also this would unbreak windows 7 support right? At least in terms of removing the |
Not possible. On
Yes, probably. |
Ah I see. Yeah, the old way it worked always bothered me too. |
b3ed00c
to
bba3e99
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Removed one unused header from |
@kasper93: Ping. Looks like the sub thing I just merged caused a merged conflict. |
This will allow to avoid hacky pthreads symbols/header override. Inspired by pl_thread from libplacebo.
This change essentially removes mp_thread_self() and instead add mp_thread_id to track threads and have ability to query current thread id during runtime. This will be useful for upcoming win32 implementation, where accessing thread handle is different than on pthreads. Greatly reduces complexity. Otherweis locked map of tid <-> handle is required which is completely unnecessary for all mpv use-cases. Note that this is the mp_thread_id, not to confuse with system tid. For example on threads-posix implementation it is simply pthread_t.
And remove redundant define while at it.
rebased |
#define pthread_mutex_trylock(...) \ | ||
mp_ptwrap_mutex_trylock(__FILE__, __LINE__, __VA_ARGS__) | ||
#define mp_mutex_init_type(mutex, mtype) \ | ||
assert(!mp_mutex_init_type_internal(mutex, mtype)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
threads-win32.h already defines this, mistake?
also if this is never supposed to fail why not drop the _internal split and make the return value void
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is fixed. It was quite a big mess up ;p a718677
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so is mp_mutex_init_type
supposed to return void
?
To resolve issue with hijacking pthread headers/symbols and overall simplify the thread API and win32 implementation in particular. No more hacks, no more internal state, no more strange time conversions.