int hal_del_funct_from_thread(const char *funct_name, const char *thread_name) { hal_funct_t *funct; hal_list_t *list_root, *list_entry; hal_funct_entry_t *funct_entry; CHECK_HALDATA(); CHECK_LOCK(HAL_LOCK_CONFIG); CHECK_STR(funct_name); CHECK_STR(thread_name); HALDBG("removing function '%s' from thread '%s'", funct_name, thread_name); { hal_thread_t *thread __attribute__((cleanup(halpr_autorelease_mutex))); /* get mutex before accessing data structures */ rtapi_mutex_get(&(hal_data->mutex)); /* search function list for the function */ funct = halpr_find_funct_by_name(funct_name); if (funct == 0) { HALERR("function '%s' not found", funct_name); return -EINVAL; } /* found the function, is it in use? */ if (funct->users == 0) { HALERR("function '%s' is not in use", funct_name); return -EINVAL; } /* search thread list for thread_name */ thread = halpr_find_thread_by_name(thread_name); if (thread == 0) { /* thread not found */ HALERR("thread '%s' not found", thread_name); return -EINVAL; } /* ok, we have thread and function, does thread use funct? */ list_root = &(thread->funct_list); list_entry = list_next(list_root); while (1) { if (list_entry == list_root) { /* reached end of list, funct not found */ HALERR("thread '%s' doesn't use %s", thread_name, funct_name); return -EINVAL; } funct_entry = (hal_funct_entry_t *) list_entry; if (SHMPTR(funct_entry->funct_ptr) == funct) { /* this funct entry points to our funct, unlink */ list_remove_entry(list_entry); /* and delete it */ free_funct_entry_struct(funct_entry); /* done */ return 0; } /* try next one */ list_entry = list_next(list_entry); } } }
int hal_call_usrfunct(const char *name, const int argc, const char **argv, int *ureturn) { hal_funct_t *funct; CHECK_HALDATA(); CHECK_STR(name); if (argc && (argv == NULL)) { HALERR("funct '%s': argc=%d but argv is NULL", name, argc); return -EINVAL; } { int i __attribute__((cleanup(halpr_autorelease_mutex))); rtapi_mutex_get(&(hal_data->mutex)); funct = halpr_find_funct_by_name(name); if (funct == NULL) { HALERR("funct '%s' not found", name); return -ENOENT; } if (funct->type != FS_USERLAND) { HALERR("funct '%s': invalid type %d", name, funct->type); return -ENOENT; } // argv sanity check - we dont want to fail this, esp in kernel land for (i = 0; i < argc; i++) { if (argv[i] == NULL) { HALERR("funct '%s': argc=%d but argv[%d] is NULL", name, i, i); return -EINVAL; } } } // call the function with rtapi_mutex unlocked long long int now = rtapi_get_clocks(); hal_funct_args_t fa = { .thread_start_time = now, .start_time = now, .thread = NULL, .funct = funct, .argc = argc, .argv = argv, }; int retval = funct->funct.u(&fa); if (ureturn) *ureturn = retval; return 0; }
int hal_add_funct_to_thread(const char *funct_name, const char *thread_name, int position) { hal_funct_t *funct; hal_list_t *list_root, *list_entry; int n; hal_funct_entry_t *funct_entry; CHECK_HALDATA(); CHECK_LOCK(HAL_LOCK_CONFIG); CHECK_STR(funct_name); CHECK_STR(thread_name); HALDBG("adding function '%s' to thread '%s'", funct_name, thread_name); { hal_thread_t *thread __attribute__((cleanup(halpr_autorelease_mutex))); /* get mutex before accessing data structures */ rtapi_mutex_get(&(hal_data->mutex)); /* make sure position is valid */ if (position == 0) { /* zero is not allowed */ HALERR("bad position: 0"); return -EINVAL; } /* search function list for the function */ funct = halpr_find_funct_by_name(funct_name); if (funct == 0) { HALERR("function '%s' not found", funct_name); return -EINVAL; } // type-check the functions which go onto threads switch (funct->type) { case FS_LEGACY_THREADFUNC: case FS_XTHREADFUNC: break; default: HALERR("cant add type %d function '%s' " "to a thread", funct->type, funct_name); return -EINVAL; } /* found the function, is it available? */ if ((funct->users > 0) && (funct->reentrant == 0)) { HALERR("function '%s' may only be added " "to one thread", funct_name); return -EINVAL; } /* search thread list for thread_name */ thread = halpr_find_thread_by_name(thread_name); if (thread == 0) { /* thread not found */ HALERR("thread '%s' not found", thread_name); return -EINVAL; } #if 0 /* ok, we have thread and function, are they compatible? */ if ((funct->uses_fp) && (!thread->uses_fp)) { HALERR("function '%s' needs FP", funct_name); return -EINVAL; } #endif /* find insertion point */ list_root = &(thread->funct_list); list_entry = list_root; n = 0; if (position > 0) { /* insertion is relative to start of list */ while (++n < position) { /* move further into list */ list_entry = list_next(list_entry); if (list_entry == list_root) { /* reached end of list */ HALERR("position '%d' is too high", position); return -EINVAL; } } } else { /* insertion is relative to end of list */ while (--n > position) { /* move further into list */ list_entry = list_prev(list_entry); if (list_entry == list_root) { /* reached end of list */ HALERR("position '%d' is too low", position); return -EINVAL; } } /* want to insert before list_entry, so back up one more step */ list_entry = list_prev(list_entry); } /* allocate a funct entry structure */ funct_entry = alloc_funct_entry_struct(); if (funct_entry == 0) NOMEM("thread->function link"); /* init struct contents */ funct_entry->funct_ptr = SHMOFF(funct); funct_entry->arg = funct->arg; funct_entry->funct.l = funct->funct.l; funct_entry->type = funct->type; /* add the entry to the list */ list_add_after((hal_list_t *) funct_entry, list_entry); /* update the function usage count */ funct->users++; } return 0; }
int main(int argc, gchar * argv[]) { int retval; int num_samples = SCOPE_NUM_SAMPLES_DEFAULT; void *shm_base; /* process and remove any GTK specific command line args */ gtk_init(&argc, &argv); /* process halscope command line args (if any) here */ if(argc > 1) num_samples = atoi(argv[1]); if(num_samples <= 0) num_samples = SCOPE_NUM_SAMPLES_DEFAULT; /* connect to the HAL */ comp_id = hal_init("halscope"); if (comp_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: hal_init() failed\n"); return -1; } if (!halpr_find_funct_by_name("scope.sample")) { char buf[1000]; sprintf(buf, EMC2_BIN_DIR "/halcmd loadrt scope_rt num_samples=%d", num_samples); if(system(buf) != 0) { rtapi_print_msg(RTAPI_MSG_ERR, "loadrt scope_rt failed\n"); hal_exit(comp_id); exit(1); } } /* set up a shared memory region for the scope data */ shm_id = rtapi_shmem_new(SCOPE_SHM_KEY, comp_id, sizeof(scope_shm_control_t)); if (shm_id < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: failed to get shared memory\n"); hal_exit(comp_id); return -1; } retval = rtapi_shmem_getptr(shm_id, &shm_base); if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "SCOPE: ERROR: failed to map shared memory\n"); rtapi_shmem_delete(shm_id, comp_id); hal_exit(comp_id); return -1; } hal_ready(comp_id); /* register an exit function to cleanup and disconnect from the HAL */ g_atexit(exit_from_hal); /* init control structure */ ctrl_usr = &ctrl_struct; init_usr_control_struct(shm_base); /* init watchdog */ ctrl_shm->watchdog = 10; /* set main window */ define_scope_windows(); /* this makes the application exit when the window is closed */ gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "destroy", GTK_SIGNAL_FUNC(main_window_closed), NULL); gtk_signal_connect(GTK_OBJECT(ctrl_usr->main_win), "focus-in-event", GTK_SIGNAL_FUNC(set_focus), NULL); /* define menu windows */ /* do next level of init */ init_horiz(); init_vert(); init_trig(); init_display(); init_run_mode_window(); /* register signal handlers for ctrl-C and SIGTERM */ signal(SIGINT, quit); signal(SIGTERM, quit); /* The interface is now completely set up */ /* show the window */ gtk_widget_show(ctrl_usr->main_win); /* read the saved config file */ read_config_file(".scope.cfg"); /* arrange for periodic call of heartbeat() */ gtk_timeout_add(100, heartbeat, NULL); /* enter the main loop */ gtk_main(); write_config_file(".scope.cfg"); return (0); }