Skip to content
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

Lock free audio #4230

Closed
wants to merge 40 commits into from
Closed

Conversation

LeonidGoltsblat
Copy link
Contributor

@LeonidGoltsblat LeonidGoltsblat commented Dec 23, 2024

  1. The main idea of ​​this PR is to create file players/recorders without locking. These operations take a lot of time because they call file io under a global lock and thus interfere with the processing of other calls. This type of load is especially typical for IVR-type applications. To avoid blocking, a slot reservation algorithm based on the new pj_stack data structure (see stack implementation and tests #4116) is used, which eliminates the need for PJSUA_LOCK() based lock protection on the pjsua_var.player[], pjsua_var.recorder[] arrays.
  2. Fixed unnecessary locking in pjsua_conf_connect2() for typical server-side use (master port, conference bridge, no sound device). In this case, pjsua_conf_connect2() called PJSUA_LOCK() (waiting for others to unlock it and preventing other calls from being processed) but nothing happens within that lock.
  3. Memory usage optimization: Immediately destroy temporary pools used to create file players/recorders. Currently, these pools are only used in the legacy conference switch, not in the conference bridge.
  4. Introduced PJSUA_MASTER_PORT_OPTIONS macro to set pjmedia_master_port_create() options parameter. Before this PR we had the parameter but no way to set its value.

PS only 3 files are changed here:

LeonidGoltsblat and others added 30 commits October 26, 2024 00:16
- some changes in sln to build with v143 build tools (VS 2022)
- 2 new pjsystest project configuration to build as Debug-Dynamic and Release-Dynamic
- stack implementation and testing incorporated into pjlib and pjlib-test projects
decreased the repeat counter increased the number of threads
# Conflicts:
#	pjlib/build/pjlib.vcxproj.filters
1) lock free (as much as possible) create/destroy file players/recorders
2) eliminate unnecessary lock in pjsua_conf_connect2() for typical server
	side usage (master port, bridge conf, no sound device)
3) immediately destroy temporary pools used to create
	file players/recorders.
4) Introduced PJSUA_MASTER_PORT_OPTIONS macro to set
	pjmedia_master_port_create() options parameter
@bennylp
Copy link
Member

bennylp commented Jan 3, 2025

Hi Leonid, thanks again for your patch. I agree that the global locking in pjsua-lib is really coarse, and you've shown an example where it could be improved (i.e in file player/recorder area).

The intended usage of players is to pre-create them during app initialization, to minimize io bottleneck as you said. And I'd like to remind you that pjsua-lib was never intended to be used as high performance server side app. But still, if you like to force using it as IVR, and if you cannot pre-create the players during startup, the intended usage is to manage the media players/recorders yourself and register the media port with pjsua_conf_add_port()/pjsua_conf_remove_port().

But still, again, if you like to have more fine grained lock granularity in file players/recorders, I would think that it would be much simpler if we just add mutex for it. I'm sure the improvement of lock free mutex will be very very small compared to the whole player creation time (which, if this is considered a problem, pjsua-lib already gives a way to let application manage it itself).

@LeonidGoltsblat
Copy link
Contributor Author

the intended usage is to manage the media players/recorders yourself

Hi Benny! First of all thank you for explanation! I agree this is the best for my use case.

I'm sure the improvement of lock free mutex will be very very small compared to the whole player creation time

You are absolutely right, but I would like to point out: the advantage is not in locking free itself. The advantage is in the ability to create and initialize resources in parallel (in this example, different players/recorders can be created in parallel). This idea is even more useful in conference bridge, where it allows creating, initializing and registering conf ports in parallel.

And thank you again for the offer to change lock granularity. It's not necessary, but I would really appreciate an implementation of the ability to get memory with explicit alignment, something like

void *pj_pool_alligned_alloc( pool, allignment, size)

(like C11 void *aligned_alloc(size_t alignment, size_t size);)

@bennylp
Copy link
Member

bennylp commented Jan 7, 2025

I'm sure the improvement of lock free mutex will be very very small compared to the whole player creation time

You are absolutely right, but I would like to point out: the advantage is not in locking free itself. The advantage is in the ability to create and initialize resources in parallel (in this example, different players/recorders can be created in parallel).

For now we'll leave this in the application (see my prior comment).

And thank you again for the offer to change lock granularity. It's not necessary, but I would really appreciate an implementation of the ability to get memory with explicit alignment, something like

void *pj_pool_alligned_alloc( pool, allignment, size)

Yes! I was thinking exactly the same thing. Feel free to submit a PR.

@bennylp
Copy link
Member

bennylp commented Jan 7, 2025

Closing this for now since #4116 was not accepted.

@bennylp bennylp closed this Jan 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants