コード例 #1
0
ファイル: fifo.cpp プロジェクト: JammyWei/ver30
/***************************************************************************************
	function:	int read_one_packet(u_int8_t **packet_addr, u_int32_t *packet_size)
	input:	packet_addr: pointer to the address of the packet for read
			packet_size: pointer to the size of the packet for read
	return value:	0: successful, -1: failed
	remarks:	value-result arguments are used
***************************************************************************************/
int read_one_packet(u_int8_t **packet_addr, u_int32_t *packet_size)
{
#if defined( __linux__ )
    	u_int32_t entry_index_for_this_read;

	free_last_read_packet();

	pthread_mutex_lock(&fifo_core.mutex);

	// wait on the condition variable if fifo is empty
	while (fifo_core.used_entry_num == 0) {
//		printf("fifo empty, waiting...\n");	//jay
		pthread_cond_wait(&fifo_core.cond, &fifo_core.mutex);
	}

    	entry_index_for_this_read = fifo_core.entry_index_for_next_read;
	
	// advertise the packet
	*packet_addr = myFIFO.packet_info_entries[entry_index_for_this_read].packet_addr;
	*packet_size = myFIFO.packet_info_entries[entry_index_for_this_read].packet_size;

	// update entry index for next read
	fifo_core.entry_index_for_next_read++;
	wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read);

	// update related info
	fifo_core.entry_index_being_used = entry_index_for_this_read;
	
	pthread_mutex_unlock(&fifo_core.mutex);
#elif defined( _WIN32 )
	u_int32_t entry_index_for_this_read;

	free_last_read_packet();

	DWORD Error = ::WaitForSingleObject( fifo_core.mutex, INFINITE );

	// wait on the condition variable if fifo is empty
	while (fifo_core.used_entry_num == 0) {
//		printf("fifo empty, waiting...\n");	//jay
		WaitForSingleObject( fifo_core.cond, INFINITE );
	}

    entry_index_for_this_read = fifo_core.entry_index_for_next_read;
	
	// advertise the packet
	*packet_addr = myFIFO.packet_info_entries[entry_index_for_this_read].packet_addr;
	*packet_size = myFIFO.packet_info_entries[entry_index_for_this_read].packet_size;

	// update entry index for next read
	fifo_core.entry_index_for_next_read++;
	wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read);

	// update related info
	fifo_core.entry_index_being_used = entry_index_for_this_read;
	
	::ReleaseMutex( fifo_core.mutex );
