Mercurial > hg > beaglert
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 |