comparison core/RTAudio.cpp @ 256:3e93d9793da3 aux_task_args

Overload BeagleRT_createAuxiliaryTask so tasks can be created with or without arguments
author Liam Donovan <l.b.donovan@qmul.ac.uk>
date Fri, 06 May 2016 21:36:27 +0100
parents 173978a5ab6a
children 88cf310417cd
comparison
equal deleted inserted replaced
254:173978a5ab6a 256:3e93d9793da3
39 39
40 // Data structure to keep track of auxiliary tasks we 40 // Data structure to keep track of auxiliary tasks we
41 // can schedule 41 // can schedule
42 typedef struct { 42 typedef struct {
43 RT_TASK task; 43 RT_TASK task;
44 void (*function)(void*); 44 void (*argfunction)(void*);
45 void (*function)(void);
45 char *name; 46 char *name;
46 int priority; 47 int priority;
47 bool started; 48 bool started;
49 bool hasArgs;
48 void* args; 50 void* args;
49 } InternalAuxiliaryTask; 51 } InternalAuxiliaryTask;
50 52
51 const char gRTAudioThreadName[] = "beaglert-audio"; 53 const char gRTAudioThreadName[] = "beaglert-audio";
52 const char gRTAudioInterruptName[] = "beaglert-pru-irq"; 54 const char gRTAudioInterruptName[] = "beaglert-pru-irq";
290 292
291 // Create a calculation loop which can run independently of the audio, at a different 293 // Create a calculation loop which can run independently of the audio, at a different
292 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY; 294 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY;
293 // priority should be generally be less than this. 295 // priority should be generally be less than this.
294 // Returns an (opaque) pointer to the created task on success; 0 on failure 296 // Returns an (opaque) pointer to the created task on success; 0 on failure
295 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void*), int priority, const char *name, void* args) 297 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void* args), int priority, const char *name, void* args)
296 { 298 {
297 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask)); 299 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
298 300
299 // Attempt to create the task 301 // Attempt to create the task
300 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) { 302 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
302 free(newTask); 304 free(newTask);
303 return 0; 305 return 0;
304 } 306 }
305 307
306 // Populate the rest of the data structure and store it in the vector 308 // Populate the rest of the data structure and store it in the vector
307 newTask->function = functionToCall; 309 newTask->argfunction = functionToCall;
308 newTask->name = strdup(name); 310 newTask->name = strdup(name);
309 newTask->priority = priority; 311 newTask->priority = priority;
310 newTask->started = false; 312 newTask->started = false;
311 newTask->args = args; 313 newTask->args = args;
314 newTask->hasArgs = true;
312 315
313 getAuxTasks().push_back(newTask); 316 getAuxTasks().push_back(newTask);
314 317
315 return (AuxiliaryTask)newTask; 318 return (AuxiliaryTask)newTask;
319 }
320 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name)
321 {
322 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
323 // Attempt to create the task
324 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
325 cout << "Error: unable to create auxiliary task " << name << endl;
326 free(newTask);
327 return 0;
328 }
329 // Populate the rest of the data structure and store it in the vector
330 newTask->function = functionToCall;
331 newTask->name = strdup(name);
332 newTask->priority = priority;
333 newTask->started = false;
334 newTask->hasArgs = false;
335 getAuxTasks().push_back(newTask);
336 return (AuxiliaryTask)newTask;
316 } 337 }
317 338
318 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next 339 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next
319 // allow it to be scheduled. 340 // allow it to be scheduled.
320 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task) 341 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task)
330 // Calculation loop that can be used for other tasks running at a lower 351 // Calculation loop that can be used for other tasks running at a lower
331 // priority than the audio thread. Simple wrapper for Xenomai calls. 352 // priority than the audio thread. Simple wrapper for Xenomai calls.
332 // Treat the argument as containing the task structure 353 // Treat the argument as containing the task structure
333 void auxiliaryTaskLoop(void *taskStruct) 354 void auxiliaryTaskLoop(void *taskStruct)
334 { 355 {
356 InternalAuxiliaryTask *task = ((InternalAuxiliaryTask *)taskStruct);
357
335 // Get function to call from the argument 358 // Get function to call from the argument
336 void (*auxiliary_function)(void*) = ((InternalAuxiliaryTask *)taskStruct)->function; 359 void (*auxiliary_argfunction)(void* args) = task->argfunction;
337 const char *name = ((InternalAuxiliaryTask *)taskStruct)->name; 360 void (*auxiliary_function)(void) = task->function;
361
362 // get the name
363 const char *name = task->name;
338 364
339 // Wait for a notification 365 // Wait for a notification
340 rt_task_suspend(NULL); 366 rt_task_suspend(NULL);
341 367
342 while(!gShouldStop) { 368 while(!gShouldStop) {
343 // Then run the calculations 369 // Then run the calculations
344 auxiliary_function(((InternalAuxiliaryTask *)taskStruct)->args); 370 if (task->hasArgs)
371 auxiliary_argfunction(task->args);
372 else
373 auxiliary_function();
345 374
346 // Wait for a notification 375 // Wait for a notification
347 rt_task_suspend(NULL); 376 rt_task_suspend(NULL);
348 } 377 }
349 378