Exemplo n.º 1
0
Arquivo: slab.c Projeto: nesl/sos-2x
int8_t ker_slab_init( sos_pid_t pid, slab_t *slab, uint8_t item_size, uint8_t items_per_pool, uint8_t flag )
{
	uint8_t i;
	if( items_per_pool > 8 ) {
		return -EINVAL;
	}
	
	//
	// build empty vector
	//
	slab->head = NULL;
	slab->num_items_per_pool = items_per_pool;
	slab->empty_vector = 0;
	slab->item_size = item_size;
	slab->flag = flag;
	for( i = 0; i < items_per_pool; i++ ) {
		slab->empty_vector <<= 1;
		slab->empty_vector |= 0x01;
	}
	
	if( slab->flag & SLAB_LONGTERM ) {
		slab->head = malloc_longterm( sizeof( slab_item_t ) + items_per_pool * item_size, pid );
	} else {
		slab->head = ker_malloc( sizeof( slab_item_t ) + items_per_pool * item_size, pid );
	}
	
	if( slab->head == NULL ) {
		return -ENOMEM;
	}
	slab->head->next = NULL;
	slab->head->alloc = 0;
	slab->head->gc_mark = 0;
	return SOS_OK;
}
Exemplo n.º 2
0
/**
 * @brief Pre-allocate timers for a module at load time
 */
int8_t timer_preallocate(sos_pid_t pid, uint8_t num_timers)
{
   // We have already checked if num_timer > 0 and pid is not NULL_PID

  uint8_t i, j;
  sos_timer_t* tt[MAX_PRE_ALLOCATED_TIMERS];
   
  //! We cannot allow a single module to pre allocate a lot of timers
  if (num_timers > MAX_PRE_ALLOCATED_TIMERS)
	return -EINVAL;
  
  //! First try to safely allocate memory blocks for all the pre-allocated timers
  for (i = 0; i < num_timers; i++){
	tt[i] = (sos_timer_t*)malloc_longterm(sizeof(sos_timer_t), TIMER_PID);
	if (tt[i] == NULL){
	  for (j = 0; j < i; j++){
		ker_free(tt[j]);
	  }
	  return -ENOMEM;
	}   
  }
  
   //! If we get here then we have all the memory allocated
   //! Now initialize all the data structures and just add them to the timer pool
  for (i = 0; i < num_timers; i++){
	timer_pre_alloc_block_init(tt[i], pid);
  }
  
  return SOS_OK;
}
Exemplo n.º 3
0
Arquivo: slab.c Projeto: nesl/sos-2x
void* ker_slab_alloc( slab_t *slab, sos_pid_t pid )
{
	slab_item_t *itr = slab->head;
	slab_item_t *prev = slab->head;
	
	
	while( itr != NULL ) {
		DEBUG(" itr->alloc = %x\n", itr->alloc);
		if( itr->alloc != slab->empty_vector ) {
			break;
		}
		prev = itr;
		itr = itr->next;
	}
	
	if( itr == NULL ) {
		//
		// The pool is exhausted, create a new one
		//
		DEBUG("pool exhausted\n");
		if( slab->flag & SLAB_LONGTERM ) {
			prev->next = malloc_longterm( sizeof( slab_item_t ) + slab->num_items_per_pool * slab->item_size, pid );
		} else {
			prev->next = ker_malloc( sizeof( slab_item_t ) + slab->num_items_per_pool * slab->item_size, pid );
		}
		if( prev->next == NULL ) {
			DEBUG("alloc NULL\n");
			return NULL;
		}
		itr = prev->next;
		itr->next = NULL;
		itr->alloc = 0x01;
		itr->gc_mark = 0;
		return itr->mem;
	} else {
		uint8_t i;
		uint8_t mask = 0x01;
		
		DEBUG("find free slot in pool\n");
		for( i = 0; i < slab->num_items_per_pool; i++, mask<<=1 ) {
			if( (itr->alloc & mask)  == 0 ) {
				itr->alloc |= mask;
				return itr->mem + (i * slab->item_size);
			}
		}
	}
	return NULL;
}
Exemplo n.º 4
0
Arquivo: sched.c Projeto: nesl/umpu
static int8_t do_register_module(mod_header_ptr h, sos_module_t *handle, 
																 void *init, uint8_t init_size, uint8_t flag)
{
  sos_pid_t pid;
  uint8_t st_size;
  int8_t ret;

  // Disallow usage of NULL_PID
  if (flag == SOS_CREATE_THREAD) {
	  pid = sched_get_pid_from_pool();
	  if (pid == NULL_PID) return -ENOMEM;
  } else {
	  pid = sos_read_header_byte(h, offsetof(mod_header_t, mod_id));
	  /*
	   * Disallow the usage of thread ID
	   */
	  if (pid > APP_MOD_MAX_PID) return -EINVAL;
  }


  // Read the state size and allocate a separate memory block for it
  st_size = sos_read_header_byte(h, offsetof(mod_header_t, state_size));
	//DEBUG("registering module pid %d with size %d\n", pid, st_size);
  if (st_size){
		//handle->handler_state = (uint8_t*)ker_malloc(st_size, pid);
		handle->handler_state = (uint8_t*)malloc_longterm(st_size, KER_SCHED_PID);
	// If there is no memory to store the state of the module
		if (handle->handler_state == NULL){
			return -ENOMEM;
		}
	} else {
		handle->handler_state = NULL;
	}

	// Initialize the data structure
	handle->header = h;
	handle->pid = pid;
  handle->flag = 0;
	handle->next = NULL;

  // add to the bin
  ret = sched_register_module(handle, h, init, init_size);
  if(ret != SOS_OK) {
	 ker_free(handle->handler_state); //! Free the memory block to hold module state
	return ret;
  }
  return SOS_OK;
}
Exemplo n.º 5
0
Arquivo: sched.c Projeto: nesl/umpu
/**
 * @brief register new module
 * NOTE: this function cannot be called in the interrupt handler
 * That is, the function is not thread safe
 * NOTE: h is stored in program memory, which can be different from RAM
 * special access function is needed.
 */
