diff core/RTAudio.cpp @ 174:1e629f126322

AuxiliaryTask can now be scheduled from setup(). Closes #1373
author Giulio Moro <giuliomoro@yahoo.it>
date Mon, 28 Dec 2015 13:53:11 +0100
parents 5f4408705eed
children 9bfe04d184fb fb2cf9c00024
line wrap: on
line diff
--- a/core/RTAudio.cpp	Mon Dec 28 04:11:59 2015 +0100
+++ b/core/RTAudio.cpp	Mon Dec 28 13:53:11 2015 +0100
@@ -44,6 +44,7 @@
 	void (*function)(void);
 	char *name;
 	int priority;
+	bool started;
 } InternalAuxiliaryTask;
 
 const char gRTAudioThreadName[] = "beaglert-audio";
@@ -214,6 +215,7 @@
 	// Set default volume levels
 	BeagleRT_setDACLevel(settings->dacLevel);
 	BeagleRT_setADCLevel(settings->adcLevel);
+	// TODO: add more argument checks
 	for(int n = 0; n < 2; n++){
 		if(settings->pgaGain[n] > 59.5){
 			std::cerr << "PGA gain out of range [0,59.5]\n";
@@ -301,18 +303,22 @@
 	newTask->function = functionToCall;
 	newTask->name = strdup(name);
 	newTask->priority = priority;
+	newTask->started = false;
 
 	gAuxTasks.push_back(newTask);
 
 	return (AuxiliaryTask)newTask;
 }
 
-// Schedule a previously created auxiliary task. It will run when the priority rules next
+// Schedule a previously created (and started) auxiliary task. It will run when the priority rules next
 // allow it to be scheduled.
 void BeagleRT_scheduleAuxiliaryTask(AuxiliaryTask task)
 {
 	InternalAuxiliaryTask *taskToSchedule = (InternalAuxiliaryTask *)task;
-
+	if(taskToSchedule->started == false){ // Note: this is not the safest method to check if a task
+		BeagleRT_startAuxiliaryTask(task); // is started (or ready to be resumed), but it probably is the fastest.
+                                           // A safer approach would use rt_task_inquire()
+	}
 	rt_task_resume(&taskToSchedule->task);
 }
 
@@ -340,6 +346,20 @@
 		rt_printf("auxiliary task %s ended\n", name);
 }
 
+
+int BeagleRT_startAuxiliaryTask(AuxiliaryTask task){
+	InternalAuxiliaryTask *taskStruct;
+	taskStruct = (InternalAuxiliaryTask *)task;
+	if(taskStruct->started == true)
+		return 0;
+	if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) {
+		cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl;
+		return -1;
+	}
+	taskStruct->started = true;
+	return 0;
+}
+
 // startAudio() should be called only after initAudio() successfully completes.
 // It launches the real-time Xenomai task which runs the audio loop. Returns 0
 // on success.
@@ -370,12 +390,7 @@
 	// The user may have created other tasks. Start those also.
 	vector<InternalAuxiliaryTask*>::iterator it;
 	for(it = gAuxTasks.begin(); it != gAuxTasks.end(); it++) {
-		InternalAuxiliaryTask *taskStruct = *it;
-
-		if(rt_task_start(&(taskStruct->task), &auxiliaryTaskLoop, taskStruct)) {
-			cerr << "Error: unable to start Xenomai task " << taskStruct->name << endl;
-			return -1;
-		}
+		return BeagleRT_startAuxiliaryTask(*it);
 	}
 
 	return 0;