comparison core/RTAudio.cpp @ 258:88cf310417cd aux_task_args

Add a parameter 'autoSchedule' to createAuxiliaryTask() which when true causes the task to be automatically scheduled after every render function call, without the user needing to call scheduleAuxiliaryTask()
author Liam Donovan <l.b.donovan@qmul.ac.uk>
date Sat, 07 May 2016 13:23:15 +0100
parents 3e93d9793da3
children c55c6f6c233c
comparison
equal deleted inserted replaced
257:1606b50a58c6 258:88cf310417cd
46 char *name; 46 char *name;
47 int priority; 47 int priority;
48 bool started; 48 bool started;
49 bool hasArgs; 49 bool hasArgs;
50 void* args; 50 void* args;
51 bool autoSchedule;
51 } InternalAuxiliaryTask; 52 } InternalAuxiliaryTask;
52 53
53 const char gRTAudioThreadName[] = "beaglert-audio"; 54 const char gRTAudioThreadName[] = "beaglert-audio";
54 const char gRTAudioInterruptName[] = "beaglert-pru-irq"; 55 const char gRTAudioInterruptName[] = "beaglert-pru-irq";
55 56
292 293
293 // Create a calculation loop which can run independently of the audio, at a different 294 // Create a calculation loop which can run independently of the audio, at a different
294 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY; 295 // (equal or lower) priority. Audio priority is defined in BEAGLERT_AUDIO_PRIORITY;
295 // priority should be generally be less than this. 296 // priority should be generally be less than this.
296 // Returns an (opaque) pointer to the created task on success; 0 on failure 297 // Returns an (opaque) pointer to the created task on success; 0 on failure
297 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void* args), int priority, const char *name, void* args) 298 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void* args), int priority, const char *name, void* args, bool autoSchedule)
298 { 299 {
299 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask)); 300 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
300 301
301 // Attempt to create the task 302 // Attempt to create the task
302 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) { 303 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
310 newTask->name = strdup(name); 311 newTask->name = strdup(name);
311 newTask->priority = priority; 312 newTask->priority = priority;
312 newTask->started = false; 313 newTask->started = false;
313 newTask->args = args; 314 newTask->args = args;
314 newTask->hasArgs = true; 315 newTask->hasArgs = true;
315 316 newTask->autoSchedule = autoSchedule;
317
316 getAuxTasks().push_back(newTask); 318 getAuxTasks().push_back(newTask);
317 319
318 return (AuxiliaryTask)newTask; 320 return (AuxiliaryTask)newTask;
319 } 321 }
320 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name) 322 AuxiliaryTask BeagleRT_createAuxiliaryTask(void (*functionToCall)(void), int priority, const char *name, bool autoSchedule)
321 { 323 {
322 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask)); 324 InternalAuxiliaryTask *newTask = (InternalAuxiliaryTask*)malloc(sizeof(InternalAuxiliaryTask));
325
323 // Attempt to create the task 326 // Attempt to create the task
324 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) { 327 if(rt_task_create(&(newTask->task), name, 0, priority, T_JOINABLE | T_FPU)) {
325 cout << "Error: unable to create auxiliary task " << name << endl; 328 cout << "Error: unable to create auxiliary task " << name << endl;
326 free(newTask); 329 free(newTask);
327 return 0; 330 return 0;
328 } 331 }
332
329 // Populate the rest of the data structure and store it in the vector 333 // Populate the rest of the data structure and store it in the vector
330 newTask->function = functionToCall; 334 newTask->function = functionToCall;
331 newTask->name = strdup(name); 335 newTask->name = strdup(name);
332 newTask->priority = priority; 336 newTask->priority = priority;
333 newTask->started = false; 337 newTask->started = false;
334 newTask->hasArgs = false; 338 newTask->hasArgs = false;
339 newTask->autoSchedule = autoSchedule;
340
335 getAuxTasks().push_back(newTask); 341 getAuxTasks().push_back(newTask);
342
336 return (AuxiliaryTask)newTask; 343 return (AuxiliaryTask)newTask;
337 } 344 }
338 345
339 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next 346 // Schedule a previously created (and started) auxiliary task. It will run when the priority rules next
340 // allow it to be scheduled. 347 // allow it to be scheduled.
344 if(taskToSchedule->started == false){ // Note: this is not the safest method to check if a task 351 if(taskToSchedule->started == false){ // Note: this is not the safest method to check if a task
345 BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest. 352 BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest.
346 // A safer approach would use rt_task_inquire() 353 // A safer approach would use rt_task_inquire()
347 } 354 }
348 rt_task_resume(&taskToSchedule->task); 355 rt_task_resume(&taskToSchedule->task);
356 }
357 void BeagleRT_autoScheduleAuxiliaryTasks(){
358 vector<InternalAuxiliaryTask*>::iterator it;
359 for(it = getAuxTasks().begin(); it != getAuxTasks().end(); it++) {
360 if ((InternalAuxiliaryTask *)(*it)->autoSchedule){
361 BeagleRT_scheduleAuxiliaryTask(*it);
362 }
363 }
349 } 364 }
350 365
351 // Calculation loop that can be used for other tasks running at a lower 366 // Calculation loop that can be used for other tasks running at a lower
352 // priority than the audio thread. Simple wrapper for Xenomai calls. 367 // priority than the audio thread. Simple wrapper for Xenomai calls.
353 // Treat the argument as containing the task structure 368 // Treat the argument as containing the task structure
357 372
358 // Get function to call from the argument 373 // Get function to call from the argument
359 void (*auxiliary_argfunction)(void* args) = task->argfunction; 374 void (*auxiliary_argfunction)(void* args) = task->argfunction;
360 void (*auxiliary_function)(void) = task->function; 375 void (*auxiliary_function)(void) = task->function;
361 376
362 // get the name 377 // get the task's name
363 const char *name = task->name; 378 const char *name = task->name;
364 379
365 // Wait for a notification 380 // Wait for a notification
366 rt_task_suspend(NULL); 381 rt_task_suspend(NULL);
367 382