mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-22 16:26:39 +00:00
76 lines
2.9 KiB
Text
76 lines
2.9 KiB
Text
|
Some notes on use of pthreads in GStreamer
|
||
|
------------------------------------------
|
||
|
|
||
|
First off, pthreads are HARD. Remember that.
|
||
|
|
||
|
1) How I learned to debug glibc and pthreads and add debug code to it.
|
||
|
|
||
|
You have to trick your GStreamer test app in running against a modified
|
||
|
glibc.
|
||
|
|
||
|
I used Red Hat 7.3, downloaded the .src.rpm, installed it, applied the
|
||
|
patches included, and ran
|
||
|
./configure --prefix=/home/thomas/cvs --with-add-ons
|
||
|
make
|
||
|
make install
|
||
|
|
||
|
After quite some time this left me with recompiled libc and libpthread
|
||
|
libraries in /home/thomas/cvs/lib, as well as a new ld-linux.so.2
|
||
|
|
||
|
Now you need to use this new ld-linux.so ld loader to run your app,
|
||
|
preferably from inside of gdb so you can tell what's going on when it
|
||
|
crashes.
|
||
|
|
||
|
You can use ld-linux.so.2 to call your binaries:
|
||
|
ld-linux.so.2 .libs/thread1
|
||
|
to run the thread1 program with the new glibc.
|
||
|
|
||
|
If this is a GStreamer app, chances are it might not find some libraries
|
||
|
it needs that you could safely use from /usr/lib (like, zlib and popt).
|
||
|
|
||
|
Also, you want it to run in gdb, so this is my full line:
|
||
|
|
||
|
LD_LIBRARY_PATH=/usr/lib /home/thomas/cvs/lib/ld-linux.so.2 \
|
||
|
/usr/bin/gdb .libs/thread1
|
||
|
|
||
|
At this point you can start adding debug code to the pthreads implementation
|
||
|
in your glibc source tree. Just change, re-run make install, and restart
|
||
|
the test app in gdb.
|
||
|
|
||
|
Helpful --gst-mask is 0x00200100 to get thread info and scheduling info
|
||
|
(with mem alloc from cothreads)
|
||
|
|
||
|
2) What GStreamer does with pthreads.
|
||
|
|
||
|
Apps create a thread with gst_thread_new. This just allocates the GstThread
|
||
|
structure without actually doing much with it.
|
||
|
|
||
|
When a thread goes from NULL to READY, the gst_thread_change_state function
|
||
|
creates the actual pthread.
|
||
|
- we lock the thread->lock mutex
|
||
|
- we create attributes for the pthread
|
||
|
- by default the pthread is JOINABLE
|
||
|
- we ask the thread's scheduler for a preferred stack size and location
|
||
|
(FIXME: if the scheduler doesn't return one, what do we do ?)
|
||
|
- we create the pthread with the given attributes
|
||
|
- the pthread id is stored in thread->thread_id
|
||
|
- the created pthread starts executing gst_thread_main_loop (thread)
|
||
|
- the change_state function does a g_cond_wait
|
||
|
- this means it unlocks the mutex, waits until thread->cond is set
|
||
|
(which happens in gst_thread_main_loop),
|
||
|
then relocks the mutex and resumes execution
|
||
|
|
||
|
From the point of view of the created pthread, here's what happens.
|
||
|
gst_thread_main_loop (thread) gets called
|
||
|
- the thread's mutex gets locked
|
||
|
- the thread's scheduler's policy gets examined
|
||
|
- the scheduler gets set up (invokes the scheduler object's setup method)
|
||
|
FIXME: what are the prereqs of this _setup method ?
|
||
|
- basic and fast scheduler both call do_cothread_context_init
|
||
|
- basic: this calls cothread_context_init
|
||
|
- cothread_context_init
|
||
|
- fast: this calls cothread_create (NULL, 0, NULL, NULL))
|
||
|
|
||
|
(FINISHME)
|
||
|
(FOLDMEBACKTOREALDOCS)
|