@@ -195,77 +195,56 @@ static void executor_init(char* student_code) {
195195 * 3: Timed out by executor
196196 * 4: Unable to find the given function in the student code
197197 */
198- static uint8_t run_py_function (const char * func_name , struct timespec * timeout , int loop , PyObject * args , PyObject * * py_ret ) {
198+ static uint8_t run_py_function (const char * func_name , struct timespec * timeout , PyObject * args , PyObject * * py_ret ) {
199199 uint8_t ret = 0 ;
200200
201201 // retrieve the Python function from the student code
202202 PyObject * pFunc = PyObject_GetAttrString (pModule , func_name );
203203 PyObject * pValue = NULL ;
204+ log_printf (ERROR , "%s" , func_name );
204205 if (pFunc && PyCallable_Check (pFunc )) {
205- struct timespec start , end ;
206- uint64_t time , max_time = 0 ;
207- if (timeout != NULL ) {
208- max_time = timeout -> tv_sec * 1e9 + timeout -> tv_nsec ;
206+ pValue = PyObject_CallObject (pFunc , args ); // make call to Python function
207+
208+ // Set return value
209+ if (py_ret != NULL ) {
210+ Py_XDECREF (* py_ret ); // Decrement previous reference, if it exists
211+ * py_ret = pValue ;
212+ } else {
213+ Py_XDECREF (pValue );
209214 }
210215
211- do {
212- clock_gettime (CLOCK_MONOTONIC , & start );
213- pValue = PyObject_CallObject (pFunc , args ); // make call to Python function
214- clock_gettime (CLOCK_MONOTONIC , & end );
215-
216- // if the time the Python function took was greater than max_time, warn that it's taking too long
217- time = (end .tv_sec - start .tv_sec ) * 1e9 + (end .tv_nsec - start .tv_nsec );
218- if (timeout != NULL && time > max_time ) {
219- log_printf (WARN , "Function %s is taking longer than %lu milliseconds, indicating a loop or sleep in the code. You probably forgot to put a Robot.sleep call into a robot action instead of a regular function." , func_name , (long ) (max_time / 1e6 ));
220- }
221- // if the time the Python function took was less than min_time, sleep to slow down execution
222- if (time < min_time ) {
223- usleep ((min_time - time ) / 1000 ); // Need to convert nanoseconds to microseconds
224- }
225-
226- // Set return value
227- if (py_ret != NULL ) {
228- Py_XDECREF (* py_ret ); // Decrement previous reference, if it exists
229- * py_ret = pValue ;
216+ // catch execution error
217+ if (pValue == NULL ) {
218+ if (!PyErr_ExceptionMatches (PyExc_TimeoutError )) {
219+ PyErr_Print ();
220+ log_printf (ERROR , "Python function %s call failed" , func_name );
221+ ret = 2 ;
230222 } else {
231- Py_XDECREF ( pValue );
223+ ret = 3 ; // Timed out by parent process
232224 }
233-
234- // catch execution error
235- if (pValue == NULL ) {
225+ } else if (mode == AUTO || mode == TELEOP ) {
226+ // Need to check if error occurred in action thread
227+ PyObject * event = PyObject_GetAttrString (pRobot , "error_event" );
228+ if (event == NULL ) {
229+ PyErr_Print ();
230+ log_printf (ERROR , "Could not get error_event from Robot instance" );
231+ exit (2 );
232+ }
233+ PyObject * event_set = PyObject_CallMethod (event , "is_set" , NULL );
234+ if (event_set == NULL ) {
236235 if (!PyErr_ExceptionMatches (PyExc_TimeoutError )) {
237236 PyErr_Print ();
238- log_printf (ERROR , "Python function %s call failed" , func_name );
239- ret = 2 ;
237+ log_printf (DEBUG , "Could not get if error is set from error_event" );
238+ exit ( 2 ) ;
240239 } else {
241240 ret = 3 ; // Timed out by parent process
242241 }
243- break ;
244- } else if (mode == AUTO || mode == TELEOP ) {
245- // Need to check if error occurred in action thread
246- PyObject * event = PyObject_GetAttrString (pRobot , "error_event" );
247- if (event == NULL ) {
248- PyErr_Print ();
249- log_printf (ERROR , "Could not get error_event from Robot instance" );
250- exit (2 );
251- }
252- PyObject * event_set = PyObject_CallMethod (event , "is_set" , NULL );
253- if (event_set == NULL ) {
254- if (!PyErr_ExceptionMatches (PyExc_TimeoutError )) {
255- PyErr_Print ();
256- log_printf (DEBUG , "Could not get if error is set from error_event" );
257- exit (2 );
258- } else {
259- ret = 3 ; // Timed out by parent process
260- }
261- break ;
262- } else if (PyObject_IsTrue (event_set ) == 1 ) {
263- log_printf (ERROR , "Stopping %s due to error in action" , func_name );
264- ret = 1 ;
265- break ;
266- }
242+ } else if (PyObject_IsTrue (event_set ) == 1 ) {
243+ log_printf (ERROR , "Stopping %s due to error in action" , func_name );
244+ ret = 1 ;
267245 }
268- } while (loop );
246+ }
247+
269248 Py_DECREF (pFunc );
270249 } else {
271250 if (PyErr_Occurred ()) {
@@ -278,32 +257,6 @@ static uint8_t run_py_function(const char* func_name, struct timespec* timeout,
278257}
279258
280259
281- /**
282- * Begins the given game mode and calls setup and main appropriately. Will run main forever.
283- *
284- * Behavior: This is a blocking function and will block the calling thread forever.
285- * This should only be run as a separate thread.
286- *
287- * Inputs:
288- * args: string of the mode to start running
289- */
290- static void run_mode (robot_desc_val_t mode ) {
291- // Set up the arguments to the threads that will run the setup and main threads
292- char * mode_str = get_mode_str (mode );
293- char setup_str [20 ], main_str [20 ];
294- sprintf (setup_str , "%s_setup" , mode_str );
295- sprintf (main_str , "%s_main" , mode_str );
296-
297- int err = run_py_function (setup_str , & setup_time , 0 , NULL , NULL ); // Run setup function once
298- if (err == 0 ) {
299- err = run_py_function (main_str , & main_interval , 1 , NULL , NULL ); // Run main function on loop
300- } else {
301- log_printf (WARN , "Won't run %s due to error %d in %s" , main_str , err , setup_str );
302- }
303- return ;
304- }
305-
306-
307260/**
308261 * Handler for killing the child mode subprocess
309262 */
@@ -361,7 +314,12 @@ static pid_t start_mode_subprocess(char* student_code) {
361314 signal (SIGINT , SIG_IGN ); // Disable Ctrl+C for child process
362315 executor_init (student_code );
363316 signal (SIGTERM , python_exit_handler ); // Set handler for killing subprocess
364- run_mode (mode );
317+
318+ char * mode_str = get_mode_str (mode );
319+ int err = run_py_function (mode_str , & main_interval , NULL , NULL ); // Run main function
320+ if (err ) {
321+ log_printf (WARN , "NEED TO EDIT STATEMENT" ); // "Problem Child"
322+ }
365323 exit (0 );
366324 return pid ; // Never reach this statement due to exit, needed to fix compiler warning
367325 } else {
0 commit comments