void init_global_data(global_data_t * data, int flavor, int instance_id, int hal_size, int rt_level, int user_level, const char *name, int stack_size) { // force-lock - we're first, so thats a bit theoretical rtapi_mutex_try(&(data->mutex)); // touch all memory exposed to RT memset(data, 0, sizeof(global_data_t)); // lock the global data segment if (flavor != RTAPI_POSIX_ID) { if (mlock(data, sizeof(global_data_t))) { syslog_async(LOG_ERR, "MSGD:%d mlock(global) failed: %d '%s'\n", instance_id, errno,strerror(errno)); } } // report progress data->magic = GLOBAL_INITIALIZING; /* set version code so other modules can check it */ data->layout_version = GLOBAL_LAYOUT_VERSION; data->instance_id = instance_id; if ((name == NULL) || (strlen(name) == 0)) { snprintf(data->instance_name, sizeof(data->instance_name), "inst%d",rtapi_instance); } else { strncpy(data->instance_name,name, sizeof(data->instance_name)); } // separate message levels for RT and userland data->rt_msg_level = rt_level; data->user_msg_level = user_level; // next value returned by rtapi_init (userland threads) // those dont use fixed sized arrays // start at 1 because the meaning of zero is special data->next_module_id = 1; // tell the others what we determined as the proper flavor data->rtapi_thread_flavor = flavor; // HAL segment size data->hal_size = hal_size; // stack size passed to rtapi_task_new() in hal_create_thread() data->hal_thread_stack_size = stack_size; // init the error ring ringheader_init(&data->rtapi_messages, 0, SIZE_ALIGN(MESSAGE_RING_SIZE), 0); memset(&data->rtapi_messages.buf[0], 0, SIZE_ALIGN(MESSAGE_RING_SIZE)); // attach to the message ringbuffer ringbuffer_init(&data->rtapi_messages, &rtapi_msg_buffer); rtapi_msg_buffer.header->refcount = 1; // rtapi not yet attached rtapi_msg_buffer.header->reader = getpid(); data->rtapi_messages.use_wmutex = 1; // locking hint // demon pids data->rtapi_app_pid = -1; // not yet started data->rtapi_msgd_pid = 0; /* done, release the mutex */ rtapi_mutex_give(&(data->mutex)); return; }
int hal_ring_new(const char *name, int size, int sp_size, int mode) { hal_ring_t *rbdesc; int *prev, next, cmp, retval; int ring_id; ringheader_t *rhptr; CHECK_HALDATA(); CHECK_STRLEN(name, HAL_NAME_LEN); CHECK_LOCK(HAL_LOCK_LOAD); { hal_ring_t *ptr __attribute__((cleanup(halpr_autorelease_mutex))); rtapi_mutex_get(&(hal_data->mutex)); // make sure no such ring name already exists if ((ptr = halpr_find_ring_by_name(name)) != 0) { HALERR("ring '%s' already exists", name); return -EEXIST; } // allocate a new ring id - needed since we dont track ring shm // segments in RTAPI if ((ring_id = next_ring_id()) < 0) { HALERR("cant allocate new ring id for '%s'", name); return -ENOMEM; } // allocate a new ring descriptor if ((rbdesc = alloc_ring_struct()) == 0) NOMEM("ring '%s'", name); rbdesc->handle = rtapi_next_handle(); rbdesc->flags = mode; rbdesc->ring_id = ring_id; // make total allocation fit ringheader, ringbuffer and scratchpad rbdesc->total_size = ring_memsize( rbdesc->flags, size, sp_size); if (rbdesc->flags & ALLOC_HALMEM) { void *ringmem = shmalloc_up(rbdesc->total_size); if (ringmem == NULL) NOMEM("ring '%s' size %d - insufficient HAL memory for ring", name,rbdesc->total_size); rbdesc->ring_offset = SHMOFF(ringmem); rhptr = ringmem; } else { // allocate shared memory segment for ring and init rbdesc->ring_shmkey = OS_KEY((RTAPI_RING_SHM_KEY + ring_id), rtapi_instance); int shmid; // allocate an RTAPI shm segment owned by HAL_LIB_xxx if ((shmid = rtapi_shmem_new(rbdesc->ring_shmkey, lib_module_id, rbdesc->total_size)) < 0) NOMEM("rtapi_shmem_new(0x%8.8x,%d) failed: %d", rbdesc->ring_shmkey, lib_module_id, rbdesc->total_size); // map the segment now so we can fill in the ringheader details if ((retval = rtapi_shmem_getptr(shmid, (void **)&rhptr, 0)) < 0) NOMEM("rtapi_shmem_getptr for %d failed %d", shmid, retval); } HALDBG("created ring '%s' in %s, total_size=%d", name, (rbdesc->flags & ALLOC_HALMEM) ? "halmem" : "shm", rbdesc->total_size); ringheader_init(rhptr, rbdesc->flags, size, sp_size); rhptr->refcount = 0; // on hal_ring_attach: increase; on hal_ring_detach: decrease rtapi_snprintf(rbdesc->name, sizeof(rbdesc->name), "%s", name); rbdesc->next_ptr = 0; // search list for 'name' and insert new structure prev = &(hal_data->ring_list_ptr); next = *prev; while (1) { if (next == 0) { /* reached end of list, insert here */ rbdesc->next_ptr = next; *prev = SHMOFF(rbdesc); return 0; } ptr = SHMPTR(next); cmp = strcmp(ptr->name, rbdesc->name); if (cmp > 0) { /* found the right place for it, insert here */ rbdesc->next_ptr = next; *prev = SHMOFF(rbdesc); return 0; } /* didn't find it yet, look at next one */ prev = &(ptr->next_ptr); next = *prev; } // automatic unlock by scope exit } }