Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
int _rtapi_exit(int module_id) {
    module_data *module;
    int n;

    if (rtapi_data == NULL) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: exit called before init\n",
			rtapi_instance);
	return -EINVAL;
    }
    rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI:%d module %02d exiting\n",
		    rtapi_instance,module_id);
    /* validate module ID */
    if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) {
	rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI:%d ERROR: bad module id\n",
			rtapi_instance);
	return -EINVAL;
    }
    /* get mutex */
    rtapi_mutex_get(&(rtapi_data->mutex));
    /* point to the module's data */
    module = &(module_array[module_id]);
    /* check module status */
    if (module->state != USERSPACE) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: not a userspace module\n",
			rtapi_instance);
	rtapi_mutex_give(&(rtapi_data->mutex));
	return -EINVAL;
    }
    /* clean up any mess left behind by the module */
    for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) {
	if (rtapi_test_bit(module_id, shmem_array[n].bitmap)) {
	    rtapi_print_msg(RTAPI_MSG_WARN,
			    "ULAPI:%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);
	}
    }
    /* update module data */
    rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI:%d module %02d exited, name = '%s'\n",
		    rtapi_instance, module_id, module->name);
    module->state = NO_MODULE;
    module->name[0] = '\0';
    rtapi_data->ul_module_count--;
    rtapi_mutex_give(&(rtapi_data->mutex));
    return 0;
}
Exemplo n.º 3
0
/*  This function is disabled everywhere...  */
void _rtapi_printall(void) {
    module_data *modules;
    task_data *tasks;
    shmem_data *shmems;
    int n, m;

    if (rtapi_data == NULL) {
	rtapi_print_msg(RTAPI_MSG_DBG, "rtapi_data = NULL, not initialized\n");
	return;
    }
    rtapi_print_msg(RTAPI_MSG_DBG, "rtapi_data = %p\n",
		    rtapi_data);
    rtapi_print_msg(RTAPI_MSG_DBG, "  magic = %d\n",
		    rtapi_data->magic);
    rtapi_print_msg(RTAPI_MSG_DBG, "  serial = %d\n",
		    rtapi_data->serial);
    rtapi_print_msg(RTAPI_MSG_DBG, "  thread_flavor id = %d\n",
		    rtapi_data->thread_flavor_id);
    rtapi_print_msg(RTAPI_MSG_DBG, "  mutex = %lu\n",
		    rtapi_data->mutex);
    rtapi_print_msg(RTAPI_MSG_DBG, "  rt_module_count = %d\n",
		    rtapi_data->rt_module_count);
    rtapi_print_msg(RTAPI_MSG_DBG, "  ul_module_count = %d\n",
		    rtapi_data->ul_module_count);
    rtapi_print_msg(RTAPI_MSG_DBG, "  task_count  = %d\n",
		    rtapi_data->task_count);
    rtapi_print_msg(RTAPI_MSG_DBG, "  shmem_count = %d\n",
		    rtapi_data->shmem_count);
    rtapi_print_msg(RTAPI_MSG_DBG, "  timer_running = %d\n",
		    rtapi_data->timer_running);
    rtapi_print_msg(RTAPI_MSG_DBG, "  timer_period  = %ld\n",
		    rtapi_data->timer_period);
    modules = &(rtapi_data->module_array[0]);
    tasks = &(rtapi_data->task_array[0]);
    shmems = &(rtapi_data->shmem_array[0]);
    rtapi_print_msg(RTAPI_MSG_DBG, "  module array = %p\n",modules);
    rtapi_print_msg(RTAPI_MSG_DBG, "  task array   = %p\n", tasks);
    rtapi_print_msg(RTAPI_MSG_DBG, "  shmem array  = %p\n", shmems);
    for (n = 0; n <= RTAPI_MAX_MODULES; n++) {
	if (modules[n].state != NO_MODULE) {
	    rtapi_print_msg(RTAPI_MSG_DBG, "  module %02d\n", n);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    state = %d\n",
			    modules[n].state);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    name = %p\n",
			    modules[n].name);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    name = '%s'\n",
			    modules[n].name);
	}
    }
    for (n = 0; n <= RTAPI_MAX_TASKS; n++) {
	if (tasks[n].state != EMPTY) {
	    rtapi_print_msg(RTAPI_MSG_DBG, "  task %02d\n", n);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    state = %d\n",
			    tasks[n].state);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    prio  = %d\n",
			    tasks[n].prio);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    owner = %d\n",
			    tasks[n].owner);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    code  = %p\n",
			    tasks[n].taskcode);
	}
    }
    for (n = 0; n <= RTAPI_MAX_SHMEMS; n++) {
	if (shmems[n].key != 0) {
	    rtapi_print_msg(RTAPI_MSG_DBG, "  shmem %02d\n", n);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    key     = %d\n",
			    shmems[n].key);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    rtusers = %d\n",
			    shmems[n].rtusers);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    ulusers = %d\n",
			    shmems[n].ulusers);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    size    = %ld\n",
			    shmems[n].size);
	    rtapi_print_msg(RTAPI_MSG_DBG, "    bitmap  = ");
	    for (m = 0; m <= RTAPI_MAX_MODULES; m++) {
		if (rtapi_test_bit(m, shmems[n].bitmap)) {
		    putchar('1');
		} else {
		    putchar('0');
		}
	    }
	    putchar('\n');
	}
    }
}
Exemplo n.º 4
0
int _rtapi_shmem_delete_inst(int shmem_id, int instance, int module_id) {
    shmem_data *shmem;
    int manage_lock, retval;
#ifdef RTAPI
    struct shm_status sm;
#endif

    /* validate shmem ID */
    if ((shmem_id < 1) || (shmem_id > RTAPI_MAX_SHMEMS)) {
	return -EINVAL;
    }
    /* point to the shmem's data */
    shmem = &(shmem_array[shmem_id]);
    /* is the block valid? */
    if (shmem->key == 0) {
	return -EINVAL;
    }
    /* validate module_id */
    if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) {
	return -EINVAL;
    }
    if (module_array[module_id].state != MODULE_STATE) {
	return -EINVAL;
    }
    /* is this module using the block? */
    if (rtapi_test_bit(module_id, shmem->bitmap) == 0) {
	return -EINVAL;
    }
    /* check if we need to manage the mutex */
    manage_lock = (shmem->magic != SHMEM_MAGIC_DEL_LOCKED);
    /* if no magic delete lock held is set, get the mutex */
    if (manage_lock) rtapi_mutex_get(&(rtapi_data->mutex));
    /* OK, we're no longer using it */
    rtapi_clear_bit(module_id, shmem->bitmap);