int8_t ker_register_module(mod_header_ptr h)
{
	sos_module_t *handle;
	int8_t ret;
	if(h == 0) return -EINVAL;
	handle = (sos_module_t*)malloc_longterm(sizeof(sos_module_t), KER_SCHED_PID);
	if (handle == NULL) {
		return -ENOMEM;
	}
	ret = do_register_module(h, handle, NULL, 0, 0);
	if(ret != SOS_OK) {
		ker_free(handle);
	}
	ker_change_own(handle->handler_state, handle->pid);
	return ret;
}
Exemplo n.º 6
0
Arquivo: sched.c Projeto: nesl/umpu
sos_pid_t ker_spawn_module(mod_header_ptr h, void *init, uint8_t init_size, uint8_t flag)
{
	sos_module_t *handle;
	if(h == 0) return NULL_PID;
	// Allocate a memory block to hold the module list entry
	//handle = (sos_module_t*)ker_malloc(sizeof(sos_module_t), KER_SCHED_PID);
	handle = (sos_module_t*)malloc_longterm(sizeof(sos_module_t), KER_SCHED_PID);
	if (handle == NULL) {
		return NULL_PID;
	}
	if( do_register_module(h, handle, init, init_size, flag) != SOS_OK) {
		ker_free(handle);
		return NULL_PID;	
	}
	return handle->pid;
}
Exemplo n.º 7
0
//! Assumption - This function is never called from an interrupt context
int8_t ker_timer_init(sos_pid_t pid, uint8_t tid, uint8_t type)
{
  sos_timer_t* tt;

  tt = find_timer_in_periodic_pool(pid, tid);
  if (tt != NULL) {
      tt->type = type;
	  list_insert_tail(&timer_pool, (list_link_t*)tt);
	  return SOS_OK;
  }
  //! re-initialize an existing timer by stoping it and updating the type
  tt = find_timer_block(pid, tid);
  if (tt != NULL){
      ker_timer_stop(pid,tid);
      tt->type = type;
      return SOS_OK;
  }
  
  //! Search if pre-initialized timer exists
  tt = alloc_from_timer_pool(pid, tid);
  
  //! Look for pre-allocated timers or try to get dynamic memory
  if (tt == NULL){
	tt = alloc_from_preallocated_timer_pool(pid);
	if (tt == NULL){
	  tt = (sos_timer_t*)malloc_longterm(sizeof(sos_timer_t), TIMER_PID);
	}
	//! Init will fail if the system does not have sufficient resources
	if (tt == NULL)
	  return -ENOMEM;
  }
  
  //! Fill up the data structure and insert into the timer pool
  tt->pid = pid;
  tt->tid = tid;
  tt->type = type;
  
  list_insert_tail(&timer_pool, (list_link_t*)tt);
  return SOS_OK;
}