Exemplo n.º 1
0
Arquivo: sched.c Projeto: nesl/umpu
/**
 * @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;
}
Exemplo n.º 2
0
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;
}