#ifdef ULAPI
    shmem->ulusers--;

    if ((shmem->ulusers == 0) && (shmem->rtusers == 0)) {
	// shmdrv can detach unused shared memory from userland too
	// this will munmap() the segment causing a drop in uattach refcount
	// and eventual free by garbage collect in shmdrv
	retval = shm_common_detach(shmem->size, shmem_addr_array[shmem_id]);
	if (retval) {
	    rtapi_print_msg(RTAPI_MSG_ERR,
			    "ULAPI:%d ERROR: shm_common_detach(%02d) failed: %s\n",
			    rtapi_instance, shmem_id, strerror(-retval));
	}
    }
    /* unmap the block */
    shmem_addr_array[shmem_id] = NULL;
#else /* RTAPI */
    shmem->rtusers--;
#endif  /* RTAPI */
    /* is somebody else still using the block? */
    if ((shmem->ulusers > 0) || (shmem->rtusers > 0)) {
	/* yes, we're done for now */
	rtapi_print_msg(RTAPI_MSG_DBG,
	    "RTAPI: shmem %02d closed by module %02d\n", shmem_id, module_id);
	if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex));
	return 0;
    }

#ifdef RTAPI
    /* no other realtime users, free the shared memory from kernel space */
    shmem_addr_array[shmem_id] = NULL;
    shmem->rtusers = 0;
    /* are any user processes using the block? */
    if (shmem->ulusers > 0) {
	/* yes, we're done for now */
	rtapi_print_msg(RTAPI_MSG_DBG,
	    "RTAPI: shmem %02d unmapped by module %02d\n", shmem_id,
	    module_id);
	if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex));
	return 0;
    }

    /* no other users at all, this ID is now free */
    sm.key = shmem->key;
    sm.size = shmem->size;
    sm.flags = 0;
    if ((retval = shmdrv_detach(&sm)) < 0) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI:%d ERROR: shmdrv_detach(%x,%d) fail: %d\n",
			rtapi_instance, sm.key, sm.size, retval);
    }
