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;
}
Beispiel #2
0
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(&current_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(&current_b_size, 1);
                            //current_b[write_pos] = id;
                            local_queue[local_queue_size] = id;
                            local_queue_size += 1;
                        }
                    }
                } else {
                    __sync_fetch_and_add(&current_a_size, 1);
                }
            }
            if (local_queue_size) {
                int write_pos = __sync_fetch_and_add(&current_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(&current_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(&current_a_size, 1);
                            //current_a[write_pos] = id;
                            local_queue[local_queue_size] = id;
                            local_queue_size += 1;
                        }
                    }
                } else {
                    __sync_fetch_and_add(&current_b_size, 1);
                }
            }
            if (local_queue_size) {
                int write_pos = __sync_fetch_and_add(&current_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++;
    }
}