-
Notifications
You must be signed in to change notification settings - Fork 27
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
threadsafe basop32 and enh40 files, with control over global variables and exit/abort #171
base: dev
Are you sure you want to change the base?
Conversation
…s and exit/abort basop32_threadsafe.c, enh40_threadsafe.c, basop32_threadsafe.h, and enh40_threadsafe.h are modified basop and enh40 files for use with ITU and ETSI codecs. The modifications make some functions static inline, allow disable terminations not suitable for Linux libs such as exit() and replace with alternate error handling and message logging, and allow removal or alternative usage of global variables Overflow and Carry. For example, sub_ovf() is identical to sub() but includes a stack based Overflow param. Definitions such as USE_BASOPS_INLINE, EXCLUDE_BASOPS_NOT_USED, USE_BASOPS_OVERFLOW_GLOBAL_VAR, USE_BASOPS_CARRY_GLOBAL_VAR, and USE_BASOPS_EXIT allow fine-grain control of modification behavior. Also: -2017 STL format & indentation is maintained -modifications include detailed comments -for testing with standard codec builds, modify your Makefile to temporarily rename basop32_threadsafe.h to basop32.h and enh40_threadsafe.h to enh40.h -so far bit-exact tested with some codecs, but no separate functional test is provided for basop
Many thanks for providing this update! We have also come across the issue with the global variables in STL and have patched it locally in our code, similar to the solution you propose. We still have some comments that we think may be considered:
Thanks and best regards, |
Hi Erik, thanks very much for your feedback ! Some comments and notes:
-Jeff |
Hi Jeff, Thanks for your reply. First, I would like to point to #173 provided by our colleagues at Fraunhofer. I guess this a clearer picture of what we had in mind.
|
A quick comment - I think
1) moving away from global variables is a good idea moving forward. It fits the general philosophy of the library for modularity (that gave me a lot of work, especially when I was incorporating modules such as G.726 and G.722 into the STL a few decades ago... not a new problem!)
2) I support the proposed approach to have a global compile time switch for backward compatibility, there is a lot of code that uses end expect that behavior. However, we need to make sure that as future versions of the module are developed, that the backward option will continue to work. That means, it needs to be carefully included in regression / portability testing.
Cheers,
Simão
From: Erik Norvell ***@***.***>
Sent: Friday, 22 September, 2023 09:21
To: openitu/STL ***@***.***>
Cc: Subscribed ***@***.***>
Subject: Re: [openitu/STL] threadsafe basop32 and enh40 files, with control over global variables and exit/abort (PR #171)
Hi Jeff,
Thanks for your reply. First, I would like to point to #173<#173> provided by our colleagues at Fraunhofer. I guess this a clearer picture of what we had in mind.
1. I suppose a build-time option could be ok, but then I think the default should be to use the new behavior. So you could e.g. activate the old solution using global variables using a preprocessor macro. Maybe the user can be made aware the tool is used in a non-recommended way.
2. I was thinking about the EVS macro in basop_threadsafe.c. Perhaps this was just there to mark the source of these changes and was meant to go away?
3. Thanks for the explanation. If I understood you right, the EVS and AMR-WB implementations would need to be updated to use the new operators. If we would take the reference basop code for these codecs and combine with the updated STL package, they would just use the old operators. To give some more explanation: in our work with IVAS we introduced these changes as outlined in #173<#173>. We needed to patch the EVS code to use the introduced operators and I was simply wondering if you needed to do something similar.
-
Reply to this email directly, view it on GitHub<#171 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEC4YAVIJQQWTTXXVVIQN23X3U34LANCNFSM6AAAAAAY2DYATA>.
You are receiving this because you are subscribed to this thread.Message ID: ***@***.******@***.***>>
|
Newer codecs like EVS do not have any global variables other than the ones in the BASOPs and potentially a frame counter (which is convenient in development code but probably even there not justified). We fully support Jeff's objective that we need to avoid global variables to have threadsafe and reentrant code. As mentioned by Erik, in #173 we have an alternative way how it could be done. We do not insist on our PR to make it, but we do have the objective to have the full set of BASOPs available without global variables so that 3GPP can develop fixed-point code that does not inherit this issue. As a side note, we've developed this with 3GPP IVAS compatibility in mind, while Jeff did so with Signalogic's implementations.
Yes, this is the main pain point of such changes. There is potentially quite some code around that uses the old operators. In our experience, the saturating behavior of the operators or usage of the Overflow / Carry flags is not extensively used. It is thus a realistic undertaking to modify existing code. Modified code would then benefit from explicit marking where Overflows happen, which would even permit faster implementations of the operators in the cases where there is no Overflow. This is of course outside the scope of STL but may be relevant for implementers who replace the BASOPs by their platform-specific intrinsics. The G.722 has been patched in #173 - but regression/portability testing was limited to the tests that were part of STL. On backward compatibility in general, I would opt more for making a cut and making the variant without global variables the default behaviour. Existing code may rely on STL2009, old ETSI BASOPs, STL2023 or even variants that have been modified inside a codec (EVS is an example that used STL2009 plus some operators that only made it into STL2015). The asserts in our approach help to identify where to modify code and if e.g. a codec wants to move to STL2025 (or whatever the next version is) then it would have to be mildly changed - as we did in G.722 or the EVS code portions inside IVAS. Leaving a variant with global variables in to activate by a preprocessor switch - just to allow using latest STL with old code - may be an option, but I don't think it would be needed. One other aspect on global variables: the BASOP counters are still global variables. We did not want to touch this in #173 as they would only be used for complexity simulation and disabled in production code - and because carrying them around would require API changes to almost all operators. |
Hi Erik, let me reply to your comments first, then Stefan's.
|
Hi Stefan- I agree with most of your comments. In particular, your philosophy on explicitly specifying "no global variables" (i.e. the BASOP_NOGLOB #define) I think is correct, and the polarity of the preprocessor macros in our pull-request should be reversed (for example USE_BASOPS_OVERFLOW_GLOBAL_VAR should be changed to NO_BASOPS_OVERFLOW_GLOBAL_VAR). However, we have a key difference on the value of using an updated STL with existing codec sources (re. your comment "Leaving a variant with global variables in to activate by a preprocessor switch - just to allow using latest STL with old code - may be an option, but I don't think it would be needed"). The main point of Signalogic's pull-request is this. We have a number of large corporate customers who are deeply concerned about using a modified STL because it would constitute an ITU license violation (per the prohibition against source code modifications in the "ITU STL General Public License at https://github.com/openitu/STL/blob/dev/LICENSE.md). In fact, in a few situations this has dominated discussion as they are concerned not only about thread-safe operation but also unforeseen and untrackable aborts and exits, of which even the remotest possibility must be avoided. To address these concerns -- and avoid any touching whatsoever of current STL source -- Signalogic has come up with a method to intercept STL exit() and abort() calls, read the stack trace to know which codec source made the STL operator call, issue a warning/error message (and also log to a file if specified by user options), perform some type of "continuation behavior" (for example setting the result to maximum possible N-bit value in the case of division by zero), and return to the calling code. Of course we want to avoid this complexity; this is why our STL pull-request provides a "NO_BASOPS_EXIT" preprocessor macro. Possibly this could be expanded to include #defines for fine-grained control of error/warning messages, logging to file, and continuation behavior. Using this approach we can serve corporate customers who wish to use their current version of codec source with an updated STL that both provides thread-safe operation and eliminates the possibility of a total application exit. |
Signalogic has published a BASOP upgrade proposal. As a non-member we can't upload the doc to the ITU site so we have posted it on our STL Github fork: https://github.com/signalogic/STL/blob/dev/doc/Signalogic_ITU_Non-Member_SG12_BASOPS_Upgrade.pdf Also we posted a 3-slide overview PPT: https://github.com/signalogic/STL/blob/dev/doc/Signalogic_ITU_BASOP_Upgrade_3Slides_Overview.pdf |
Continued upgraded basop development:
|
basop32_threadsafe.c, enh40_threadsafe.c, basop32_threadsafe.h, and enh40_threadsafe.h are modified basop and enh40 files for use with ITU and ETSI codecs. The modifications make some functions static inline, allow disabling terminations not suitable for Linux libs such as exit() and replace with alternate error handling and message logging, and allow removal or alternative usage of global variables Overflow and Carry. For example, sub_ovf() is identical to sub() but includes a stack based Overflow param. Definitions such as USE_BASOPS_INLINE, EXCLUDE_BASOPS_NOT_USED, USE_BASOPS_OVERFLOW_GLOBAL_VAR, USE_BASOPS_CARRY_GLOBAL_VAR, and USE_BASOPS_EXIT allow fine-grain control of modification behavior. Also:
-2017 STL format & indentation is maintained
-modifications include detailed comments
-for testing with standard codec builds, modify your Makefile to temporarily rename basop32_threadsafe.h to basop32.h and enh40_threadsafe.h to enh40.h
-so far bit-exact tested with some codecs, but no separate functional test is provided for basop