#include "RCCE.h" #include "RCCE_pwr_wq.h" #include int RCCE_WI_valid(void *); int RCCE_qsort(char *, size_t, size_t, int (*)(const void*, const void*)); /* comparison function used in routine to sort core IDs */ int id_compare(const void *e1, const void *e2); int RCCE_setup_work_queue_teams(QUEUE_PARMS *wq_pars){ int NP, ID, ue, size, mem, master, team_lead, team_size, local_rank; int test, isleader; int *team_member, *master_list; NP = wq_pars->NP = RCCE_num_ues(); ID = wq_pars->ID = RCCE_ue(); team_member = wq_pars->team_member; master_list = wq_pars->master_list; /* determine the number of UEs in the local power domain and form teams */ wq_pars->team_size = team_size = RCCE_power_domain_size(); wq_pars->team_lead = team_lead = RCCE_power_domain_master(); if (team_lead == ID) { /* the team lead is the first team member */ team_member[0] = team_lead; size = 1; /* the team leads collects IDs from its team members ... */ while (sizemaster = NP-1; /* the team containing the overall master must remove it from its member list */ if (team_member[team_size-1] == master) wq_pars->team_size = --team_size; /* the overall master is not in any team */ if (ID==master) team_size = wq_pars->team_size = 0; /* each UE determines its rank within the team */ local_rank = wq_pars->local_rank = 0; for (ue=0; uelocal_rank = ue; /* this code determines number of power domain leads, plus list of UEs */ if (ID == master) { wq_pars->master_number = 0; for (int ue=0; uemaster_number] = ue; (wq_pars->master_number)++; } } } else { /* all cores let the master know their team lead status */ isleader = (ID == team_lead); RCCE_send((char *)(&isleader), sizeof(int), master); } /* all UEs report their team size and memberships */ // for (ue=0; uemaster_number; ue++) { RCCE_recv_test((char *)(&ignore), sizeof(int), wq_pars->master_list[ue], &test); if (test) { // printf("Master sends work to UE %d\n", wq_pars->master_list[ue]); RCCE_send((char *)address, size, wq_pars->master_list[ue]); count++; /* generate the next work item */ RCCE_new_work_item(work_item, wq_pars); } } } else { /* this loop ends all teams, so must insist each team checks in */ for (ue=0; uemaster_number; ue++) { RCCE_recv((char *)(&ignore), sizeof(int), wq_pars->master_list[ue]); // printf("Master sends end of work message to UE %d\n", ue); RCCE_send((char *)address, size, wq_pars->master_list[ue]); } } return(count); } int RCCE_queue_member_loop(void *work_item, QUEUE_PARMS *wq_pars) { int gimme_work, mem; int size = RCCE_WI_size(work_item); void *address = RCCE_WI_address(work_item); /* ask for work if I am a team lead */ if (wq_pars->ID == wq_pars->team_lead) { RCCE_send((char *)(&gimme_work), sizeof(int), wq_pars->master); RCCE_recv((char *)address, size, wq_pars->master); /* team leads parcel out the work to the workers */ for (mem=1; mem<(wq_pars->team_size); mem++) { printf("Team lead %d sends work to UE %d\n", RCCE_ue(), wq_pars->team_member[mem]); fflush(0); RCCE_send((char *)address, size, wq_pars->team_member[mem]); } } else { RCCE_recv((char *)address, size, wq_pars->team_lead); } if (RCCE_WI_valid(work_item)) { RCCE_execute_work_item(work_item, wq_pars); // printf("UE %d executed work item\n", wq_pars->ID); } else { // printf("UE %d received stop queue task\n", RCCE_ue()); return(1); } return(RCCE_SUCCESS); }