/** * @brief register task with handle * Here we assume the state has been initialized. * We just need to link to the bin */ static int8_t sched_register_module(sos_module_t *h, mod_header_ptr p, void *init, uint8_t init_size) { HAS_CRITICAL_SECTION; uint8_t num_timers; uint8_t bins = hash_pid(h->pid); if(ker_get_module(h->pid) != NULL) { return -EEXIST; //ker_deregister_module(h->pid); DEBUG("Module %d is already registered\n", h->pid); } //! Read the number of timers to be pre-allocated num_timers = sos_read_header_byte(p, offsetof(mod_header_t, num_timers)); if (num_timers > 0){ //! If there is no memory to pre-allocate the requested timers if (timer_preallocate(h->pid, num_timers) < 0){ return -ENOMEM; } } // link the functions fntable_link(h); ENTER_CRITICAL_SECTION(); /** * here is critical section. * We need to prevent others to search this module */ // add to the bin h->next = mod_bin[bins]; mod_bin[bins] = h; LEAVE_CRITICAL_SECTION(); DEBUG("Register %d, Code ID %d, Handle = %x\n", h->pid, sos_read_header_byte(h, offsetof(mod_header_t, mod_id)), (unsigned int)h); // send an init message to application // XXX : need to check the failure if(post_long(h->pid, KER_SCHED_PID, MSG_INIT, init_size, init, SOS_MSG_RELEASE | SOS_MSG_SYSTEM_PRIORITY) != SOS_OK) { timer_remove_all(h->pid); return -ENOMEM; } return SOS_OK; }
int8_t timer_micro_reboot(sos_module_t *handle){ sos_pid_t pid; list_link_t *link; mod_header_ptr hdr; uint8_t num_timers_left; pid = handle->pid; hdr = handle->header; num_timers_left = sos_read_header_byte(hdr, offsetof(mod_header_t, num_timers)); DEBUG("Timer: Pre-alloc timers requested %d \n", num_timers_left); if (num_timers_left > 0){ for (link = prealloc_timer_pool.l_next; link != (&prealloc_timer_pool); link = link->l_next){ sos_timer_t *h = (sos_timer_t*)link; if (h->pid == pid) num_timers_left--; // Assert - This value should NEVER become negative } } DEBUG("Timer: Timers left to pre-allocate %d \n", num_timers_left); //! Stop all timers of pid //! Move timer blocks to the pre-allocated pool //! or free them for (link = deltaq.l_next; link != (&deltaq); link = link->l_next){ sos_timer_t *h = (sos_timer_t*)link; if (h->pid == pid){ link = link->l_prev; timer_remove_timer(h); if (num_timers_left > 0){ num_timers_left--; timer_pre_alloc_block_init(h, pid); DEBUG("Timer: Allocated active timer \n"); } else ker_free(h); } } //! Remove all initialized timers //! Move timer blocks to the pre-allocated pool //! or free them for (link = timer_pool.l_next; link != (&timer_pool); link = link->l_next){ sos_timer_t *h = (sos_timer_t*)link; if (h->pid == pid){ link = link->l_prev; list_remove((list_link_t*)h); if (num_timers_left > 0){ num_timers_left--; timer_pre_alloc_block_init(h, pid); DEBUG("Timer: Allocated an initialzed but non-running timer\n"); } else ker_free(h); } } //! If necessary, allocate memory for the pre-allocated timers if (num_timers_left > 0){ DEBUG("Timer: Alloc more memory for timers\n"); if (timer_preallocate(pid, num_timers_left) != SOS_OK) return -ENOMEM; } return SOS_OK; }