ar9170_tx_queue* ieee80211_psm_can_send_first_atim(struct ar9170* ar) { #if IBSS_PSM_DEBUG_DEEP printf("DEBUG: IBSS_PSM; Check and send first atim.\n"); #endif int i,j; int found_atim_at_index = -1; /* * Walk through the list of pending ATIM frames; * Remove the pending ATIMS for STAs that are * already known to be awake for the following * Data Transmission period. Stop and return * the list when an ATIM transmission is valid */ struct sk_buff* atim_packet = NULL; /* Obtain a reference to the ATIM Queue of the considered AR9170 device. */ ar9170_tx_queue* the_atim_queue = ar->tx_pending_atims; if (linked_list_is_empty(the_atim_queue)) { /* There are no pending ATIMs. */ #if IBSS_PSM_DEBUG printf("WARNING: There are no pending ATIMs!\n"); #endif return NULL; } else { /* Walk along the non-empty queue. */ for (i=0; i<linked_list_get_len(the_atim_queue); i++) { atim_packet = linked_list_get_element_at(the_atim_queue, i); if (atim_packet == NULL) { printf("ERROR: The ATIM queue is empty before it finishes!\n"); return NULL; } else { /* Check whether the receiver is awake */ if (!ieee80211_psm_is_DA_awake(atim_packet)) { /* We found a valid ATIM frame */ found_atim_at_index = i; break; } } } /* If valid ATIM packet is found */ if (found_atim_at_index >= 0) { #if IBSS_MH_PSM_DEBUG_DEEP printf("DEBUG: PSM; ATIM at position %d must be sent.\n", found_atim_at_index); #endif /* Erase [remove] all ATIM packets in front of this position */ for (j=0; j< found_atim_at_index; j++) { #if IBSS_PSM_DEBUG printf("DEBUG: PSM: Removing ATIM frame at position: %u.n", j); #endif struct sk_buff* an_atim = linked_list_get(the_atim_queue); if (an_atim->data != NULL) { sfree(an_atim->data); an_atim->data = NULL; } the_atim_queue = linked_list_remove_first(the_atim_queue); } return the_atim_queue; } else { #if IBSS_PSM_DEBUG_DEEP printf("DEBUG: No ATIM needs to be sent. Shall erase the whole list.\n"); #endif for (j=0; j<linked_list_get_len(the_atim_queue); j++) { struct sk_buff* an_atim = linked_list_get(the_atim_queue); if ((an_atim != NULL) && (an_atim->data != NULL)) { sfree(an_atim->data); an_atim->data = NULL; } } linked_list_erase(the_atim_queue); return NULL; } } }
static int bfwork_run_threaded(bam_fwork_t *fwork) { int err; bam_region_t *region; linked_list_t *regions; double times; omp_lock_t end_condition_lock; int end_condition; omp_lock_t reads_lock; size_t reads; size_t reads_to_write; //Init lock omp_init_lock(&end_condition_lock); omp_init_lock(&reads_lock); //#pragma omp parallel private(err, region, regions, times, reads_to_write) { //#pragma omp single { printf("Running in multithreading mode with %d threads\n", omp_get_max_threads()); end_condition = 1; reads = 0; } #pragma omp parallel sections private(err, region, regions, times, reads_to_write) { //Region read #pragma omp section { regions = fwork->regions_list; while(1) { //Create new current region region = (bam_region_t *)malloc(sizeof(bam_region_t)); breg_init(region); //Fill region #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif err = bfwork_obtain_region(fwork, region); #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_READ, fwork->context->time_stats, times / (double)region->size); omp_unset_lock(®ion->lock); #endif if(err) { if(err == WANDER_REGION_CHANGED || err == WANDER_READ_EOF) { //Until process, this region cant be writed omp_test_lock(®ion->write_lock); //Add region to framework regions bfwork_region_insert(fwork, region); #pragma omp task untied firstprivate(region) private(err) { int i; size_t pf_l; double aux_time; //Process region omp_set_lock(®ion->lock); #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif //Process region pf_l = fwork->context->processing_f_l; for(i = 0; i < pf_l; i++) { fwork->context->processing_f[i](fwork, region); } #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_PROC_FUNC, fwork->context->time_stats, times / (double)region->size); aux_time = omp_get_wtime(); #endif omp_unset_lock(®ion->lock); omp_set_lock(&reads_lock); reads += region->size; printf("Reads processed: %lu\r", reads); omp_unset_lock(&reads_lock); #ifdef D_TIME_DEBUG aux_time = omp_get_wtime() - aux_time; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(region->size != 0) time_add_time_slot(D_FWORK_PROC, fwork->context->time_stats, (times + aux_time) / (double)region->size); omp_unset_lock(®ion->lock); #endif //Set this region as writable omp_unset_lock(®ion->write_lock); } //End readings if(err == WANDER_READ_EOF) break; } else { if(err == WANDER_READ_TRUNCATED) { LOG_WARN("Readed truncated read\n"); } else { LOG_FATAL_F("Failed to read next region, error code: %d\n", err); } break; } } else { //No more regions, end loop LOG_INFO("No more regions to read"); break; } } omp_set_lock(&end_condition_lock); end_condition = 0; omp_unset_lock(&end_condition_lock); //LOG_WARN("Read thread exit\n"); }//End read section //Write section #pragma omp section { regions = fwork->regions_list; omp_set_lock(&end_condition_lock); while(end_condition || linked_list_size(regions) > 0) { omp_unset_lock(&end_condition_lock); #ifdef D_TIME_DEBUG times = omp_get_wtime(); #endif //Get next region omp_set_lock(&fwork->regions_lock); region = linked_list_get_first(regions); omp_unset_lock(&fwork->regions_lock); if(region == NULL) { omp_set_lock(&end_condition_lock); continue; } //Wait region to be writable omp_set_lock(®ion->write_lock); //Write region omp_set_lock(&fwork->output_file_lock); reads_to_write = region->size; breg_write_n(region, reads_to_write, fwork->output_file); omp_unset_lock(&fwork->output_file_lock); //Remove from list omp_set_lock(&fwork->regions_lock); if(linked_list_size(regions) == 1) //Possible bug? linked_list_clear(regions, NULL); else linked_list_remove_first(regions); //Signal read section if regions list is full if(linked_list_size(regions) < (FWORK_REGIONS_MAX / 2) ) omp_unset_lock(&fwork->free_slots); omp_unset_lock(&fwork->regions_lock); #ifdef D_TIME_DEBUG times = omp_get_wtime() - times; omp_set_lock(®ion->lock); if(fwork->context->time_stats) if(reads_to_write != 0) time_add_time_slot(D_FWORK_WRITE, fwork->context->time_stats, times / (double)reads_to_write); omp_unset_lock(®ion->lock); #endif //Free region breg_destroy(region, 1); free(region); omp_set_lock(&end_condition_lock); } omp_unset_lock(&end_condition_lock); //LOG_WARN("Write thread exit\n"); }//End write section }//End sections }//End parallel //Lineskip printf("\n"); //Free omp_destroy_lock(&end_condition_lock); return NO_ERROR; }