#endif

	return 0;
}
コード例 #2
0
ファイル: fifo.c プロジェクト: WayWingsDev/live555
/* ***************************************************************************/
int fifo_read_one_packet(fifo_t *fifo, u8 *header, u8 **packet_addr, u32 *packet_size)
{
    int entry_index_for_this_read;

//	printf("lock, read\n");
    pthread_mutex_lock(&fifo->mutex);
//	printf("locked, read\n");

    free_last_read_packet(fifo);

    // wait on the condition variable if fifo is empty
    while (fifo->used_entry_num == 0) {
//		printf("unlock, waiting...\n");	//jay
        pthread_cleanup_push(cancel_read_wait, (void *) &fifo->mutex);
        pthread_cond_wait(&fifo->cond, &fifo->mutex);
//		printf("lock, awake\n");
        pthread_cleanup_pop(0);
    }

    entry_index_for_this_read = fifo->entry_index_for_next_read;

    while (fifo->packet_info_entries[entry_index_for_this_read].entry_state == ENTRY_INVALID) {
        fifo_printf("\t\t\t\tskip entry %d\n", entry_index_for_this_read);
        entry_index_for_this_read++;
        wraparound_entry_index_if_necessary(fifo, &entry_index_for_this_read);
    }

    fifo_printf("\t\t\t\t\t[%x]read %d, entry %d\n", (u32)fifo&0xf, entry_index_for_this_read, fifo->used_entry_num);

    // advertise the packet
    *packet_addr = fifo->packet_info_entries[entry_index_for_this_read].packet_addr;
    *packet_size = fifo->packet_info_entries[entry_index_for_this_read].packet_size;
    memcpy(header, &fifo->header_entries[entry_index_for_this_read*(fifo->header_size)],
           fifo->header_size);

    // update entry index for next read
    fifo->entry_index_for_next_read = entry_index_for_this_read + 1;
    wraparound_entry_index_if_necessary(fifo, &fifo->entry_index_for_next_read);

    // update related info
    fifo->entry_index_being_used = entry_index_for_this_read;

//	printf("unlock, read\n");
    pthread_mutex_unlock(&fifo->mutex);

    return 0;
}
コード例 #3
0
ファイル: fifo.c プロジェクト: WayWingsDev/live555
/***************************************************************************************
	function:	int fifo_write_one_packet(u8 *packet_addr, u32 packet_size)
	input:	packet_addr: address of the packet to be stored into the fifo
			packet_size: size of packet to be stored into the fifo
	return value:	0: successful, -1: failed
	remarks:	the algorithm gives priority to writers for sharing the free entries
***************************************************************************************/
int fifo_write_one_packet(fifo_t *fifo, u8 *header, u8 *packet_addr, u32 packet_size)
{
    u8 *addr_for_this_write;
    int entry_index_for_this_write;

//	printf("lock, write\n");
    pthread_mutex_lock(&fifo->mutex);
//	printf("locked, write\n");

    addr_for_this_write = fifo->addr_for_next_write;
    entry_index_for_this_write = fifo->entry_index_for_next_write;

    // skip the entry being used for this write
    if (entry_index_for_this_write == fifo->entry_index_being_used) {
        entry_index_for_this_write++;
        wraparound_entry_index_if_necessary(fifo, &entry_index_for_this_write);
    }
    fifo_printf("[%x]write %d, using %d, next read %d, entry %d\n", (u32)fifo&0xf, entry_index_for_this_write, fifo->entry_index_being_used,
                fifo->entry_index_for_next_read, fifo->used_entry_num);

    // if necessary, adjust write address to avoid wrapping around data
    if ((addr_for_this_write + packet_size) > (fifo->buffer_end_addr + 1))
        addr_for_this_write = fifo->buffer_start_addr;

    // save the packet
    memcpy(addr_for_this_write, packet_addr, packet_size);

    // save the header
    memcpy(&fifo->header_entries[entry_index_for_this_write*(fifo->header_size)],
           header, fifo->header_size);

    // update related info
    if (fifo->packet_info_entries[entry_index_for_this_write].entry_state == ENTRY_INVALID)
        fifo->used_entry_num++;

    // fill the entry
    fifo->packet_info_entries[entry_index_for_this_write].packet_addr = addr_for_this_write;
    fifo->packet_info_entries[entry_index_for_this_write].packet_size = packet_size;
    fifo->packet_info_entries[entry_index_for_this_write].entry_state = ENTRY_VALID;

    // advance the entry for next read, if it is overwirtten by this write, when fifo is full
    if (entry_index_for_this_write == fifo->entry_index_for_next_read &&
            fifo->used_entry_num > 2) {	 // being used entry is still ocupying one entry
        // if fifo is nearly full
        fifo->entry_index_for_next_read++;
        wraparound_entry_index_if_necessary(fifo, &fifo->entry_index_for_next_read);
        if (fifo->entry_index_for_next_read == fifo->entry_index_being_used) {
            fifo->entry_index_for_next_read++;	// skip the entry being used for next read
            wraparound_entry_index_if_necessary(fifo, &fifo->entry_index_for_next_read);
        }
        fifo_printf("fifo full, advance read entry to %d >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n", fifo->entry_index_for_next_read);
    }

    // update entry index for next write
    fifo->entry_index_for_next_write = entry_index_for_this_write + 1;
    wraparound_entry_index_if_necessary(fifo, &fifo->entry_index_for_next_write);

    // update address for next write
    fifo->addr_for_next_write = addr_for_this_write + packet_size;
    if (fifo->addr_for_next_write > fifo->buffer_end_addr)
        fifo->addr_for_next_write -= fifo->buffer_total_size;

    // signal the condition variable if necessary
    if (fifo->used_entry_num <= 1)
        pthread_cond_signal(&fifo->cond);

//	fifo->buffer_used_size += packet_size;

//	printf("unlock, write\n");
    pthread_mutex_unlock(&fifo->mutex);

#if 0
    printf("fifo_write_one_packet\n");
    for (i = 0; i < 4; i++) {
        printf("%p\t", fifo->packet_info_entries[i].packet_addr);
    }
    printf("\nnow %d entry used\n", fifo->used_entry_num);
#endif
    return 0;
}
コード例 #4
0
ファイル: fifo.cpp プロジェクト: JammyWei/ver30
/***************************************************************************************
	function:	int write_one_packet(u_int8_t *packet_addr, u_int32_t packet_size)
	input:	packet_addr: address of the packet to be stored into the fifo
			packet_size: size of packet to be stored into the fifo
	return value:	0: successful, -1: failed
	remarks:	the algorithm gives priority to writers for sharing the free entries
***************************************************************************************/
int write_one_packet(u_int8_t *packet_addr, u_int32_t packet_size)
{
#if defined( __linux__ )
	u_int8_t *addr_for_this_write;
	int entry_index_for_this_write = 0;

	pthread_mutex_lock(&fifo_core.mutex);
	addr_for_this_write = fifo_core.addr_for_next_write;
	entry_index_for_this_write = fifo_core.entry_index_for_next_write;


	// skip the entry being used for this write
	if (entry_index_for_this_write == fifo_core.entry_index_being_used) {
		entry_index_for_this_write++;
		wraparound_entry_index_if_necessary(&entry_index_for_this_write);
	}

	// if necessary, adjust write address to avoid wrapping around data
	if ((addr_for_this_write + packet_size) > (myFIFO.buffer_end_addr + 1))
		addr_for_this_write = myFIFO.buffer_start_addr;

	// save the packet
	memcpy(addr_for_this_write, packet_addr, packet_size);

	// fill the entry
	myFIFO.packet_info_entries[entry_index_for_this_write].packet_addr = addr_for_this_write;
	myFIFO.packet_info_entries[entry_index_for_this_write].packet_size = packet_size;

	// advance the entry for next read, if it is overwirtten by this write, when fifo is full
	if (entry_index_for_this_write == fifo_core.entry_index_for_next_read &&
		fifo_core.used_entry_num == myFIFO.max_entry_num) {	// if fifo is full
		fifo_core.entry_index_for_next_read++;
		wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read);
		printf("fifo full, dropping frame...\n");
	}

	// update entry index for next write
	fifo_core.entry_index_for_next_write++;
	wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_write);

	if (fifo_core.entry_index_for_next_write == fifo_core.entry_index_being_used) {
		fifo_core.entry_index_for_next_write++;	// skip entry being used by last read
		wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_write);
	} 
	
	// update address for next write
	fifo_core.addr_for_next_write = addr_for_this_write + packet_size;
	if (fifo_core.addr_for_next_write > myFIFO.buffer_end_addr)
		fifo_core.addr_for_next_write -= myFIFO.buffer_total_size;

	// signal the condition variable
	if (fifo_core.used_entry_num == 0)
		pthread_cond_signal(&fifo_core.cond);

	// update related info
	fifo_core.used_entry_num++;
	fifo_core.buffer_used_size += packet_size;
	
	pthread_mutex_unlock(&fifo_core.mutex);
