Exemplo n.º 1
0
/**
 * Creates a semaphore
 *
 * @param semaphore         : pointer to variable which will receive handle of created semaphore
 *
 * @returns WWD_SUCCESS on success, WICED_ERROR otherwise
 */
wwd_result_t host_rtos_init_semaphore( /*@out@*/ host_semaphore_type_t* semaphore ) /*@modifies *semaphore@*/
{
    return ( tx_semaphore_create( semaphore, (char*) "", 0 ) == TX_SUCCESS ) ? WWD_SUCCESS : WWD_SEMAPHORE_ERROR;
}
Exemplo n.º 2
0
Arquivo: demo.c Projeto: igou/tx
void    tx_application_define(void *first_unused_memory)
{

CHAR    *pointer;


    /* Create a byte memory pool from which to allocate the thread stacks.  */
    tx_byte_pool_create(&byte_pool_0, "byte pool 0", first_unused_memory, DEMO_BYTE_POOL_SIZE);

    /* Put system definition stuff in here, e.g. thread creates and other assorted
       create information.  */

    /* Allocate the stack for thread 0.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create the main thread.  */
    tx_thread_create(&thread_0, "thread 0", thread_0_entry, 0,  
            pointer, DEMO_STACK_SIZE, 
            1, 1, TX_NO_TIME_SLICE, TX_AUTO_START);


    /* Allocate the stack for thread 1.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 1 and 2. These threads pass information through a ThreadX 
       message queue.  It is also interesting to note that these threads have a time
       slice.  */
    tx_thread_create(&thread_1, "thread 1", thread_1_entry, 1,  
            pointer, DEMO_STACK_SIZE, 
            16, 16, 4, TX_AUTO_START);

    /* Allocate the stack for thread 2.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    tx_thread_create(&thread_2, "thread 2", thread_2_entry, 2,  
            pointer, DEMO_STACK_SIZE, 
            16, 16, 4, TX_AUTO_START);

    /* Allocate the stack for thread 3.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 3 and 4.  These threads compete for a ThreadX counting semaphore.  
       An interesting thing here is that both threads share the same instruction area.  */
    tx_thread_create(&thread_3, "thread 3", thread_3_and_4_entry, 3,  
            pointer, DEMO_STACK_SIZE, 
            8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 4.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    tx_thread_create(&thread_4, "thread 4", thread_3_and_4_entry, 4,  
            pointer, DEMO_STACK_SIZE, 
            8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 5.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create thread 5.  This thread simply pends on an event flag which will be set
       by thread_0.  */
    tx_thread_create(&thread_5, "thread 5", thread_5_entry, 5,  
            pointer, DEMO_STACK_SIZE, 
            4, 4, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 6.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    /* Create threads 6 and 7.  These threads compete for a ThreadX mutex.  */
    tx_thread_create(&thread_6, "thread 6", thread_6_and_7_entry, 6,  
            pointer, DEMO_STACK_SIZE, 
            8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the stack for thread 7.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_STACK_SIZE, TX_NO_WAIT);

    tx_thread_create(&thread_7, "thread 7", thread_6_and_7_entry, 7,  
            pointer, DEMO_STACK_SIZE, 
            8, 8, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Allocate the message queue.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_QUEUE_SIZE*sizeof(ULONG), TX_NO_WAIT);

    /* Create the message queue shared by threads 1 and 2.  */
    tx_queue_create(&queue_0, "queue 0", TX_1_ULONG, pointer, DEMO_QUEUE_SIZE*sizeof(ULONG));

    /* Create the semaphore used by threads 3 and 4.  */
    tx_semaphore_create(&semaphore_0, "semaphore 0", 1);

    /* Create the event flags group used by threads 1 and 5.  */
    tx_event_flags_create(&event_flags_0, "event flags 0");

    /* Create the mutex used by thread 6 and 7 without priority inheritance.  */
    tx_mutex_create(&mutex_0, "mutex 0", TX_NO_INHERIT);

    /* Allocate the memory for a small block pool.  */
    tx_byte_allocate(&byte_pool_0, (VOID **) &pointer, DEMO_BLOCK_POOL_SIZE, TX_NO_WAIT);

    /* Create a block memory pool to allocate a message buffer from.  */
    tx_block_pool_create(&block_pool_0, "block pool 0", sizeof(ULONG), pointer, DEMO_BLOCK_POOL_SIZE);

    /* Allocate a block and release the block memory.  */
    tx_block_allocate(&block_pool_0, (VOID **) &pointer, TX_NO_WAIT);

    /* Release the block back to the pool.  */
    tx_block_release(pointer);
}
Exemplo n.º 3
0
CM_Frame_Table * CM_Frame_Table::Allocate(
		CM_Mem					*p_mem, 
		CM_CONFIG				*p_config, 
		CM_PREFETCH_CALLBACK	*p_prefetch_callback,
		CM_WRITE_CALLBACK		*p_write_callback,
		CM_Stats				*p_stats,
		void					*p_callback_context,
		U32						 num_page_frames,
		void					*p_page_memory)
{
	// Allocate CM_Frame_Table object
	CM_Frame_Table *p_frame_table = 
		(CM_Frame_Table *)p_mem->Allocate(sizeof(CM_Frame_Table));

	if (p_frame_table == 0)
		return 0;
	
	// Initialize table lists.
	LIST_INITIALIZE(&p_frame_table->m_list_waiting_to_flush);
	LIST_INITIALIZE(&p_frame_table->m_list_wait_frame);

	// Initialize each of our dummy frames.  Each of our frame lists
	// is a dummy frame so that, when the last frame in the list points
	// to the head of the list, we can treat it as a frame without
	// having to check to see if we are pointing to the head of the list.
	p_frame_table->m_clock_list.Initialize(0, CM_PAGE_STATE_CLEAN);
	p_frame_table->m_dirty_clock_list.Initialize(0, CM_PAGE_STATE_DIRTY);

	// Save callbacks.
	p_frame_table->m_p_prefetch_callback = p_prefetch_callback;
	p_frame_table->m_p_write_callback = p_write_callback;
	p_frame_table->m_p_callback_context = p_callback_context;

	// Make sure the page size is a multiple of 8 for alignment.
	p_frame_table->m_page_size = ((p_config->page_size + 7) / 8) * 8;

	p_frame_table->m_num_pages_replaceable = 0;
	p_frame_table->m_num_pages_clock = 0;
	p_frame_table->m_num_pages_dirty_clock = 0;
	p_frame_table->m_num_pages_being_written = 0;
	p_frame_table->m_num_pages_working_set = 0;
	p_frame_table->m_p_clock_frame = 0;
	p_frame_table->m_p_dirty_clock_frame = 0;

	// Find out how much memory is available.
	// Leave this for debugging.  Should be close to zero.
	U32 memory_available = p_mem->Memory_Available();

	// Save number of page frames.
	p_frame_table->m_num_page_frames = num_page_frames;

    if (p_config->page_table_size)
	{
		// Linear mapping
		// Don't allocate more pages than specified in the config.
		if (p_frame_table->m_num_page_frames > p_config->page_table_size)
			p_frame_table->m_num_page_frames = p_config->page_table_size;
	}

	// Allocate array of page frames
	p_frame_table->m_p_page_frame_array = (char *)p_page_memory;

	// Allocate array of frames
	p_frame_table->m_p_frame_array = 
		(CM_Frame *)p_mem->Allocate(sizeof(CM_Frame) * p_frame_table->m_num_page_frames);
	if (p_frame_table->m_p_frame_array == 0)
		return 0;

	// When m_p_clock_frame is zero, we know that the frame table is not yet initialized.
	p_frame_table->m_p_clock_frame = 0;

	// Initialize each frame
    CM_Frame *p_frame;
	for (U32 index = 0; index < p_frame_table->m_num_page_frames; index++)
	{
		// Point to the next frame.
		p_frame = p_frame_table->Get_Frame(index + 1);

		// Have the frame initialize itself.
		p_frame->Initialize(index + 1, CM_PAGE_STATE_CLEAN);
		CT_ASSERT((p_frame_table->Get_Frame(index + 1) == p_frame), CM_Frame_Table::Allocate);
		CT_ASSERT((p_frame->Get_Frame_Index() == (index + 1)), CM_Frame_Table::Allocate);

		// Make sure the list object is first in the frame.
		CT_ASSERT(((CM_Frame *)&p_frame->m_list == p_frame), CM_Frame_Table::Allocate);
		CT_ASSERT((p_frame->Is_Replaceable()), CM_Frame_Table::Allocate);

		// Initially, each frame is on the clock list
		LIST_INSERT_TAIL(&p_frame_table->m_clock_list.m_list, &p_frame->m_list);
		p_frame_table->m_num_pages_clock++;
		p_frame_table->m_num_pages_replaceable++;
	}

	// Initialize the clocks
	p_frame_table->m_p_clock_frame = p_frame;
	p_frame_table->m_p_dirty_clock_frame = &p_frame_table->m_dirty_clock_list;

	// Calculate dirty page writeback threshold from the percentage in the config file.
	p_frame_table->m_dirty_page_writeback_threshold = 
		(p_frame_table->m_num_page_frames * p_config->dirty_page_writeback_threshold)
		/ 100;

	// Calculate dirty page error threshold from the percentage in the config file.
	p_frame_table->m_dirty_page_error_threshold = (p_frame_table->m_num_page_frames 
		* p_config->dirty_page_error_threshold)
		/ 100;

	// Make sure the number of reserve pages is less than the number of pages in the cache.
	// This would only happen in a test environment where the cache size is small.
	p_frame_table->m_num_reserve_pages = p_config->num_reserve_pages;
	if (p_frame_table->m_num_reserve_pages > p_frame_table->m_num_pages_replaceable)

		// Make number of reserve pages less than number of pages in the cache.
		p_frame_table->m_num_reserve_pages = 
			p_frame_table->m_num_pages_replaceable - (p_frame_table->m_num_pages_replaceable / 2);

	// Calculate the maximum number of dirty pages.
	U32 max_number_dirty_pages = p_frame_table->m_num_pages_replaceable
		- p_frame_table->m_num_reserve_pages;

	// Make sure the dirty page error threshold is less than the maximum number of dirty pages;
	// otherwise we will have a context waiting for a page to be cleaned, and it will 
	// never happen.  This would only occur in a test situation, where cache size is small.
	if (p_frame_table->m_dirty_page_error_threshold > max_number_dirty_pages)

		// Make dirty page error threshold less than max_number_dirty_pages.
		p_frame_table->m_dirty_page_error_threshold = 
			max_number_dirty_pages - (max_number_dirty_pages / 2);

	// Make sure the writeback threshold is less than the dirty page error threshold.
	if (p_frame_table->m_dirty_page_writeback_threshold > p_frame_table->m_dirty_page_error_threshold)

		// Make dirty page writeback threshold less than dirty page error threshold.
		p_frame_table->m_dirty_page_writeback_threshold = 
			p_frame_table->m_dirty_page_error_threshold 
				- (p_frame_table->m_dirty_page_error_threshold / 2);

	// Initialize pointer to statistics object
	p_frame_table->m_p_stats = p_stats;

#ifdef _WINDOWS

	// Initialize Windows mutex
	p_frame_table->m_mutex = CreateMutex(
		NULL, // LPSECURITY_ATTRIBUTES lpEventAttributes,	// pointer to security attributes
		
		// If TRUE, the calling thread requests immediate ownership of the mutex object. 
		// Otherwise, the mutex is not owned. 
		0, // flag for initial ownership 
		// If lpName is NULL, the event object is created without a name. 
		NULL // LPCTSTR lpName 	// pointer to semaphore-object name  
	   );

	if (p_frame_table->m_mutex == 0)
	{
		DWORD erc = GetLastError();
		CT_Log_Error(CT_ERROR_TYPE_FATAL,
			"CM_Frame_Table::Allocate", 
			"CreateMutex failed",
			erc,
			0);
		return p_frame_table;
	}
#else
#ifdef THREADX
	// Initialize Threadx semaphore
	Status	status = tx_semaphore_create(&p_frame_table->m_mutex, "CmMutex",
		1); // initial count
#else
	// Initialize Nucleus semaphore
	Status	status = NU_Create_Semaphore(&p_frame_table->m_mutex, "CmMutex",
		1, // initial count
		NU_FIFO);
#endif

	if (status != OK)
	{
		CT_Log_Error(CT_ERROR_TYPE_FATAL,
			"CM_Frame_Table::Allocate", 
			"NU_Create_Semaphore failed",
			status,
			0);
		return p_frame_table;
	}
#endif

#ifdef _DEBUG
	Got_Mutex = 0;
#endif

	// Return pointer to table object
	return p_frame_table;

} // CM_Frame_Table::Allocate