#endif  /* RTAPI */


    /* update the data array and usage count */
    shmem->key = 0;
    shmem->size = 0;
    rtapi_data->shmem_count--;
    /* release the lock if needed, print a debug message and return */
    if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex));
    rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: shmem %02d freed by module %02d\n",
	shmem_id, module_id);
    return 0;
}
Exemplo n.º 5
0
int _rtapi_shmem_new_inst(int userkey, int instance, int module_id, unsigned long int size) {
    int n, retval;
    int shmem_id;
    shmem_data *shmem;
    struct shm_status sm;

    int key = OS_KEY(userkey, instance);

    /* key must be non-zero, and also cannot match the key that RTAPI uses */
    if ((key == 0) || (key == OS_KEY(RTAPI_KEY, instance))) {
	rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: bad shmem key: %d\n",
			key);
	return -EINVAL;
    }
    /* get the mutex */
    rtapi_mutex_get(&(rtapi_data->mutex));
    /* validate module_id */
    if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) {
	rtapi_mutex_give(&(rtapi_data->mutex));
	rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: bad module ID: %d\n",
			module_id);
	return -EINVAL;
    }
    if (module_array[module_id].state != MODULE_STATE) {
	rtapi_print_msg(RTAPI_MSG_ERR,
			"RTAPI: ERROR: not a " OUR_API " module ID: %d\n",
			module_id);
	rtapi_mutex_give(&(rtapi_data->mutex));
	return -EINVAL;
    }

    /* check if a block is already open for this key */
    for (n = 1; n <= RTAPI_MAX_SHMEMS; n++) {
	if (shmem_array[n].key == key) {
	    /* found a match */
	    shmem_id = n;
	    shmem = &(shmem_array[n]);
	    /* is it big enough? */
	    if (shmem->size < size) {
		rtapi_mutex_give(&(rtapi_data->mutex));
		rtapi_print_msg(RTAPI_MSG_ERR,
				"RTAPI: ERROR: shmem size mismatch\n");
		return -EINVAL;
	    }
	    /* is this module already using it? */
	    if (rtapi_test_bit(module_id, shmem->bitmap)) {
		rtapi_mutex_give(&(rtapi_data->mutex));
		rtapi_print_msg(RTAPI_MSG_WARN,
				"RTAPI: Warning: shmem already mapped\n");
		return -EEXIST;
	    }
	    /* yes, has it been mapped into kernel space? */
#ifdef RTAPI
	    if (shmem->rtusers == 0) {
#endif
		/* no, map it and save the address */
		sm.key = key;
		sm.size = size;
		sm.flags = 0;
#ifdef ULAPI
		sm.driver_fd = shmdrv_driver_fd();
#endif
		retval = shmdrv_attach(&sm, &shmem_addr_array[shmem_id]);
		if (retval < 0) {
		    rtapi_mutex_give(&(rtapi_data->mutex));
		    rtapi_print_msg(RTAPI_MSG_ERR,
				    "shmdrv attached failed key=0x%x size=%ld\n", key, size);
		    return retval;
		}
		if (shmem_addr_array[shmem_id] == NULL) {
		    rtapi_print_msg(RTAPI_MSG_ERR,
				    "RTAPI: ERROR: failed to map shmem\n");
		    rtapi_mutex_give(&(rtapi_data->mutex));
#ifdef ULAPI
		    check_memlock_limit("failed to map shmem");
#endif
		    return -ENOMEM;
		}
#ifdef RTAPI
	    }
#endif
	    /* update usage data */
	    rtapi_set_bit(module_id, shmem->bitmap);
#ifdef ULAPI
	    shmem->ulusers++;
#else  /* RTAPI */
	    shmem->rtusers++;
#endif  /* RTAPI */
	    /* announce another user for this shmem */
	    rtapi_print_msg(RTAPI_MSG_DBG,
		"RTAPI: shmem %02d opened by module %02d\n",
		shmem_id, module_id);
	    /* done */
	    rtapi_mutex_give(&(rtapi_data->mutex));
	    return shmem_id;
	}
    }
    /* find empty spot in shmem array */
    n = 1;
    while ((n <= RTAPI_MAX_SHMEMS) && (shmem_array[n].key != 0)) {
	rtapi_print_msg(RTAPI_MSG_DBG, OUR_API ": shmem %d occupuied \n",n);
	n++;
    }
    if (n > RTAPI_MAX_SHMEMS) {
	/* no room */
	rtapi_mutex_give(&(rtapi_data->mutex));
	rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI: ERROR: reached shmem limit %d\n",
	    n);
	return -EMFILE;
    }
    /* we have space for the block data */
    rtapi_print_msg(RTAPI_MSG_DBG, OUR_API ": using new shmem %d  \n",n);
    shmem_id = n;
    shmem = &(shmem_array[n]);

    /* get shared memory block from OS and save its address */
    sm.key = key;
    sm.size = size;
    sm.flags = 0;
