Esempio n. 1
0
/**
** malloc()  allocates  size bytes and returns a pointer to the allocated memory.  The memory is not cleared.  If size is 0, then
** malloc() returns either NULL, or a unique pointer value that can later be successfully passed to free().
*/
extern void* bitmap_heap_malloc(size_t size)
{
	void* pointer = NULL;
	if ( size > 0 )
	{
		int32_t blocks = to_blocks(size);
		int32_t block;
		/** Search each heap... */
		int lvl = caribou_lib_lock();
		for(heap_num=0; heap_num < heap_count; heap_num++)
		{
			#if defined(CARIBOU_MPU_ENABLED)
				heap_state->heap_current_thread = caribou_thread_current();
			#endif
			block = locate_free(HEAP_STATE(heap_num),blocks);
			if ( block >= 0 )
			{
				pointer = allocate(HEAP_STATE(heap_num),block,blocks);
				break;
			}
		}
		if ( pointer == NULL )
		{
			notify_heap_alloc_failed(size);
		}
		caribou_lib_lock_restore(lvl);
	}
	#if defined(CARIBOU_CLEAR_HEAP_MALLOC)
		if ( pointer )
			memset(pointer,0,size);
	#endif
	return pointer;
}
Esempio n. 2
0
struct sys_timeouts *sys_arch_timeouts(void)
{
	sys_thread_t thread = lwip_system_threads;
	caribou_thread_t *self = caribou_thread_current();
	// Search the threads list for the thread that is currently running
	for ( ; thread!=NULL; thread=thread->next)
	{
		if (thread->thread == self)
			return thread->timeouts;
	}
	// No match, so just return the system-wide default version
	return &lwip_system_timeouts;
}
Esempio n. 3
0
/**
 * @brief 
 * @param tmer A pointer to the timer
 * @patam timerfn The timer callback function
 * @param arg Arguments to pass to the callback function
 * @param flags Timer flags
 * @return A pointer to the timer or NULL if a problem was encountered.
 */
caribou_timer_t* caribou_timer_init( caribou_timer_t* timer, caribou_timer_callback_fn* timerfn, void* arg, uint8_t flags )
{
	caribou_thread_t* thread = caribou_thread_current();
	if ( timer )
	{
        memset(timer,0,sizeof(caribou_timer_t));
		timer->flags = flags & ~CARIBOU_TIMER_F_DYNAMIC;
        timer->timerfn = timerfn;
        timer->fnarg = arg;
		append_timer_node(thread,timer);
	}
	return timer;
}
Esempio n. 4
0
/**
 * @brief Instantiate a new timer on the heap memory, and associate it with the current thread. 
 * @patam timerfn The timer callback function
 * @param arg Arguments to pass to the callback function
 * @param flags Timer flags
 * @return A pointer to the newly allocated caribou_timer_t* structure instance,
 * or NULL if a problem was encountered.
 */
caribou_timer_t* caribou_timer_create( caribou_timer_callback_fn* timerfn, void* arg, uint8_t flags )
{
	caribou_thread_t* thread = caribou_thread_current();
	caribou_timer_t* timer = new_timer_node(timerfn,arg);
	if ( timer )
	{
		timer->flags = flags | CARIBOU_TIMER_F_DYNAMIC;
        timer->timerfn = timerfn;
        timer->fnarg = arg;
		append_timer_node(thread,timer);
	}
	return timer;
}
Esempio n. 5
0
/**
 * @brief Find the starting block for the heap. Taking into account memory which has been
 * claimed by MPU protected threads.
 * @param blocks Return the number of blocks.
 * @return Starting block number.
 */
static int32_t block_range(heap_state_t* heap_state, int32_t* blocks)
{
	int32_t rc = 0;
	*blocks = heap_state->heap_blocks;
	#if defined(CARIBOU_MPU_ENABLED)
		if ( heap_state->heap_current_thread->mpu_subregion_cnt )
		{
			caribou_thread_t* thread = caribou_thread_current();
			if ( thread )
			{
				if ( thread == HEAP_STATE(heap_num)->heap_thread[ thread->mpu_subregion ] )
				{
					uint32_t subregion_size = HEAP_STATE(heap_num)->heap_subregion_size;
					rc = subregion_size * thread->mpu_subregion;
					*blocks = subregion_size / HEAP_BLOCK_SIZE;
				}
			}
		}
	#endif
	return rc;
}
Esempio n. 6
0
/**
** realloc() changes the size of the memory block pointed to by ptr to size bytes.  The contents will be unchanged to the minimum
** of  the  old and new sizes; newly allocated memory will be uninitialized.  If ptr is NULL, then the call is equivalent to mal‐
** loc(size), for all values of size; if size is equal to zero, and ptr is not NULL, then the call is  equivalent  to  free(ptr).
** Unless  ptr is NULL, it must have been returned by an earlier call to malloc() or realloc().  If the area pointed to
** was moved, a free(ptr) is done.
*/
extern void* bitmap_heap_realloc(void* pointer, size_t size)
{
	if (pointer != NULL && size > 0 )
	{
		int32_t blocks = to_blocks(size);
		int32_t block=(-1);
		int32_t used;
		int lvl = caribou_lib_lock();
		/** Search each heap... */
		for(heap_num=0; heap_num < heap_count; heap_num++)
		{
			block = from_pointer(HEAP_STATE(heap_num),pointer);
			if ( block >= 0 )
				break;
		}
		if ( block >= 0 )
		{
			used = blocks_used(HEAP_STATE(heap_num),block);
			if (blocks > used)
			{
				if (!extend(HEAP_STATE(heap_num),block,used,blocks-used))         /* attempt to extend existing block */
				{
					int32_t target;
					deallocate(HEAP_STATE(heap_num),block,used);                  /* make currently allocated blocks available to be re-allocated.. */
					#if defined(CARIBOU_MPU_ENABLED)
						heap_state->heap_current_thread = caribou_thread_current();
					#endif
					target = locate_free(HEAP_STATE(heap_num),blocks);            /* ...then attempts to locate a sequence of free blocks... */
					if (target >= 0 )
					{
						void* pTarget = allocate(HEAP_STATE(heap_num),target,blocks);	/* allocate the new blocks... */
						memmove(pTarget,pointer,used*HEAP_BLOCK_SIZE);			/* ...and move the data to the new area. */
						pointer = pTarget;
					}
					else
					{
						/* 
						 * The re-allocation failed in the current heap pool. 
						 * It may be possible to get a fit in another pool. 
						 */
						void* pTarget;
						if ( (pTarget = bitmap_heap_malloc(size)) != NULL )
						{
							memmove(pTarget,pointer,used*HEAP_BLOCK_SIZE);
							pointer = pTarget;
						}
						else
						{
							notify_heap_invalid_realloc(pointer,size);
							pointer = NULL;
						}
					}
				}
			}
			else if (blocks < used)
			{
				/* shrink the allocation */
				deallocate(HEAP_STATE(heap_num),block,used);
				allocate(HEAP_STATE(heap_num),block,blocks);
			}
		}
		else
		{
			notify_heap_invalid_realloc(pointer,size);
			pointer = NULL;
		}
		caribou_lib_lock_restore(lvl);
	}
	else if (pointer != NULL && size == 0)
	{
		bitmap_heap_free(pointer);
		pointer=NULL;
	}
	else if (pointer == NULL )
	{
		pointer = bitmap_heap_malloc(size);
	}
	return pointer;
}