#elif defined( _WIN32 )
	u_int8_t *addr_for_this_write;
	int entry_index_for_this_write = 0;

	DWORD Error = WaitForSingleObject( fifo_core.mutex, INFINITE );
	addr_for_this_write = fifo_core.addr_for_next_write;
	entry_index_for_this_write = fifo_core.entry_index_for_next_write;

	// skip the entry being used for this write
	if (entry_index_for_this_write == fifo_core.entry_index_being_used) {
		entry_index_for_this_write++;
		wraparound_entry_index_if_necessary(&entry_index_for_this_write);
	}

	// if necessary, adjust write address to avoid wrapping around data
	if ((addr_for_this_write + packet_size) > (myFIFO.buffer_end_addr + 1))
		addr_for_this_write = myFIFO.buffer_start_addr;

	// save the packet
	memcpy(addr_for_this_write, packet_addr, packet_size);

	// fill the entry
	myFIFO.packet_info_entries[entry_index_for_this_write].packet_addr = addr_for_this_write;
	myFIFO.packet_info_entries[entry_index_for_this_write].packet_size = packet_size;

	// advance the entry for next read, if it is overwirtten by this write, when fifo is full
	if (entry_index_for_this_write == fifo_core.entry_index_for_next_read &&
		fifo_core.used_entry_num == myFIFO.max_entry_num) {	// if fifo is full
		fifo_core.entry_index_for_next_read++;
		wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_read);
		printf("fifo full, dropping frame...\n");
	}

	// update entry index for next write
	fifo_core.entry_index_for_next_write++;
	wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_write);

	if (fifo_core.entry_index_for_next_write == fifo_core.entry_index_being_used) {
		fifo_core.entry_index_for_next_write++;	// skip entry being used by last read
		wraparound_entry_index_if_necessary(&fifo_core.entry_index_for_next_write);
	} 
	
	// update address for next write
	fifo_core.addr_for_next_write = addr_for_this_write + packet_size;
	if (fifo_core.addr_for_next_write > myFIFO.buffer_end_addr)
		fifo_core.addr_for_next_write -= myFIFO.buffer_total_size;

	// signal the condition variable
	if (fifo_core.used_entry_num == 0)
	{
		::SetEvent( fifo_core.cond );
	}

	// update related info
	fifo_core.used_entry_num++;
	fifo_core.buffer_used_size += packet_size;
	
	::ReleaseMutex( fifo_core.mutex );
#endif

#if 0
	int i;
	printf("write_one_packet\n");
	for (i = 0; i < 4; i++) {
		printf("%p\t", myFIFO.packet_info_entries[i].packet_addr);
	}
	printf("\nnow %d entry used\n", fifo_core.used_entry_num);
#endif
	return 0;
}