static u32 netvsc_get_next_send_section(struct netvsc_device *net_device) { unsigned long index; u32 max_words = net_device->map_words; unsigned long *map_addr = (unsigned long *)net_device->send_section_map; u32 section_cnt = net_device->send_section_cnt; int ret_val = NETVSC_INVALID_INDEX; int i; int prev_val; for (i = 0; i < max_words; i++) { if (!~(map_addr[i])) continue; index = ffz(map_addr[i]); prev_val = sync_test_and_set_bit(index, &map_addr[i]); if (prev_val) continue; if ((index + (i * BITS_PER_LONG)) >= section_cnt) break; ret_val = (index + (i * BITS_PER_LONG)); break; } return ret_val; }
void* thread_func(void*) { pthread_t thread_id = pthread_self(); //printf("%d\n", sched_getcpu()); int k = 0; unsigned int *local_queue = (unsigned int*) malloc(sizeof(unsigned int)*num_of_nodes); int local_queue_size = 0; while(1) { if (k%2 ==0) { while (current_a_size > 0) { unsigned int index; int read_pos = __sync_sub_and_fetch(¤t_a_size, 1); if (read_pos >= 0) { index = current_a[read_pos]; Node cur_node = node_list[index]; for (int i = cur_node.start; i < (cur_node.start+cur_node.edge_num); i++) { unsigned int id = edge_list[i].dest; int its_color = sync_test_and_set_bit(id, bitmap); if (!its_color) { cost[id] = cost[index] + 1; //int write_pos = __sync_fetch_and_add(¤t_b_size, 1); //current_b[write_pos] = id; local_queue[local_queue_size] = id; local_queue_size += 1; } } } else { __sync_fetch_and_add(¤t_a_size, 1); } } if (local_queue_size) { int write_pos = __sync_fetch_and_add(¤t_b_size, local_queue_size); for (int i=0; i<local_queue_size; i++) { current_b[write_pos+i] = local_queue[i]; } local_queue_size = 0; } pthread_barrier_wait(&barr); if (current_b_size == 0) break; pthread_barrier_wait(&barr2); } else { while (current_b_size > 0) { unsigned int index; int read_pos = __sync_sub_and_fetch(¤t_b_size, 1); if (read_pos >= 0) { index = current_b[read_pos]; Node cur_node = node_list[index]; for (int i = cur_node.start; i < (cur_node.start+cur_node.edge_num); i++) { unsigned int id = edge_list[i].dest; int its_color = sync_test_and_set_bit(id, bitmap); if (!its_color) { cost[id] = cost[index] + 1; //int write_pos = __sync_fetch_and_add(¤t_a_size, 1); //current_a[write_pos] = id; local_queue[local_queue_size] = id; local_queue_size += 1; } } } else { __sync_fetch_and_add(¤t_b_size, 1); } } if (local_queue_size) { int write_pos = __sync_fetch_and_add(¤t_a_size, local_queue_size); for (int i=0; i<local_queue_size; i++) { current_a[write_pos+i] = local_queue[i]; } local_queue_size = 0; } pthread_barrier_wait(&barr); if (current_a_size == 0) break; pthread_barrier_wait(&barr2); } k++; } }