/*********************************************************** * Name: os_cond_signal * * Arguments: OS_COND_T *cond * * Description: Routine to signal at least one thread * waiting on a condition variable. The * caller must say whether they have obtained * the semaphore. * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_cond_signal( OS_COND_T *cond, bool_t sem_claimed ) { int32_t success = -1; if (cond) { COND_WAITER_T *w; // Ensure the condvar's semaphore is claimed for thread-safe access if (!sem_claimed) { success = os_semaphore_obtain((*cond)->semaphore); os_assert(success == 0); } w = (*cond)->waiters; if (w) { // Wake the first person waiting vcos_event_signal(&w->latch); (*cond)->waiters = w->next; } success = 0; if (!sem_claimed) { success = os_semaphore_release((*cond)->semaphore); } os_assert(success == 0); } return success; }
int32_t ipc_vchi_msg_dequeue( /*VCHI_SERVICE_HANDLE_T*/int32_t handle, void *data, uint32_t max_data_size_to_read, uint32_t *actual_msg_size, VCHI_FLAGS_T flags ) { // vchi_msg_dequeue(handle,data,max_data_size_to_read,actual_msg_size,flags); uint32_t events; uint32_t read_size; int32_t success=0; os_assert(max_data_size_to_read<IPC_SHARED_MEM_SIZE); ipc_aquire(IPC_SEM_ACCESS); ipc->buffer[0] = set_vchi_handle(handle); ipc->buffer[1] = max_data_size_to_read; ipc->buffer[2] = flags; ipc->buffer[3] = 0xbabeface; ipc_signal(IPC_VCHI_MSG_DEQUEUE_EVENT); ipc_wait(&events); os_assert(events == (1<<IPC_VCHI_MSG_DEQUEUE_EVENT)); read_size = ipc->buffer[1]; os_assert(read_size <= max_data_size_to_read); memcpy(data,&ipc->buffer[4],read_size); *actual_msg_size = read_size; ipc_release(IPC_SEM_ACCESS); return success; }
int32_t ipc_vchi_bulk_queue_receive(/*VCHI_SERVICE_HANDLE_T*/int32_t handle, void * data_dst, uint32_t data_size, VCHI_FLAGS_T flags, void * bulk_handle ) { // vchi_bulk_queue_receive(handle,data_dst,data_size,flags,bulk_handle); int32_t events; int32_t success=0; os_assert(data_size<IPC_SHARED_MEM_SIZE); ipc_aquire(IPC_SEM_ACCESS); ipc->buffer[0] = set_vchi_handle(handle); ipc->buffer[1] = data_size; ipc->buffer[2] = flags; ipc->buffer[3] = 0xbabeface; ipc_signal(IPC_VCHI_BULK_RECEIVE_EVENT); ipc_wait(&events); os_assert(events == (1<<IPC_VCHI_BULK_RECEIVE_EVENT)); memcpy(data_dst,&ipc->buffer[4],data_size); ipc_release(IPC_SEM_ACCESS); return success; }
/*********************************************************** * Name: vchi_bulk_aux_service_init * * Arguments: VCHI_CONNECTION_T *connections, * const uint32_t num_connections * * Description: Routine to init the bulk auxiliary service * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t vchi_bulk_aux_service_init( VCHI_CONNECTION_T **connections, const uint32_t num_connections, void **state ) { int32_t success = 0; uint32_t count = 0; BULK_AUX_SERVICE_INFO_T *bulk_aux_info = (BULK_AUX_SERVICE_INFO_T *)*state; os_assert(num_connections <= VCHI_MAX_NUM_CONNECTIONS); if (!bulk_aux_info) { bulk_aux_info = (BULK_AUX_SERVICE_INFO_T *)os_malloc( VCHI_MAX_NUM_CONNECTIONS * sizeof(BULK_AUX_SERVICE_INFO_T), 0, "vchi:bulk_aux_info" ); memset( bulk_aux_info, 0,VCHI_MAX_NUM_CONNECTIONS * sizeof(BULK_AUX_SERVICE_INFO_T) ); for( count = 0; count < num_connections; count++ ) { // record the connection info bulk_aux_info[count].connection = connections[count]; // create the server (this is a misnomer as the the BULX service acts as both client and server success += (connections[count])->api->service_connect((connections[count])->state,MAKE_FOURCC("BULX"),0,0,VC_TRUE,bulk_aux_callback,&bulk_aux_info[count],VC_FALSE,VC_FALSE,VC_FALSE,&bulk_aux_info[count].open_handle); os_assert(success == 0); } } else { for( count = 0; count < num_connections; count++ ) { os_assert( bulk_aux_info[count].connection == connections[count]); } } *state = bulk_aux_info; return success; }
/* ---------------------------------------------------------------------- * read data from the given non-wrap fifo, by copying out of the * fifo to the given address * * returns 0 on success, non-0 otherwise * -------------------------------------------------------------------- */ int32_t non_wrap_fifo_read( VCHI_NWFIFO_T *_fifo, void *data, const uint32_t max_data_size ) { NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo; int32_t success = -1; uint8_t *address = NULL; uint32_t length; os_assert(0); // FIXME: will deadlock os_semaphore_obtain( &fifo->sem ); os_assert( fifo->base_address ); // request the address and length for this transfer if ( non_wrap_fifo_request_read_address(fifo,&address,&length) == 0 ) { if ( length <= max_data_size ){ // there is enough space and the data has been written so we can copy it out memcpy(data,address,length); // now tidy up our information about what is in the FIFO if ( non_wrap_fifo_read_complete(fifo,address) == 0 ) { // success! success = 0; } } } os_semaphore_release( &fifo->sem ); return success; }
/*********************************************************** * Name: software_fifo_create * * Arguments: const uint32_t size - size of FIFO (in bytes) * int alignment - required alignment (bytes) * SOFTWARE_FIFO_HANDLE_T *handle - handle to this FIFO * * Description: Allocates space for a FIFO and initialises it * * Returns: 0 if successful, any other value is failure * ***********************************************************/ int32_t software_fifo_create( const uint32_t size, int alignment, SOFTWARE_FIFO_HANDLE_T *handle ) { int32_t success = -1; // check that the alignment is a power of 2 or 0 os_assert((OS_COUNT(alignment) == 1) || (alignment == 0)); // put the alignment into a form we can use (must be power of 2) alignment = alignment ? alignment-1 : 0; // check we have a valid pointer if(handle) { memset(handle,0,sizeof(SOFTWARE_FIFO_HANDLE_T)); // allocate slightly more space than we need so that we can get the required alignment handle->malloc_address = (uint8_t *)os_malloc(size+alignment, OS_ALIGN_DEFAULT, ""); if(handle->malloc_address) { handle->base_address = (uint8_t *)(((uint32_t)handle->malloc_address + alignment) & ~alignment); handle->read_ptr = handle->base_address; handle->write_ptr = handle->base_address; handle->size = size; handle->bytes_read = 0; handle->bytes_written = 0; success = os_semaphore_create(&handle->software_fifo_semaphore,OS_SEMAPHORE_TYPE_SUSPEND); // oops, unable to create the semaphore os_assert(success == 0); } } // oops, looks like you've run out of memory os_assert(success == 0); return(success); }
/*********************************************************** * Name: os_cond_broadcast * * Arguments: OS_COND_T *cond * bool_t sem_claimed * * Description: Routine to signal all threads waiting on * a condition variable. The caller must * say whether they have obtained the semaphore. * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_cond_broadcast( OS_COND_T *cond, bool_t sem_claimed ) { int32_t success = -1; if (cond) { COND_WAITER_T *w; // Ensure the condvar's semaphore is claimed for thread-safe access if (!sem_claimed) { success = os_semaphore_obtain((*cond)->semaphore); os_assert(success == 0); } for (w = (*cond)->waiters; w; w = w->next) { vcos_event_signal(&w->latch); } (*cond)->waiters = NULL; success = 0; if (!sem_claimed) { success = os_semaphore_release((*cond)->semaphore); } os_assert(success == 0); } return success; }
/*********************************************************** * Name: os_cond_wait * * Arguments: OS_COND_T *cond, * OS_SEMAPHORE_T *semaphore * * Description: Routine to wait for a condition variable * to be signalled. Semaphore is released * while waiting. The same semaphore must * always be used. * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_cond_wait( OS_COND_T *cond, OS_SEMAPHORE_T *semaphore ) { int32_t success = -1; if (cond && semaphore) { COND_WAITER_T w; COND_WAITER_T *p, **prev; // Check the API is being followed os_assert((*cond)->semaphore == semaphore && os_semaphore_obtained(semaphore)); // Fill in a new waiter structure allocated on our stack w.next = NULL; vcos_demand(vcos_event_create(&w.latch, NULL) == VCOS_SUCCESS); // Add it to the end of the condvar's wait queue (we wake first come, first served) prev = &(*cond)->waiters; p = (*cond)->waiters; while (p) prev = &p->next, p = p->next; *prev = &w; // Ready to go to sleep now success = os_semaphore_release(semaphore); os_assert(success == 0); vcos_event_wait(&w.latch); success = os_semaphore_obtain(semaphore); os_assert(success == 0); } return success; }
void os_task_wait_time_set( uint8_t tid, uint8_t id, uint16_t time ) { os_assert( tid < nTasks ); os_assert( time > 0 ); task_list[ tid ].clockId = id; task_list[ tid ].time = time; task_waiting_time_set( tid ); }
/*********************************************************** * Name: software_fifo_data_available * * Arguments: SOFTWARE_FIFO_HANDLE_T handle - handle to this FIFO * * Description: Returns the amount of data available to be read * * Returns: negative values are errors * ***********************************************************/ int32_t software_fifo_data_available( SOFTWARE_FIFO_HANDLE_T *handle ) { int32_t data_available = (int32_t)(handle->bytes_written - handle->bytes_read); os_assert(handle->base_address); os_assert(data_available <= handle->size); return( data_available ); }
/*********************************************************** * Name: software_fifo_room_available * * Arguments: SOFTWARE_FIFO_HANDLE_T handle - handle to this FIFO * * Description: Returns the amount of space left in the FIFO * * Returns: negative values are errors * ***********************************************************/ int32_t software_fifo_room_available( SOFTWARE_FIFO_HANDLE_T *handle ) { int32_t room_available = (int32_t)handle->size - (int32_t)((handle->bytes_written - handle->bytes_read)); os_assert(handle->base_address); os_assert((room_available <= handle->size) && (room_available >= 0)); return( room_available ); }
int32_t ipc_wait(int32_t *events) { int32_t status; int32_t success=0; os_assert(myIPC); status = os_eventgroup_retrieve( &myIPC->s2c_event,events); os_assert( status == 0 ); return success; }
int32_t ipc_signal(int32_t event_mask) { int32_t status; int32_t success=0; os_assert(myIPC); //myIPC->buffer[3] = IPC_CLIENT_SIG; status = os_eventgroup_signal( &myIPC->c2s_event,event_mask); os_assert( status == 0 ); return success; }
/*********************************************************** * Name: os_init * * Arguments: void * * Description: Routine to init the local OS stack - called from vchi_init * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_init( void ) { int success; vcos_init(); os_cond_init(); os_assert(!vcos_os_inited++); /* should only be called once now */ success = os_semaphore_create(&os_mutex_global, OS_SEMAPHORE_TYPE_SUSPEND); os_assert(success == 0); return success; }
size_t vchi_bulk_aux_service_form_header( void *dest, size_t dest_len, fourcc_t service_id, MESSAGE_TX_CHANNEL_T channel, uint32_t total_size, uint32_t chunk_size, uint32_t crc, uint32_t data_size, int16_t data_shift, uint16_t head_bytes, uint16_t tail_bytes ) { uint8_t *message = (uint8_t *)dest; if ( dest_len < BULX_HEADER_SIZE ) { os_assert( 0 ); return 0; } vchi_writebuf_fourcc( &message[BULX_SERVICE_OFFSET], service_id ); vchi_writebuf_uint32( &message[BULX_SIZE_OFFSET], total_size ); vchi_writebuf_uint32( &message[BULX_CHUNKSIZE_OFFSET], chunk_size ); vchi_writebuf_uint32( &message[BULX_CRC_OFFSET], crc ); vchi_writebuf_uint32( &message[BULX_DATA_SIZE_OFFSET], data_size ); vchi_writebuf_uint16( &message[BULX_DATA_SHIFT_OFFSET], data_shift ); // actually int16 message[BULX_CHANNEL_OFFSET] = channel; message[BULX_RESERVED_OFFSET] = 0; vchi_writebuf_uint16( &message[BULX_HEAD_SIZE_OFFSET], head_bytes ); vchi_writebuf_uint16( &message[BULX_TAIL_SIZE_OFFSET], tail_bytes ); return BULX_HEADER_SIZE; }
int32_t ipc_vchi_msg_hold( /*VCHI_SERVICE_HANDLE_T*/int32_t handle, void **data, uint32_t *msg_size, VCHI_FLAGS_T flags, VCHI_HELD_MSG_T *message_handle ) { //vchi_msg_hold(handle,data,msg_size,flags,message_handle); int32_t events; int32_t success=0; //myIPC->buffer[1] = 0; myIPC->buffer[2] = flags; myIPC->buffer[3] = handle; ipc_signal(IPC_VCHI_MSG_HOLD_EVENT); ipc_wait(&events); os_assert(events == (1<<IPC_VCHI_MSG_HOLD_EVENT)); *msg_size = myIPC->buffer[0]; //message_handle = (VCHI_HELD_MSG_T*)myIPC->buffer[2]; *data = (void*)myIPC->buffer[4]; return success; }
/* ---------------------------------------------------------------------- * remove the slot with the given address from the given non-wrap fifo. * intended for out-of-order operations * * the given address must belong to a slot between the read and write * slots, and be in the 'ready' state * * returns 0 on success, non-0 otherwise * -------------------------------------------------------------------- */ int32_t non_wrap_fifo_remove( VCHI_NWFIFO_T *_fifo, void *address ) { NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo; int32_t success = -1; uint32_t slot; os_semaphore_obtain( &fifo->sem ); slot = fifo->read_slot; os_assert( fifo->base_address ); while( slot != fifo->write_slot ) { if ( fifo->slot_info[slot].address == address && fifo->slot_info[slot].state == NON_WRAP_READY ) { // mark this as no longer being in use fifo->slot_info[slot].state = NON_WRAP_NOT_IN_USE; success = 0; break; } // increment and wrap our slot number slot = next_slot( fifo, slot ); } // if the entry to be removed was the current read slot then we need to move on if ( slot == fifo->read_slot && success == 0 ) fifo->read_slot = next_read_slot( fifo, slot ); os_semaphore_release( &fifo->sem ); return success; }
/* ---------------------------------------------------------------------- * fetch the address and length of the oldest message in the given * non-wrap fifo * * NOTE: on success, this routine will leave the fifo locked! * * returns 0 on success, non-0 otherwise * -------------------------------------------------------------------- */ int32_t non_wrap_fifo_request_read_address( VCHI_NWFIFO_T *_fifo, const void **address, uint32_t *length ) { NON_WRAP_FIFO_HANDLE_T *fifo = (NON_WRAP_FIFO_HANDLE_T *)_fifo; int32_t success = -1; os_semaphore_obtain( &fifo->sem ); os_assert( fifo->base_address ); // check that this slot is ready to be read from if ( fifo->slot_info[fifo->read_slot].state == NON_WRAP_READY ) { *address = fifo->slot_info[fifo->read_slot].address; *length = fifo->slot_info[fifo->read_slot].length; // mark this slot as being in the process of being read fifo->slot_info[fifo->read_slot].state = NON_WRAP_READING; // success! success = 0; } // on success, the fifo is left locked if ( success != 0 ) os_semaphore_release( &fifo->sem ); return success; }
/*********************************************************** * Name: bulk_aux_callback * * Arguments: void *callback_param * const VCHI_CALLBACK_REASON_T reason * void *handle * * Description: Handles callbacks for received messages * * Returns: - * ***********************************************************/ static void bulk_aux_callback( void *callback_param, //my service local param const VCHI_CALLBACK_REASON_T reason, void *handle ) { BULK_AUX_SERVICE_INFO_T * service_info = (BULK_AUX_SERVICE_INFO_T *)callback_param; switch(reason) { case VCHI_CALLBACK_MSG_AVAILABLE: #if defined VCHI_COARSE_LOCKING os_semaphore_obtain(&service_info->connection->sem); #endif service_info->connection->api->bulk_aux_received(service_info->connection->state); #if defined VCHI_COARSE_LOCKING os_semaphore_release(&service_info->connection->sem); #endif break; case VCHI_CALLBACK_MSG_SENT: #if defined VCHI_COARSE_LOCKING os_semaphore_obtain(&service_info->connection->sem); #endif service_info->connection->api->bulk_aux_transmitted(service_info->connection->state, handle); #if defined VCHI_COARSE_LOCKING os_semaphore_release(&service_info->connection->sem); #endif break; case VCHI_CALLBACK_BULK_RECEIVED: case VCHI_CALLBACK_BULK_DATA_READ: case VCHI_CALLBACK_BULK_SENT: // bulk auxiliary service doesn't use bulk transfers(!) os_assert(0); break; } }
int32_t ipc_vchi_msg_hold( /*VCHI_SERVICE_HANDLE_T*/int32_t handle, void **data, uint32_t *msg_size, VCHI_FLAGS_T flags, VCHI_HELD_MSG_T *message_handle ) { //vchi_msg_hold(handle,data,msg_size,flags,message_handle); int32_t events; int32_t success=0; ipc_aquire(IPC_SEM_ACCESS); ipc->buffer[0] = set_vchi_handle(handle); ipc->buffer[1] = 0; ipc->buffer[2] = flags; ipc->buffer[3] = 0xbabeface; ipc_signal(IPC_VCHI_MSG_HOLD_EVENT); ipc_wait(&events); os_assert(events == (1<<IPC_VCHI_MSG_HOLD_EVENT)); *msg_size = ipc->buffer[1]; // message_handle = (VCHI_HELD_MSG_T*)ipc->buffer[2]; *data = &ipc->buffer[4]; // ipc_release(IPC_SEM_ACCESS); return success; }
/* Sets the task to wait for semaphore state */ void os_task_wait_sem_set( uint8_t tid, Sem_t sem ) { os_assert( tid < nTasks ); task_wait_sem_set( tid, sem ); /* The time is ticked to measure waiting time */ task_list[ tid ].time = 0; }
/*********************************************************** * Name: vchi_control_service_close * * Arguments: VCHI_CONNECTION_T *connections, * const uint32_t num_connections * * Description: Routine to init the control service * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t vchi_control_service_close( void ) { int32_t success = 0; #if 1 os_assert(0); #else uint32_t count = 0; for( count = 0; count < VCHI_MAX_NUM_CONNECTIONS; count++ ) { if( control_info[count].initialised == VC_TRUE) { // we have previously initialised this connection // so set it all as uninitialised // HACK HACK TBD FIXME - do we need to signal to the other end of the connections that we are closing this end?????? // similarly we would need to respond to such requests ourselves...... control_info[count].initialised = VC_FALSE; control_info[count].connection = NULL; success += os_semaphore_release( &control_info[count].connected_semaphore ); } } #endif // close the timer os_time_term(); // reset the timer offset time_offset = 0; return(success); }
/*********************************************************** * Name: software_fifo_write * * Arguments: SOFTWARE_FIFO_HANDLE_T *handle - handle to this FIFO * uint8_t * data - data to write * uint32_t data_size - how much data to write (in bytes) * * Description: Writes the required amount of data to the FIFO * * Returns: 0 if successful, any other value is failure * ***********************************************************/ int32_t software_fifo_write( SOFTWARE_FIFO_HANDLE_T *handle, const void *data, const uint32_t data_size ) { uint32_t bytes_left; os_assert(handle->base_address); // check that there is enough room in the FIFO to fulfill this request if( software_fifo_room_available(handle) < data_size ) return(-1); bytes_left = (handle->base_address+handle->size) - handle->write_ptr; if(bytes_left >= data_size) { memcpy(handle->write_ptr,data,data_size); handle->write_ptr += data_size; if(handle->write_ptr >= handle->base_address+handle->size) handle->write_ptr = handle->base_address; } else { memcpy(handle->write_ptr,data,bytes_left); handle->write_ptr = handle->base_address; memcpy(handle->write_ptr,data,data_size - bytes_left); handle->write_ptr += data_size - bytes_left; } handle->bytes_written += data_size; return(0); }
void vchi_control_reply_sub_service(void *handle, fourcc_t service_id) { CONTROL_SERVICE_INFO_T * service_info = (CONTROL_SERVICE_INFO_T *)handle; uint32_t ii; for (ii=0;ii<VCHI_MAX_SERVICES_PER_CONNECTION;ii++) { if (service_info->control_reply[ii].service_id == service_id) { service_info->control_reply[ii].reply_to_send--; os_assert(service_info->control_reply[ii].reply_to_send >=0); service_info->server_available_replies_to_send--; os_assert(service_info->server_available_replies_to_send >=0); } } }
void os_task_resume( uint8_t tid ) { os_assert( tid < nTasks ); if ( task_list[ tid ].state == SUSPENDED ) { task_list[ tid ].state = task_list[ tid ].savedState; } }
static void eeprom_test_setup(void) { int i; i2c_master_enable(I2C1, I2C_BUS_RESET); buffer_r = (uint8 *) zalloc(BUFFER_SIZE); os_assert(buffer_r != NULL); buffer_w = (uint8 *) zalloc(BUFFER_SIZE + 1); os_assert(buffer_w != NULL); buffer_w[0] = 0x0; for (i = 1; i < BUFFER_SIZE + 1; i++) buffer_w[i] = i - 1; os_log(LOG_DEBUG, "buffers are ready: r: 0x%x, w: 0x%x\n", buffer_r, buffer_w); }
/* ---------------------------------------------------------------------- * allocate space for a new non-wrap fifo, and return pointer to * opaque handle. returns NULL on failure * -------------------------------------------------------------------- */ VCHI_NWFIFO_T * non_wrap_fifo_create( const char *name, const uint32_t size, int alignment, int no_of_slots ) { int32_t success = -1; NON_WRAP_FIFO_HANDLE_T *fifo; // check that the alignment is a power of 2 or 0 #ifndef WIN32 os_assert((OS_COUNT(alignment) == 1) || (alignment == 0)); #endif // put the alignment into a form we can use (must be power of 2) alignment = alignment ? alignment - 1 : 0; // create new non-wrap fifo struct fifo = (NON_WRAP_FIFO_HANDLE_T *)os_malloc( sizeof(NON_WRAP_FIFO_HANDLE_T), OS_ALIGN_DEFAULT, "" ); os_assert( fifo ); if (!fifo) return NULL; memset( fifo, 0, sizeof(NON_WRAP_FIFO_HANDLE_T) ); fifo->name = name; // allocate slightly more space than we need so that we can get the required alignment fifo->malloc_address = (uint8_t *)os_malloc(size+alignment, OS_ALIGN_DEFAULT, ""); if ( fifo->malloc_address ) { fifo->base_address = (uint8_t *)(((size_t)fifo->malloc_address + alignment) & ~alignment); fifo->read_ptr = fifo->base_address; fifo->write_ptr = fifo->base_address; // now allocate the space for the slot_info structures fifo->slot_info = (NON_WRAP_SLOT_T *)os_malloc(no_of_slots*sizeof(NON_WRAP_SLOT_T), OS_ALIGN_DEFAULT, ""); memset( fifo->slot_info, 0, no_of_slots * sizeof(NON_WRAP_SLOT_T) ); fifo->size = size; fifo->num_of_slots = no_of_slots; success = os_semaphore_create( &fifo->sem, OS_SEMAPHORE_TYPE_SUSPEND ); os_assert(success == 0); success = os_cond_create( &fifo->space_available_cond, &fifo->sem ); os_assert(success == 0); } else { os_free(fifo); fifo = NULL; } return (VCHI_NWFIFO_T *)fifo; }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- // TDataBuffer* RFrameXferBlockProtocolStack::GetTxFrame( const TWhaTxQueueState& aWhaTxQueueState, TBool& aMore ) { TraceDump( NWSA_TX_DETAILS, ("WLANLDD: RFrameXferBlockProtocolStack::GetTxFrame")); TraceDump( NWSA_TX_DETAILS, (("WLANLDD: VO: %d packets"), iVoiceTxQueue.GetLength())); TraceDump( NWSA_TX_DETAILS, (("WLANLDD: VI: %d packets"), iVideoTxQueue.GetLength())); TraceDump( NWSA_TX_DETAILS, (("WLANLDD: BE: %d packets"), iBestEffortTxQueue.GetLength())); TraceDump( NWSA_TX_DETAILS, (("WLANLDD: BG: %d packets"), iBackgroundTxQueue.GetLength())); TDataBuffer* packet = NULL; TQueueId queueId ( EQueueIdMax ); if ( TxPossible( aWhaTxQueueState, queueId ) ) { switch ( queueId ) { case EVoice: packet = iVoiceTxQueue.GetPacket(); break; case EVideo: packet = iVideoTxQueue.GetPacket(); break; case ELegacy: packet = iBestEffortTxQueue.GetPacket(); break; case EBackGround: packet = iBackgroundTxQueue.GetPacket(); break; #ifndef NDEBUG default: TraceDump(ERROR_LEVEL, (("WLANLDD: queueId: %d"), queueId)); os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); #endif } aMore = TxPossible( aWhaTxQueueState, queueId ); } else { aMore = EFalse; } TraceDump( NWSA_TX_DETAILS, (("WLANLDD: krn meta hdr: 0x%08x"), reinterpret_cast<TUint32>(packet))); return packet; }
uint8_t task_create( taskproctype taskproc, uint8_t prio, Msg_t *msgPool, uint8_t poolSize, uint16_t msgSize ) { uint8_t taskId; tcb *task; os_assert( os_running() == 0 ); os_assert( nTasks < N_TASKS ); os_assert( taskproc != NULL ); taskId = nTasks; /* Check that no other task has the same prio */ while ( taskId != 0 ) { --taskId; os_assert( task_list[ taskId ].prio != prio ); } task = &task_list[ nTasks ]; task->tid = nTasks; task->prio = prio; task->state = READY; task->savedState = READY; task->semaphore = 0; task->internal_state = 0; task->taskproc = taskproc; task->waitSingleEvent = 0; task->time = 0; if ( poolSize > 0 ) { task->msgQ = os_msgQ_create( msgPool, poolSize, msgSize ); } else { task->msgQ = NO_QUEUE; } os_task_clear_wait_queue( nTasks ); nTasks++; return task->tid; }
/*********************************************************** * Name: os_cond_create * * Arguments: OS_COND_T *condition * OS_SEMAPHORE_T *semaphore * * Description: Routine to create a condition variable * * Returns: int32_t - success == 0 * ***********************************************************/ int32_t os_cond_create( OS_COND_T *condition, OS_SEMAPHORE_T *semaphore ) { int32_t success = -1; int i; os_assert(vcos_cv_inited); if( condition && semaphore ) { uint32_t n; vcos_mutex_lock(&cond_latch); // start searching from os_cond_next n = os_cond_next; for (i=0; i<MAX_COND; i++) { if ( os_cond[n].semaphore == NULL ) break; if ( ++n == MAX_COND ) n = 0; } if ( i < MAX_COND ) { OS_COND_T cond = &os_cond[n]; cond->waiters = NULL; cond->semaphore = semaphore; *condition = cond; success = 0; if ( ++n == MAX_COND ) n = 0; os_cond_next = n; } os_assert( success == 0 ); vcos_mutex_unlock( &cond_latch ); } return success; }