static int module_delete(int module_id) { module_data *module; char name[RTAPI_NAME_LEN + 1]; int n; rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI:%d module %d exiting\n", rtapi_instance, module_id); /* validate module ID */ if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) { return -EINVAL; } /* point to the module's data */ module = &(module_array[module_id]); /* check module status */ if (module->state != REALTIME) { /* not an active realtime module */ return -EINVAL; } /* clean up any mess left behind by the module */ for (n = 1; n <= RTAPI_MAX_TASKS; n++) { if ((task_array[n].state != EMPTY) && (task_array[n].owner == module_id)) { rtapi_print_msg(RTAPI_MSG_WARN, "RTAPI:%d WARNING: module '%s' failed to delete task %02d\n", rtapi_instance, module->name, n); task_array[n].state = DELETE_LOCKED; _rtapi_task_delete(n); } } for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) { if (rtapi_test_bit(module_id, shmem_array[n].bitmap)) { rtapi_print_msg(RTAPI_MSG_WARN, "RTAPI:%d WARNING: module '%s' failed to delete shmem %02d\n", rtapi_instance, module->name, n); // mark block as ready for delete, lock already held shmem_array[n].magic = SHMEM_MAGIC_DEL_LOCKED; _rtapi_shmem_delete(n, module_id); } } rtapi_snprintf(name, RTAPI_NAME_LEN, "%s", module->name); /* update module data */ module->state = NO_MODULE; module->name[0] = '\0'; rtapi_data->rt_module_count--; if (rtapi_data->rt_module_count == 0) { if (rtapi_data->timer_running != 0) { #ifdef HAVE_RTAPI_MODULE_TIMER_STOP _rtapi_module_timer_stop(); #endif rtapi_data->timer_period = 0; timer_counts = 0; max_delay = DEFAULT_MAX_DELAY; rtapi_data->timer_running = 0; } } rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI:%d module %d exited, name: '%s'\n", rtapi_instance, module_id, name); return 0; }
int _rtapi_task_delete(int task_id) { task_data *task; int retval = 0; if(task_id < 0 || task_id >= RTAPI_MAX_TASKS) return -EINVAL; task = &(task_array[task_id]); /* validate task handle */ if (task->magic != TASK_MAGIC) // nothing to delete return -EINVAL; if (task->state != DELETE_LOCKED) // we don't already hold mutex rtapi_mutex_get(&(rtapi_data->mutex)); #ifdef MODULE if ((task->state == PERIODIC) || (task->state == FREERUN)) { /* task is running, need to stop it */ rtapi_print_msg(RTAPI_MSG_WARN, "RTAPI: WARNING: tried to delete task %02d while running\n", task_id); _rtapi_task_pause(task_id); } /* get rid of it */ rt_task_delete(ostask_array[task_id]); /* free kernel memory */ kfree(ostask_array[task_id]); /* update data */ task->prio = 0; task->owner = 0; task->taskcode = NULL; ostask_array[task_id] = NULL; rtapi_data->task_count--; /* if no more tasks, stop the timer */ if (rtapi_data->task_count == 0) { if (rtapi_data->timer_running != 0) { # ifdef HAVE_RTAPI_MODULE_TIMER_STOP _rtapi_module_timer_stop(); # endif rtapi_data->timer_period = 0; max_delay = DEFAULT_MAX_DELAY; rtapi_data->timer_running = 0; } } #endif /* MODULE */ #ifdef HAVE_RTAPI_TASK_DELETE_HOOK retval = _rtapi_task_delete_hook(task,task_id); #endif if (task->state != DELETE_LOCKED) // we don't already hold mutex rtapi_mutex_give(&(rtapi_data->mutex)); task->state = EMPTY; task->magic = 0; rtapi_print_msg(RTAPI_MSG_DBG, "rt_task_delete %d \"%s\"\n", task_id, task->name ); return retval; }
void cleanup_module(void) { int n; struct shm_status sm; int retval; if (rtapi_data == NULL) { /* never got inited, nothing to do */ return; } #ifdef HAVE_RTAPI_MODULE_EXIT_HOOK _rtapi_module_exit_hook(); #endif /* grab the mutex */ rtapi_mutex_get(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d exit\n", rtapi_instance); /* clean up leftover modules (start at 1, we don't use ID 0 */ for (n = 1; n <= RTAPI_MAX_MODULES; n++) { if (module_array[n].state == REALTIME) { rtapi_print_msg(RTAPI_MSG_WARN, "RTAPI: WARNING: module '%s' (ID: %02d) did not " "call rtapi_exit()\n", module_array[n].name, n); module_delete(n); } } /* cleaning up modules should clean up everything, if not there has probably been an unrecoverable internal error.... */ for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) { if (shmem_array[n].rtusers > 0) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: shared memory block %02d not deleted\n", n); } } for (n = 1; n <= RTAPI_MAX_TASKS; n++) { if (task_array[n].state != EMPTY) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: task %02d not deleted\n", n); /* probably un-recoverable, but try anyway */ _rtapi_task_pause(n); /* rtapi_task_delete should not grab mutex */ task_array[n].state = DELETE_LOCKED; _rtapi_task_delete(n); } } if (rtapi_data->timer_running != 0) { #ifdef HAVE_RTAPI_MODULE_TIMER_STOP _rtapi_module_timer_stop(); #endif rtapi_data->timer_period = 0; timer_counts = 0; rtapi_data->timer_running = 0; max_delay = DEFAULT_MAX_DELAY; } rtapi_mutex_give(&(rtapi_data->mutex)); #ifdef CONFIG_PROC_FS proc_clean(); #endif sm.key = OS_KEY(RTAPI_KEY, rtapi_instance); sm.size = sizeof(rtapi_data_t); sm.flags = 0; if ((retval = shmdrv_detach(&sm)) < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI:%d ERROR: detach rtapi returns %d\n", rtapi_instance, retval); } rtapi_data = NULL; global_data->rtapi_messages.refcount -= 1; // detach rtapi end sm.key = OS_KEY(GLOBAL_KEY, rtapi_instance); sm.size = sizeof(global_data_t); sm.flags = 0; if ((retval = shmdrv_detach(&sm)) < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI:%d ERROR: detach global returns %d\n", rtapi_instance, retval); } global_data = NULL; rtapi_print_msg(RTAPI_MSG_INFO, "RTAPI:%d Exit complete\n", rtapi_instance); return; }