lkfqReadRelease(lkfq_tc_t * pQ, lkfq_data_p pD) { CCURASSERT(pQ); CCURASSERT(pD); if(pQ && pD) { #if TRANSC_LKFQ_LOCKCK /* pQ->tQFree Mutex here */ if(pQ->bLock) pthread_mutex_lock(&(pQ->tQFree.tLock)); #endif /* TRANSC_LKFQ_LOCKCK */ while(1) { if(MISC_LKFQ_STS_FAIL == lfds611_queue_enqueue(pQ->tQFree.pRbQs,pD)) usleep(10); else break; } #if TRANSC_LKFQ_LOCKCK /* pQ->tQFree Mutex here */ if(pQ->bLock) pthread_mutex_unlock(&(pQ->tQFree.tLock)); #endif /* TRANSC_LKFQ_LOCKCK */ } }
thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state ) { struct queue_test_rapid_enqueuing_and_dequeuing_state *qtreds; time_t start_time; lfds611_atom_t user_data; assert( queue_test_rapid_enqueuing_and_dequeuing_state != NULL ); qtreds = (struct queue_test_rapid_enqueuing_and_dequeuing_state *) queue_test_rapid_enqueuing_and_dequeuing_state; lfds611_queue_use( qtreds->qs ); time( &start_time ); while( time(NULL) < start_time + 10 ) { lfds611_queue_enqueue( qtreds->qs, (void *) (qtreds->counter++) ); lfds611_queue_dequeue( qtreds->qs, (void *) &user_data ); } return( (thread_return_t) EXIT_SUCCESS ); }
lkfqWrite(lkfq_tc_t* pQ, lkfq_data_p pD) { CCURASSERT(pQ); CCURASSERT(pD); if(pQ && pD) { /* Flush the freelist before writing. */ lkfqFlushFreeList(pQ); #if TRANSC_LKFQ_LOCKCK /* pQ->tQAlloc Mutex here */ if(pQ->bLock) pthread_mutex_lock(&(pQ->tQAlloc.tLock)); #endif /* TRANSC_LKFQ_LOCKCK */ if(MISC_LKFQ_STS_FAIL == lfds611_queue_enqueue(pQ->tQAlloc.pRbQs,pD)) { cp_mempool_free(pQ->pMp, pD); } #if TRANSC_LKFQ_LOCKCK /* pQ->tQAlloc Mutex here */ if(pQ->bLock) pthread_mutex_unlock(&(pQ->tQAlloc.tLock)); #endif /* TRANSC_LKFQ_LOCKCK */ } }
void lfds611_ringbuffer_put_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element *fe ) { assert( rs != NULL ); assert( fe != NULL ); lfds611_queue_enqueue( rs->qs, fe ); return; }
//------------------------------------------------------------------------------ void msc_log_declare_proto ( const msc_proto_t protoP) //------------------------------------------------------------------------------ { int rv = 0; msc_queue_item_t *new_item_p = NULL; char *char_message_p = NULL; if ((MIN_MSC_PROTOS <= protoP) && (MAX_MSC_PROTOS > protoP)) { // may be build a memory pool for that also ? new_item_p = malloc (sizeof (msc_queue_item_t)); if (NULL != new_item_p) { rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); if (0 == rv) { msc_flush_messages (); rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); } if (1 == rv) { rv = snprintf (char_message_p, MSC_MAX_MESSAGE_LENGTH, "%" PRIu64 " [PROTO] %d %s\n", __sync_fetch_and_add (&g_message_number, 1), protoP, &g_msc_proto2str[protoP][0]); if (0 > rv) { fprintf (stderr, "Error while declaring new protocol in MSC: %s", strerror (errno)); } new_item_p->message_str = char_message_p; new_item_p->message_str_size = rv; new_item_p->message_bin = NULL; new_item_p->message_bin_size = 0; rv = lfds611_queue_enqueue (g_msc_message_queue_p, new_item_p); if (0 == rv) { rv = lfds611_queue_guaranteed_enqueue (g_msc_message_queue_p, new_item_p); if (0 == rv) { fprintf (stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p); rv = lfds611_stack_guaranteed_push (g_msc_memory_stack_p, char_message_p); free (new_item_p); } } return; } else { fprintf (stderr, "Error while lfds611_stack_pop()\n"); } free (new_item_p); } else { fprintf (stderr, "Error while malloc in MSC"); } } }
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( void *queue_test_enqueuing_state ) { struct queue_test_enqueuing_state *qtes; assert( queue_test_enqueuing_state != NULL ); qtes = (struct queue_test_enqueuing_state *) queue_test_enqueuing_state; lfds611_queue_use( qtes->qs ); // TRD : top byte of counter is already our thread number while( lfds611_queue_enqueue(qtes->qs, (void *) qtes->counter++) ); return( (thread_return_t) EXIT_SUCCESS ); }
/** @brief Send a message to another module. * @param[in] pMsg The pointer of message to be sent. * @return 0: success. ****************************************************************************/ int FwkMsg::send(tMsg *pMsg) { FwkTask *pTask = stFwkCtx.aTasks[pMsg->dstMod]; //$ Enqueue message in destination task queue lfds611_queue_enqueue(pTask->msgQ, (void*)pMsg); { //$ Call to write for an event fd must be of 8 bytes ssize_t ret; eventfd_t sem_counter = 1; ret = write(pTask->task_event_fd, &sem_counter, sizeof (sem_counter)); AssertFatal(ret==sizeof(sem_counter), "Write to task message FD (%d) failed (%d/%d)\n", pMsg->dstMod, (int)ret, (int)sizeof (sem_counter)); } return 0; }
thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_dequeuer( void *queue_test_enqueuing_and_dequeuing_state ) { struct queue_test_enqueuing_and_dequeuing_state *qteds; time_t start_time; lfds611_atom_t thread, count, user_data; assert( queue_test_enqueuing_and_dequeuing_state != NULL ); qteds = (struct queue_test_enqueuing_and_dequeuing_state *) queue_test_enqueuing_and_dequeuing_state; lfds611_queue_use( qteds->qs ); time( &start_time ); while( time(NULL) < start_time + 10 ) { lfds611_queue_enqueue( qteds->qs, (void *) (qteds->counter++) ); lfds611_queue_dequeue( qteds->qs, (void *) &user_data ); thread = user_data >> (sizeof(lfds611_atom_t)*8-8); count = (user_data << 8) >> 8; if( thread >= qteds->cpu_count ) qteds->error_flag = RAISED; else { if( count < qteds->per_thread_counters[thread] ) qteds->error_flag = RAISED; if( count >= qteds->per_thread_counters[thread] ) qteds->per_thread_counters[thread] = count+1; } } return( (thread_return_t) EXIT_SUCCESS ); }
void queue_test_rapid_enqueuing_and_dequeuing( void ) { unsigned int loop, cpu_count; thread_state_t *thread_handles; struct lfds611_queue_state *qs; struct queue_test_rapid_enqueuing_and_dequeuing_state *qtreds; struct lfds611_validation_info vi = { 50000, 50000 }; lfds611_atom_t user_data, thread, count, *per_thread_counters; enum lfds611_data_structure_validity dvs[2]; internal_display_test_name( "Rapid enqueuing and dequeuing (10 seconds)" ); cpu_count = abstraction_cpu_count(); lfds611_queue_new( &qs, 100000 ); for( loop = 0 ; loop < 50000 ; loop++ ) lfds611_queue_enqueue( qs, NULL ); qtreds = malloc( sizeof(struct queue_test_rapid_enqueuing_and_dequeuing_state) * cpu_count ); for( loop = 0 ; loop < cpu_count ; loop++ ) { (qtreds+loop)->qs = qs; (qtreds+loop)->counter = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8); } thread_handles = malloc( sizeof(thread_state_t) * cpu_count ); for( loop = 0 ; loop < cpu_count ; loop++ ) abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_rapid_enqueuer_and_dequeuer, qtreds+loop ); for( loop = 0 ; loop < cpu_count ; loop++ ) abstraction_thread_wait( thread_handles[loop] ); free( thread_handles ); lfds611_queue_query( qs, LFDS611_QUEUE_QUERY_VALIDATE, (void *) &vi, (void *) dvs ); // TRD : now check results per_thread_counters = malloc( sizeof(lfds611_atom_t) * cpu_count ); for( loop = 0 ; loop < cpu_count ; loop++ ) *(per_thread_counters+loop) = 0; while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and lfds611_queue_dequeue(qs, (void *) &user_data) ) { thread = user_data >> (sizeof(lfds611_atom_t)*8-8); count = (user_data << 8) >> 8; if( thread >= cpu_count ) { dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA; break; } if( per_thread_counters[thread] == 0 ) per_thread_counters[thread] = count; if( count < per_thread_counters[thread] ) dvs[0] = LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS; if( count >= per_thread_counters[thread] ) per_thread_counters[thread] = count+1; } free( per_thread_counters ); free( qtreds ); lfds611_queue_delete( qs, NULL, NULL ); internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] ); return; }
void queue_test_dequeuing( void ) { unsigned int loop, cpu_count; thread_state_t *thread_handles; struct lfds611_queue_state *qs; struct queue_test_dequeuing_state *qtds; struct lfds611_validation_info vi = { 0, 0 }; enum lfds611_data_structure_validity dvs[2]; /* TRD : create a queue with 1,000,000 elements use a single thread to enqueue every element each elements user data is an incrementing counter then run one thread per CPU where each busy-works dequeuing when an element is dequeued, we check (on a per-thread basis) the value deqeued is greater than the element previously dequeued */ internal_display_test_name( "Dequeuing" ); cpu_count = abstraction_cpu_count(); lfds611_queue_new( &qs, 1000000 ); for( loop = 0 ; loop < 1000000 ; loop++ ) lfds611_queue_enqueue( qs, (void *) (lfds611_atom_t) loop ); qtds = malloc( sizeof(struct queue_test_dequeuing_state) * cpu_count ); for( loop = 0 ; loop < cpu_count ; loop++ ) { (qtds+loop)->qs = qs; (qtds+loop)->error_flag = LOWERED; } thread_handles = malloc( sizeof(thread_state_t) * cpu_count ); for( loop = 0 ; loop < cpu_count ; loop++ ) abstraction_thread_start( &thread_handles[loop], loop, queue_test_internal_thread_simple_dequeuer, qtds+loop ); for( loop = 0 ; loop < cpu_count ; loop++ ) abstraction_thread_wait( thread_handles[loop] ); free( thread_handles ); // TRD : check queue is empty lfds611_queue_query( qs, LFDS611_QUEUE_QUERY_VALIDATE, (void *) &vi, (void *) dvs ); // TRD : check for raised error flags for( loop = 0 ; loop < cpu_count ; loop++ ) if( (qtds+loop)->error_flag == RAISED ) dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA; free( qtds ); lfds611_queue_delete( qs, NULL, NULL ); internal_display_test_result( 2, "queue", dvs[0], "queue freelist", dvs[1] ); return; }
//------------------------------------------------------------------------------ void msc_log_message ( const char *const message_operationP, const msc_proto_t proto1P, const msc_proto_t proto2P, const uint8_t * const bytesP, const unsigned int num_bytes, char *format, ...) //------------------------------------------------------------------------------ { va_list args; uint64_t mac = 0; // TO DO mac on bytesP param int rv; int rv2; msc_queue_item_t *new_item_p = NULL; char *char_message_p = NULL; if ((MIN_MSC_PROTOS > proto1P) || (MAX_MSC_PROTOS <= proto1P) || (MIN_MSC_PROTOS > proto2P) || (MAX_MSC_PROTOS <= proto2P)) { return; } new_item_p = malloc (sizeof (msc_queue_item_t)); if (NULL != new_item_p) { rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); if (0 == rv) { msc_flush_messages (); rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); } if (1 == rv) { rv = snprintf (char_message_p, MSC_MAX_MESSAGE_LENGTH, "%" PRIu64 " [MESSAGE] %d %s %d %" PRIu64 " ", __sync_fetch_and_add (&g_message_number, 1), proto1P, message_operationP, proto2P, mac); if ((0 > rv) || (MSC_MAX_MESSAGE_LENGTH < rv)) { fprintf (stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]); goto error_event; } va_start (args, format); rv2 = vsnprintf (&char_message_p[rv], MSC_MAX_MESSAGE_LENGTH - rv, format, args); va_end (args); if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) { fprintf (stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]); goto error_event; } rv += rv2; rv2 = snprintf (&char_message_p[rv], MSC_MAX_MESSAGE_LENGTH - rv, "\n"); if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) { fprintf (stderr, "Error while logging MSC message : %s/%s", &g_msc_proto2str[proto1P][0], &g_msc_proto2str[proto2P][0]); goto error_event; } rv += rv2; new_item_p->message_str = char_message_p; new_item_p->message_str_size = rv; new_item_p->message_bin = NULL; // TO DO new_item_p->message_bin_size = 0; // TO DO rv = lfds611_queue_enqueue (g_msc_message_queue_p, new_item_p); if (0 == rv) { fprintf (stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p); rv = lfds611_stack_guaranteed_push (g_msc_memory_stack_p, char_message_p); free (new_item_p); } } else { fprintf (stderr, "Error while lfds611_stack_pop()\n"); msc_flush_messages (); } } return; error_event: rv = lfds611_stack_guaranteed_push (g_msc_memory_stack_p, char_message_p); free (new_item_p); }
//------------------------------------------------------------------------------ void msc_log_event ( const msc_proto_t protoP, char *format, ...) //------------------------------------------------------------------------------ { va_list args; int rv; int rv2; msc_queue_item_t *new_item_p = NULL; char *char_message_p = NULL; if ((MIN_MSC_PROTOS > protoP) || (MAX_MSC_PROTOS <= protoP)) { return; } new_item_p = malloc (sizeof (msc_queue_item_t)); if (NULL != new_item_p) { rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); if (0 == rv) { msc_flush_messages (); rv = lfds611_stack_pop (g_msc_memory_stack_p, (void **)&char_message_p); } if (1 == rv) { rv = snprintf (char_message_p, MSC_MAX_MESSAGE_LENGTH, "%" PRIu64 " [EVENT] %d ", __sync_fetch_and_add (&g_message_number, 1), protoP); if ((0 > rv) || (MSC_MAX_MESSAGE_LENGTH < rv)) { fprintf (stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]); goto error_event; } va_start (args, format); rv2 = vsnprintf (&char_message_p[rv], MSC_MAX_MESSAGE_LENGTH - rv, format, args); va_end (args); if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) { fprintf (stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]); goto error_event; } rv += rv2; rv2 = snprintf (&char_message_p[rv], MSC_MAX_MESSAGE_LENGTH - rv, "\n"); if ((0 > rv2) || ((MSC_MAX_MESSAGE_LENGTH - rv) < rv2)) { fprintf (stderr, "Error while logging MSC event : %s", &g_msc_proto2str[protoP][0]); goto error_event; } rv += rv2; new_item_p->message_str = char_message_p; new_item_p->message_str_size = rv; new_item_p->message_bin = NULL; new_item_p->message_bin_size = 0; rv = lfds611_queue_enqueue (g_msc_message_queue_p, new_item_p); if (0 == rv) { fprintf (stderr, "Error while lfds611_queue_guaranteed_enqueue message %s in MSC", char_message_p); rv = lfds611_stack_guaranteed_push (g_msc_memory_stack_p, char_message_p); free (new_item_p); } } else { fprintf (stderr, "Error while lfds611_stack_pop()\n"); } } return; error_event: rv = lfds611_stack_guaranteed_push (g_msc_memory_stack_p, char_message_p); free (new_item_p); }