I'm using PortAudio's callback API for designing a signal processing loopback library.
I'd like to add a branch that depends on a flag inside the callback, so like
int pa_callback(const void *inputuffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
if (do_something_flag) {
do_something(inputBuffer, outputBuffer, frameCount);
} else {
do_something_else(inputBuffer, outputBuffer, frameCount);
}
return paContinue;
}
Where do_something_flag is set elsewhere in my program at regular intervals.
The PortAudio callback documentation states:
Before we begin, it's important to realize that the callback is a
delicate place. This is because some systems perform the callback in a
special thread, or interrupt handler, and it is rarely treated the
same as the rest of your code. For most modern systems, you won't be
able to cause crashes by making disallowed calls in the callback, but
if you want your code to produce glitch-free audio, you will have to
make sure you avoid function calls that may take an unbounded amount
of time to execute. Exactly what these are depend on your platform but
almost certainly include the following: memory
allocation/deallocation, I/O (including file I/O as well as console
I/O, such as printf()), context switching (such as exec() or yield()),
mutex operations, or anything else that might rely on the OS. If you
think short critical sections are safe please go read about priority
inversion.
I don't care about the atomicity of the do_something_flag. That is, I don't care how many cycles it takes to get a correct value (within reason).
According to the documentation, it looks like I can't use mutexes for setting/reading that variable.
1) What are my options?
2) If I make it global and set it in another part of my program (another thread), what is the absolute worst that will happen? Again, I mean in terms of corrupting data to the point of program failure/etc.
Is there a right way to do this?
I'm not totally sure what you're exactly trying to do but I'm guessing it's what your title is asking about - "Changing a variable elsewhere".
Let's take this example: you have a variable frequency that changes over time. How do you access this? Well you have a generic pointer in the callback called userData. This can point to anything - a data structure, array, etc. I don't really remember how often the callback function gets called (it's pretty often... I wouldn't worry about speed) but the userData allows you to have variables that can be changed in your main thread while the pointer in the audio thread allows you to access it directly in the memory... My knowledge on thread safety isn't the best and sorry if that isn't the best explanation but I can at least show you how to do it through code (below).
This is how i usually do it but you don't need to do it yourself; I set a structure at the top of my file like so:
typedef struct {
float freq;
float vol;
}paData;
Obviously you'll initialize this somewhere in your code (probably in your main function call) and open the audio stream as such (data is of type paData):
/* Open audio stream */
err = Pa_OpenStream(&(*stream),
&inputParameters,
&outputParameters,
SAMPLE_RATE, bufSize, paNoFlag,
paCallback, &data);
After opening it you can have your callback like this:
static int pa_callback(const void *inputBffer,
void *outputBuffer,
unsigned long frameCount,
const PaStreamCallbackTimeInfo *timeInfo,
PaStreamCallbackFlags statusFlags,
void *userData)
{
// cast data so we can use it
paData *data = (paData *)userData;
// what's our frequency?
printf("%f\n", data->freq);
/* Do something with your code here */
return paContinue;
}
Hope that helps.
Related
I am currently writing a small game in C and feel like I can't get away from global variables.
For example I am storing the player position as a global variable because it's needed in other files. I have set myself some rules to keep the code clean.
Only use a global variable in the file it's defined in, if possible
Never directly change the value of a global from another file (reading from another file using extern is okay)
So for example graphics settings would be stored as file scope variables in graphics.c. If code in other files wants to change the graphics settings they would have to do so through a function in graphics.c like graphics_setFOV(float fov).
Do you think those rules are sufficient for avoiding global variable hell in the long term?
How bad are file scope variables?
Is it okay to read variables from other files using extern?
Typically, this kind of problem is handled by passing around a shared context:
graphics_api.h
#ifndef GRAPHICS_API
#define GRAPHICS_API
typedef void *HANDLE;
HANDLE init_graphics(void);
void destroy_graphics(HANDLE handle);
void use_graphics(HANDLE handle);
#endif
graphics.c
#include <stdio.h>
#include <stdlib.h>
#include "graphics_api.h"
typedef struct {
int width;
int height;
} CONTEXT;
HANDLE init_graphics(void) {
CONTEXT *result = malloc(sizeof(CONTEXT));
if (result) {
result->width = 640;
result->height = 480;
}
return (HANDLE) result;
}
void destroy_graphics(HANDLE handle) {
CONTEXT *context = (CONTEXT *) handle;
if (context) {
free(context);
}
}
void use_graphics(HANDLE handle) {
CONTEXT *context = (CONTEXT *) handle;
if (context) {
printf("width = %5d\n", context->width);
printf("height = %5d\n", context->height);
}
}
main.c
#include <stdio.h>
#include "graphics_api.h"
int main(void) {
HANDLE handle = init_graphics();
if (handle) {
use_graphics(handle);
destroy_graphics(handle);
}
return 0;
}
Output
width = 640
height = 480
Hiding the details of the context by using a void pointer prevents the user from changing the data contained within the memory to which it points.
How do you avoid using global variables in inherently stateful programs?
By passing arguments...
// state.h
/// state object:
struct state {
int some_value;
};
/// Initializes state
/// #return zero on success
int state_init(struct state *s);
/// Destroys state
/// #return zero on success
int state_fini(struct state *s);
/// Does some operation with state
/// #return zero on success
int state_set_value(struct state *s, int new_value);
/// Retrieves some operation from state
/// #return zero on success
int state_get_value(struct state *s, int *value);
// state.c
#include "state.h"
int state_init(struct state *s) {
s->some_value = -1;
return 0;
}
int state_fini(struct state *s) {
// add free() etc. if needed here
// call fini of other objects here
return 0;
}
int state_set_value(struct state *s, int value) {
if (value < 0) {
return -1; // ERROR - invalid argument
// you may return EINVAL here
}
s->some_value = value;
return 0; // success
}
int state_get_value(struct state *s, int *value) {
if (s->some_value < 0) { // value not set yet
return -1;
}
*value = s->some_value;
return 0;
}
// main.c
#include "state.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
struct state state; // local variable
int err = state_init(&state);
if (err) abort();
int value;
err = state_get_value(&state, &value);
if (err != 0) {
printf("Getting value errored: %d\n", err);
}
err = state_set_value(&state, 50);
if (err) abort();
err = state_get_value(&state, &value);
if (err) abort();
printf("Current value is: %d\n", value);
err = state_fini(&state);
if (err) abort();
}
The only single case where global variables (preferably only a single pointer to some stack variable anyway) have to be used are signal handlers. The standard way would be to only increment a single global variable of type sig_atomic_t inside a signal handler and do nothing else - then execute all signal handling related logic from the normal flow in the rest of the code by checking the value of that variable. (On POSIX system) all other asynchronous communication from the kernel, like timer_create, that take sigevent structure, they can pass arguments to notified function by using members in union sigval.
Do you think those rules are sufficient for avoiding global variable hell in the long term?
Subjectively: no. I believe that a potentially uneducated programmer has too much freedom in creating global variables given the first rule. In complex programs I would use a hard rule: Do not use global variables. If finally after researching all other ways and all other possibilities have been exhausted and you have to use a global variables, make sure global variables leave the smallest possible memory footprint.
In simple short programs I wouldn't care much.
How bad are file scope variables?
This is opinion based - there are good cases where projects use many global variables. I believe that topic is exhausted in are global variables bad and numerous other internet resources.
Is it okay to read variables from other files using extern?
Yes, it's ok.
There are no "hard rules" and each project has it's own rules. I also recommend to read c2 wiki global variables are bad.
The first thing you have to ask yourself is: Just why did the programming world come to loath global variables? Obviously, as you noted, the way to model a global state is essentially a global (set of) variable(s). So what's the problem with that?
The Problem
All parts of the program have access to that state. The whole program becomes tightly coupled. Global variables violate the prime directive in programming, divide and conquer. Once all functions operate on the same data you can as well do away with the functions: They are no longer logical separations of concern but degrade to a notational convenience to avoid large files.
Write access is worse than read access: You'll have a hard time finding out just why on earth the state is unexpected at a certain point; the change can have happened anywhere. It is tempting to take shortcuts: "Ah, we can make the state change right here instead of passing a computation result back up three layers to the caller; that makes the code much smaller."
Even read access can be used to cheat and e.g. change behavior of some deep-down code depending on some global information: "Ah, we can skip rendering, there is no display yet!" A decision which should not be made in the rendering code but at top level. What if top level renders to a file!?
This creates both a debugging and a development/maintenance nightmare. If every piece of the code potentially relies on the presence and semantics of certain variables — and can change them! — it becomes exponentially harder to debug or change the program. The code agglomerating around the global data is like a cast, or perhaps a Boa Constrictor, which starts to immobilize and strangle your program.
Such programming can be avoided with (self-)discipline, but imagine a large project with many teams! It's much better to "physically" prevent access. Not coincidentally all programming languages after C, even if they are otherwise fundamentally different, come with improved modularization.
So what can we do?
The solution is indeed to pass parameters to functions, as KamilCuk said; but each function should only get the information they legitimately need. Of course it is best if the access is read-only and the result is a return value: Pure functions cannot change state at all and thus perfectly separate concerns.
But simply passing a pointer to the global state around does not cut the mustard: That's only a thinly veiled global variable.
Instead, the state should be separated into sub-states. Only top-level functions (which typically do not do much themselves but mostly delegate) have access to the overall state and hand sub-states to the functions they call. Third-tier functions get sub-sub states, etc. The corresponding implementation in C is a nested struct; pointers to the members — const whenever possible — are passed to functions which therefore cannot see, let alone alter, the rest of the global state. Separation of concerns is thus guaranteed.
I am writing a kernel module to monitor a few syscalls wanting to return the function arguments to user-land (via netlink socket) if the call was successful.
jprobe.kp.symbol_name = "rename";
jprobe.entry = rename_handler;
kretprobe.kp.symbol_name = "rename";
kretprobe.handler = rename_ret_handler;
static rename_obj_t _g_cur_rename = NULL;
static void _rename_handler(const char *oldpath, const char *newpath)
{
_g_cur_rename = create_rename(oldpath, newpath);
jprobe_return();
}
static void _rename_ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs)
{
/* Send only if successful */
if (regs_return_value(regs) == 0) {
add_send_queue(_g_cur_rename);
}
return 0;
}
I worry that another rename syscall may preempt[1] the current one after the jprobe and I will send incorrect return codes and arguments.
jprobe: rename(a, b)
jprobe rename(c, d)
kretprobe
kretprobe
Edit: This article[2] states that interrupts are disabled during a kprobe handler. But does that mean that interrupts are disable throughout the whole chain (jprobe -> kprobe -> kretprobe) or just for that single kprobe?
https://unix.stackexchange.com/questions/186355/few-questions-about-system-calls-and-kernel-modules-kernel-services-in-parallel
https://lwn.net/Articles/132196/
Interrupts are disabled for each jprobe call: not for the entire sequence.
How many calls are you expecting in the time it will take the application to process them? There are different approaches depending on how fast you expect the calls to come in. The simplest method, if you are only expecting maybe a few hundred calls before you can process them and you will dedicate the static memory to the purpose, is to implement a static array of rename_obj_t objects in memory and then use atomic_add from the kernel asm includes to point to the next entry (mod the size of your array).
This way you are returning a unique static reference each time, so long as the counter doesn't wrap around before you process the returned values. atomic_add is guaranteed to have the correct memory barriers in place so you don't have to worry about things like cache coherency.
I have a library which provides function calls to a user as below:
int* g_ID = NULL;
void processing(int p1, char p2)
{
int ID = newID();
g_ID = &ID;
callback(p1, p2);
return ID;
}
void SendResponse()
{
sendID(*g_ID);
}
The user sets up its application by registering its callback function with the signature void (f*)(int p1, char p2) and should not have knowledge about the ID used internally the library. So the user space code looks something like:
main()
{
RegisterCallback(HandleRequest);
while (inProgress())
sleep(1); /* just sleep here */
}
void (HandleRequest*)(int val1, char val2)
{
/* ... do something user specific ... */
SendResponse();
return;
}
The problem here is, that the library (handling IDs and g_ID is not thread safe) !! User's callback is invoked asynchronously by other library functions, as threads. Several threads can be executed this way in parallel. But I won't give the user visibility of library internal IDs.
I know the code snippets above are not perfect. There're just to demonstrate my intention ... SendResponse() is not yet implemented ;-).
I hope, someone can give some ideas how to "implement" SendResponse() and to keep thread safety.
You could use a threadlocal here to keep the g_ID, rather than making using a global. This will work in the scenario, as I understand it, that there may be multiple concurrent calls to process() from different threads, but that the process() method is as shown - that the SendResponse() call will only occur within the scope (runtime scope, not lexical) of the callback() method. That is true in the code shown. It could be untrue if HandleRequest did something exotic like kick off another thread an then return (but you could certainly ban that by documentation).
The other, more classic, approach is to encapsulate all the state you care about, like g_ID, into a void *, or opaque_state * or whatever, that you pass to the callback, and then methods like SendRespose() take that as an argument. If you don't like void * you can implement the opaque_state * version without exposing any details of that structure using a forward declaration.
Suppose there is a library function (can not modify) that accept a callback (function pointer) as its argument which will be called at some point in the future. My question: is there a way to store extra data along with the function pointer, so that when the callback is called, the extra data can be retrieved. The program is in c.
For example:
// callback's type, no argument
typedef void (*callback_t)();
// the library function
void regist_callback(callback_t cb);
// store data with the function pointer
callback_t store_data(callback_t cb, int data);
// retrieve data within the callback
int retrieve_data();
void my_callback() {
int a;
a = retrieve_data();
// do something with a ...
}
int my_func(...) {
// some variables that i want to pass to my_callback
int a;
// ... regist_callback may be called multiple times
regist_callback(store_data(my_callback, a));
// ...
}
The problem is because callback_t accept no argument. My idea is to generate a small piece of asm code each time to fill into regist_callback, when it is called, it can find the real callback and its data and store it on the stack (or some unused register), then jump to the real callback, and inside the callback, the data can be found.
pseudocode:
typedef struct {
// some asm code knows the following is the real callback
char trampoline_code[X];
callback_t real_callback;
int data;
} func_ptr_t;
callback_t store_data(callback_t cb, int data) {
// ... malloc a func_ptr_t
func_ptr_t * fpt = malloc(...);
// fill the trampoline_code, different machine and
// different calling conversion are different
// ...
fpt->real_callback = cb;
fpt->data = data;
return (callback_t)fpt;
}
int retrieve_data() {
// ... some asm code to retrive data on stack (or some register)
// and return
}
Is it reasonable? Is there any previous work done for such problem?
Unfortunately you're likely to be prohibited from executing your trampoline in more and more systems as time goes on, as executing data is a pretty common way of exploiting security vulnerabilities.
I'd start by reporting the bug to the author of the library. Everybody should know better than to offer a callback interface with no private data parameter.
Having such a limitation would make me think twice about how whether or not the library is reentrant. I would suggest ensuring you can only have one call outstanding at a time, and store the callback parameter in a global variable.
If you believe that the library is fit for use, then you could extend this by writing n different callback trampolines, each referring to their own global data, and wrap that up in some management API.
I have an Arduino project where I read data from a webserver.
I have an EthernetClient that reads the data character by character in a callback function.
My working code looks like (only the relevant parts):
void setup() {
Serial.begin(9600);
...
}
void loop() {
char* processedData = processData(callback); // this is in a external lib
}
boolean callback(char* buffer, int& i) {
...
if (Client.available()) {
char c = client.read();
buffer[i++] = c;
Serial.print(c);
}
...
}
This works without any problems (reading and processing the data), but when I remove Serial.begin(9600); and Serial.print(c); it stops working and I don't know why? The only thing changed is that the char c is not printed. What could be the problem?
A common reason why callback functions change their behavior when seemingly unrelated code is altered, is optimizer-related bugs.
Many embedded compilers fail to understand that a callback function (or an interrupt service routine) will ever be called in the program. They see no explicit call to that function and then assumes it is never called.
When the compiler has made such an assumption, it will optimize variables that are changed by the callback function, because it fails to see that the variable is changed by the program, between the point of initialization and the point of access.
// Bad practice example:
int x;
void main (void)
{
x=5;
...
if(x == 0) /* this whole if statement will get optimized away,
the compiler assumes that x has never been changed. */
{
do_stuff();
}
}
void callback (void)
{
x = 0;
}
When this bug strikes, it is nearly impossible to find, it can cause any kind of weird symptoms.
The solution is to always declare all file scope ("global") variables shared between main() and an interrupt/callback/thread as volatile. This makes it impossible for the compiler to make incorrect optimizer assumptions.
(Please note that the volatile keyword cannot be used to achieve synchronization nor does it guarantee any memory barriers. This answer is not in the slightest related to such issues!)
A guess: Because without the serial driver started, there is no data to process, and therefore your callback is not hit.
What were you hoping the serial callback to be doing in the absence of data?
Providing more information about Client and processData may help.