static void inline add_to_buffer(void* stream, unsigned int length){ // This shouldn't lose any data and works for any size unsigned int stream_offset = 0; // Length calculations are in samples (stereo (short) sample pairs) unsigned int lengthi, rlengthi; unsigned int lengthLeft = length >> 2; unsigned int rlengthLeft = ceilf(lengthLeft / freq_ratio); while(1){ rlengthi = (buffer_offset + (rlengthLeft << 2) <= buffer_size) ? rlengthLeft : ((buffer_size - buffer_offset) >> 2); lengthi = rlengthi * freq_ratio; #ifdef THREADED_AUDIO // Wait for a buffer we can copy into LWP_SemWait(buffer_empty); #endif copy_to_buffer(buffer[which_buffer] + buffer_offset, stream + stream_offset, rlengthi); if(buffer_offset + (rlengthLeft << 2) < buffer_size){ buffer_offset += rlengthi << 2; #ifdef THREADED_AUDIO // This is a little weird, but we didn't fill this buffer. // So it is still considered 'empty', but since we 'decremented' // buffer_empty coming in here, we want to set it back how // it was, so we don't cause a deadlock LWP_SemPost(buffer_empty); #endif return; } lengthLeft -= lengthi; stream_offset += lengthi << 2; rlengthLeft -= rlengthi; #ifdef THREADED_AUDIO // Start the thread if this is the first sample if(!thread_running){ thread_running = 1; LWP_SemPost(first_audio); } // Let the audio thread know that we've filled a new buffer LWP_SemPost(buffer_full); #else play_buffer(); #endif #ifdef AIDUMP if(AIdump) fwrite(&buffer[which_buffer][0],1,buffer_size,AIdump); #endif NEXT(which_buffer); buffer_offset = 0; } }
void pauseAudio(void){ #ifdef THREADED_AUDIO // We just grab the audio_free 'lock' and don't let go // when we have this lock, audio_thread must be waiting if(audioEnabled){ LWP_SemWait(audio_free); audio_paused = 1; } #endif AUDIO_StopDMA(); }
void * mem_realloc(void *rmem, mem_size_t newsize) { mem_size_t size; mem_size_t ptr, ptr2; struct mem *mem, *mem2; /* Expand the size of the allocated memory region so that we can adjust for alignment. */ if ((newsize % MEM_ALIGNMENT) != 0) { newsize += MEM_ALIGNMENT - ((newsize + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); } if (newsize > MEM_SIZE) { return NULL; } LWP_SemWait(mem_sem); LWIP_ASSERT("mem_realloc: legal memory", (u8_t *)rmem >= (u8_t *)ram && (u8_t *)rmem < (u8_t *)ram_end); if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_realloc: illegal memory\n")); return rmem; } mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); ptr = (u8_t *)mem - ram; size = mem->next - ptr - SIZEOF_STRUCT_MEM; #if MEM_STATS lwip_stats.mem.used -= (size - newsize); #endif /* MEM_STATS */ if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE < size) { ptr2 = ptr + SIZEOF_STRUCT_MEM + newsize; mem2 = (struct mem *)&ram[ptr2]; mem2->used = 0; mem2->next = mem->next; mem2->prev = ptr; mem->next = ptr2; if (mem2->next != MEM_SIZE) { ((struct mem *)&ram[mem2->next])->prev = ptr2; } plug_holes(mem2); } LWP_SemPost(mem_sem); return rmem; }
static void inline play_buffer(void){ #ifndef THREADED_AUDIO // We should wait for the other buffer to finish its DMA transfer first while( AUDIO_GetDMABytesLeft() ); AUDIO_StopDMA(); #else // THREADED_AUDIO // Wait for a sample to actually be played to work around a deadlock LWP_SemWait(first_audio); // This thread will keep giving buffers to the audio as they come while(thread_running){ // Wait for a buffer to be processed LWP_SemWait(buffer_full); #endif // Make sure the buffer is in RAM, not the cache DCFlushRange(buffer[thread_buffer], buffer_size); // Actually send the buffer out to be played next AUDIO_InitDMA((unsigned int)&buffer[thread_buffer], buffer_size); #ifdef THREADED_AUDIO // Wait for the audio interface to be free before playing LWP_SemWait(audio_free); #endif // Start playing the buffer AUDIO_StartDMA(); #ifdef THREADED_AUDIO // Move the index to the next buffer NEXT(thread_buffer); } #endif }
void mem_free(void *rmem) { struct mem *mem; if (rmem == NULL) { LWIP_DEBUGF(MEM_DEBUG | DBG_TRACE | 2, ("mem_free(p == NULL) was called.\n")); return; } LWP_SemWait(mem_sem); LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && (u8_t *)rmem < (u8_t *)ram_end); if ((u8_t *)rmem < (u8_t *)ram || (u8_t *)rmem >= (u8_t *)ram_end) { LWIP_DEBUGF(MEM_DEBUG | 3, ("mem_free: illegal memory\n")); #if MEM_STATS ++lwip_stats.mem.err; #endif /* MEM_STATS */ LWP_SemPost(mem_sem); return; } mem = (struct mem *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); LWIP_ASSERT("mem_free: mem->used", mem->used); mem->used = 0; if (mem < lfree) { lfree = mem; } #if MEM_STATS lwip_stats.mem.used -= mem->next - ((u8_t *)mem - ram); #endif /* MEM_STATS */ plug_holes(mem); LWP_SemPost(mem_sem); }
static s32 DebugHelper_request( DebugHelper_t *helper, s32 code, s32 nargs, HelperParam_t *param ) { if ( code <= HELPER_CODE_NONE || code >= HELPER_CODE_END ) { return 0; } __db_req_count[ code ] ++; DEBUG_PRINT((NULL,0,"DebugHelper_request(%p), code=%d.\n", helper, code)); /* nargs is not used */ helper->param = param; //if ( nargs > 0 ) { // memcpy( helper->param, param, nargs * sizeof( HelperParam_t)); //} helper->code = code; /* notify the helper thread */ LWP_SemPost( helper->requestReadySema); /* wait be notified until the helper thread complete the request */ LWP_SemWait( helper->answerReadySema); return helper->retvalue; }
void * mem_malloc(mem_size_t size) { mem_size_t ptr, ptr2; struct mem *mem, *mem2; if (size == 0) { return NULL; } /* Expand the size of the allocated memory region so that we can adjust for alignment. */ if ((size % MEM_ALIGNMENT) != 0) { size += MEM_ALIGNMENT - ((size + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT); } if (size > MEM_SIZE) { return NULL; } LWP_SemWait(mem_sem); for (ptr = (u8_t *)lfree - ram; ptr < MEM_SIZE; ptr = ((struct mem *)&ram[ptr])->next) { mem = (struct mem *)&ram[ptr]; if (!mem->used && mem->next - (ptr + SIZEOF_STRUCT_MEM) >= size + SIZEOF_STRUCT_MEM) { ptr2 = ptr + SIZEOF_STRUCT_MEM + size; mem2 = (struct mem *)&ram[ptr2]; mem2->prev = ptr; mem2->next = mem->next; mem->next = ptr2; if (mem2->next != MEM_SIZE) { ((struct mem *)&ram[mem2->next])->prev = ptr2; } mem2->used = 0; mem->used = 1; #if MEM_STATS lwip_stats.mem.used += (size + SIZEOF_STRUCT_MEM); /* if (lwip_stats.mem.max < lwip_stats.mem.used) { lwip_stats.mem.max = lwip_stats.mem.used; } */ if (lwip_stats.mem.max < ptr2) { lwip_stats.mem.max = ptr2; } #endif /* MEM_STATS */ if (mem == lfree) { /* Find next free block after mem */ while (lfree->used && lfree != ram_end) { lfree = (struct mem *)&ram[lfree->next]; } LWIP_ASSERT("mem_malloc: !lfree->used", !lfree->used); } LWP_SemPost(mem_sem); LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", (unsigned long)((u8_t *)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); return (u8_t *)mem + SIZEOF_STRUCT_MEM; } } LWIP_DEBUGF(MEM_DEBUG | 2, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); #if MEM_STATS ++lwip_stats.mem.err; #endif /* MEM_STATS */ LWP_SemPost(mem_sem); return NULL; }
static void *DebugHelper_run( void *args) { DebugHelper_t *helper = (DebugHelper_t*) args; s32 code = HELPER_CODE_NONE; s32 ret; DEBUG_PRINT((NULL,0,"Helper(%p) thread up and running ...\n", helper)); while (1) { /* wait be notified by gdb-runtime-core */ LWP_SemWait( helper->requestReadySema); code=helper->code; DEBUG_PRINT((NULL,0,"Helper(%p) wakeup with code:%d\n", helper, helper->code)); if ( code<= HELPER_CODE_NONE || code>= HELPER_CODE_END ) { continue; } __db_ack_count[ code]++; DEBUG_PRINT((NULL,0,"Helper(%p) working on code:%d\n", helper, code)); switch( code) { case HELPER_CODE_OPEN: ret = helper_opentcpip( helper); break; case HELPER_CODE_CLOSE: ret = helper_closetcpip( helper); break; case HELPER_CODE_READ: ret = helper_readtcpip( helper); break; case HELPER_CODE_WRITE: ret = helper_writetcpip( helper); break; case HELPER_CODE_WAIT: ret = helper_waittcpip( helper); break; case HELPER_CODE_STOP: ret = 0; break; default: ret = 0; break; } helper->retvalue = ret; DEBUG_PRINT((NULL,0,"Helper(%p) completed with ret-code:%d\n", helper, ret)); /* just be safe */ helper->code = HELPER_CODE_NONE; /* notify the gdb-runtime-core */ LWP_SemPost( helper->answerReadySema); if ( code==HELPER_CODE_STOP) { break ; } } return NULL; }