#ifdef ULAPI
    sm.driver_fd = shmdrv_driver_fd();
#endif
    retval = shmdrv_create(&sm);
    if (retval < 0) {
	rtapi_mutex_give(&(rtapi_data->mutex));
	rtapi_print_msg(RTAPI_MSG_ERR,"shmdrv create failed key=0x%x size=%ld\n", key, size);
	return retval;
    }
    retval = shmdrv_attach(&sm, &shmem_addr_array[shmem_id]);
    if (retval < 0) {
	rtapi_mutex_give(&(rtapi_data->mutex));
	rtapi_print_msg(RTAPI_MSG_ERR,"shmdrv attached failed key=0x%x size=%ld\n", key, size);
	return retval;
    }
    if (shmem_addr_array[shmem_id] == NULL) {
	rtapi_mutex_give(&(rtapi_data->mutex));
	rtapi_print_msg(RTAPI_MSG_ERR,
	    "RTAPI: ERROR: could not create shmem %d\n", n);
	return -ENOMEM;
    }
    /* the block has been created, update data */
    rtapi_set_bit(module_id, shmem->bitmap);
    shmem->key = key;
#ifdef RTAPI
    shmem->rtusers = 1;
    shmem->ulusers = 0;
#else /* ULAPI */
    shmem->rtusers = 0;
    shmem->ulusers = 1;
#endif  /* ULAPI */
    shmem->size = size;
    shmem->magic = SHMEM_MAGIC;
    shmem->instance = instance;
    rtapi_data->shmem_count++;

    /* zero the first word of the shmem area */
    *((long int *) (shmem_addr_array[shmem_id])) = 0;
    /* announce the birth of a brand new baby shmem */
    rtapi_print_msg(RTAPI_MSG_DBG,
	"RTAPI: shmem %02d created by module %02d, key: %d, size: %lu\n",
	shmem_id, module_id, key, size);

    /* and return the ID to the proud parent */
    rtapi_mutex_give(&(rtapi_data->mutex));
    return shmem_id;
}