inline void flower(int x,int y,int l,queue<int> &q){ while(st[x]!=l){ pa[x]=y; if(S[y=match[x]]==1)qpush(y); st[x]=st[y]=l,x=pa[y]; } }
int main(){ struct queue q; q.front = 0; q.rear = 0; int i = 0; for(; i < 1000; i++){ qpush(&q, i); int a = qpop(&q); printf("%d\n", a); } exit(0); }
// Called only once per thread. static void populate(intq *q) { int i; qitem *entry = calloc(1,sizeof(qitem)*BLOCK_SIZE); #ifndef _TESTAPP_ entry[0].env = enif_alloc_env(); #endif entry[0].blockStart = 1; entry[0].home = q; qpush(q, &entry[0]); for (i = 1; i < BLOCK_SIZE; i++) { #ifndef _TESTAPP_ entry[i].env = enif_alloc_env(); #endif entry[i].home = q; qpush(q, &entry[i]); } tls_qsize += BLOCK_SIZE; }
MADNS * madns_create(char const *resolv_conf, int query_time, int server_reqs) { int i, rcvbufsiz = 128 * 1024; MADNS *mp = calloc(1, sizeof(MADNS)); char line[512]; start = tick(); mp->sock = -1; // for destroy, called inside "create". mp->query_time = OPT(query_time, MADNS_QUERY_TIME); mp->limit = MIN_CACHE; FILE *fp = fopen(OPT(resolv_conf, MADNS_RESOLV_CONF), "r"); if (fp && (mp->serv = malloc(sizeof *mp->serv * fseek(fp, 0L, 2)))) { for (rewind(fp); fgets(line, sizeof line, fp);) if (1 == sscanf(line, "nameserver %s", line)) { mp->serv[mp->nservs].ip = inet_addr(line); if (mp->serv[mp->nservs].ip != INADDR_NONE) mp->serv[mp->nservs++].nreqs = 0; } fclose(fp); } if (!mp->nservs) return madns_destroy(mp), NULL; mp->server_reqs = MIN(OPT(server_reqs, MADNS_SERVER_REQS), MAX_TIDS / mp->nservs); mp->qsize = mp->nfree = mp->nservs * mp->server_reqs; if (mp->qsize > MAX_TIDS || mp->qsize < 2) return madns_destroy(mp), NULL; mp->serv = realloc(mp->serv, sizeof(SERVER) * mp->nservs); mp->cachev = calloc(mp->limit, sizeof(CACHE_INFO *)); mp->queries = malloc(mp->qsize * sizeof(*mp->queries)); qinit(&mp->active); qinit(&mp->unused); for (i = 0; i < mp->qsize; ++i) qpush(&mp->unused, &mp->queries[i].link); mp->sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (mp->sock == -1) return madns_destroy(mp), NULL; fcntl(mp->sock, F_SETFD, FD_CLOEXEC); fcntl(mp->sock, F_SETFL, O_NONBLOCK | fcntl(mp->sock, F_GETFL, 0)); setsockopt(mp->sock, SOL_SOCKET, SO_RCVBUF, (char *)&rcvbufsiz, sizeof rcvbufsiz); return mp; }
int process(void) { int i, j, k; int cn, cm, cd; int tmp; for(i=0; i<n+2; i++) for(j=0; j<m+2; j++) for(k=0; k<4; k++) matrix[i][j][k] = INF; qfront = qrear = 0; matrix[tn][tm][0] = matrix[tn][tm][1] = matrix[tn][tm][2] = matrix[tn][tm][3]=0; qpush(tn, tm, 0); qpush(tn, tm, 1); qpush(tn, tm, 2); qpush(tn, tm, 3); while(qfront != qrear) { qpop(&cn, &cm, &cd); for(k=0; k<4; k++) { if(table[cn+dy[k]][cm+dx[k]] && k!=neg[cd]) { tmp = matrix[cn][cm][cd] + (cd==k ? 0 : 1); if(matrix[cn+dy[k]][cm+dx[k]][k] > tmp) { matrix[cn+dy[k]][cm+dx[k]][k] = tmp; qpush(cn+dy[k], cm+dx[k], k); } } } } for(i=0; i<n+2; i++) { for(j=0; j<m+2; j++) { trace[i][j] = 0; for(k=1; k<4; k++) if(matrix[i][j][trace[i][j]] > matrix[i][j][k]) trace[i][j] = k; } } return 0; }
inline bool bfs(int x){ for(int i=1;i<=n;++i)st[i]=i; memset(S+1,-1,sizeof(int)*n); queue<int>q;qpush(x); while(q.size()){ x=q.front(),q.pop(); for(size_t i=0;i<g[x].size();++i){ int y=g[x][i]; if(S[y]==-1){ pa[y]=x,S[y]=1; if(!match[y]){ for(int lst;x;y=lst,x=pa[y]) lst=match[x],match[x]=y,match[y]=x; return 1; } qpush(match[y]); }else if(!S[y]&&st[y]!=st[x]){ int l=lca(y,x); flower(y,x,l,q),flower(x,y,l,q); } } } return 0; }
int madns_request(MADNS * mp, char const *name, void *ctx) { if (!ctx || !madns_ready(mp) || strlen(name) > DNS_MAX_HOSTNAME) return 0; QUERY *qp = link_QUERY(qpull(mp->unused.next)); mp->nfree--; qp->ctx = ctx; qp->expires = 0; // so failure in "send_request" causes instant expiry. qp->tid = qp - mp->queries + mp->qsize * ((rand() & 32767) / mp->qsize + 1); qp->name = strdup(name); qp->started = tick(); qpush(&mp->active, &qp->link); send_request(mp, qp); return qp->tid; // for auditing only; anything other than (-1) is okay. }
static void * destroy_query(MADNS * mp, QUERY * qp, in_addr_t logip) { void *ret = qp->ctx; double latency = tick() - qp->started; qp->server->nreqs--; qp->server->latency += (latency - qp->server->latency) / mp->server_reqs / 2; char ips[99]; LOG("%s %s lat %.4f -> server %s %.4f reqs=%d\n", qp->name, ipstr(logip, ips + 33), latency, ipstr(qp->server->ip, ips), qp->server->latency, qp->server->nreqs); free(qp->name); qpull(&qp->link); memset(qp, 0, sizeof *qp); qpush(&mp->unused, &qp->link); mp->nfree++; return ret; }
Hand_t handPixels(int x, int y, guint16 *reduced_buffer, int reduced_width, int reduced_height){ int cornerx = x - XY_THRESHOLD; int cornery = y - XY_THRESHOLD; int boxsize = XY_THRESHOLD * 2; int tempx, tempy; int centerx, centery; if(cornerx < 0){ cornerx = 0; } if(cornery < 0){ cornery = 0; } if(cornerx + boxsize >= reduced_width && cornery + boxsize >= reduced_height){ boxsize = imin(reduced_width - cornerx, reduced_height - cornery); }else if(cornerx + boxsize >= reduced_width){ boxsize = reduced_width - cornerx; }else if(cornery + boxsize >= reduced_height){ boxsize = reduced_height - cornery; } centerx = centery = boxsize / 2; //Create a map of the pixels around the hand Pixel map[4 * XY_THRESHOLD * XY_THRESHOLD]; for(int i = 0; i < boxsize; i++){ for(int k = 0; k < boxsize; k++){ //O((XY_THRESHOLD*2)^2) tempx = cornerx + i; tempy = cornery + k; map[k * boxsize + i].x = tempx; map[k * boxsize + i].y = tempy; map[k * boxsize + i].i = i; map[k * boxsize + i].k = k; if(tempx < reduced_width && tempy < reduced_height){ map[k * boxsize + i].z = reduced_buffer[tempy * reduced_width + tempx]; }else{ map[k * boxsize + i].z = -100; } map[k * boxsize + i].visited = 0; } } map[centery * boxsize + centerx].visited = 1; int hand_pixels = 1; int averagex = 0; int averagey = 0; Pixel* q[4 * XY_THRESHOLD * XY_THRESHOLD]; int index = 0; int back = 0; back = qpush(q, &map[centery * boxsize + centerx], back); Pixel *next; while(index != back){ Pixel cur = *q[index]; //q.front() index++; //q.pop() for(int i = 0; i < 4; i++){ switch(i){ case 0: //LEFT tempx = cur.i - 1; tempy = cur.k; break; case 1: //DOWN tempx = cur.i; tempy = cur.k -1; break; case 2: //RIGHT tempx = cur.i + 1; tempy = cur.k; break; case 3: //UP tempx = cur.i; tempy = cur.k + 1; break; default: tempx = cur.i; tempy = cur.k; } if(tempx >= 0 && tempx < boxsize && tempy >= 0 && tempy < boxsize){ next = &map[tempy * boxsize + tempx]; //problem in next line if(!next->visited && abs(cur.z - next->z) < DEPTH_THRESHOLD){ hand_pixels++; averagex += next->x; averagey += next->y; back = qpush(q, next, back); } next->visited = 1; } } } averagex /= hand_pixels; averagey /= hand_pixels; int xdif = x - averagex; int ydif = y - averagey; double theta = atan2(ydif, xdif); Hand_t hand = {hand_pixels, theta}; return hand; }
// Push item from scheduler thread to worker thread. int queue_push(queue *queue, qitem *entry) { qpush(&queue->q, entry); SEM_POST(queue->sem); return 1; }
// Push entry back to home queue. // Called from worker thread to give an entry back to a scheduler thread. void queue_recycle(qitem *entry) { qpush(entry->home, entry); }
int doBoards(const node* dictionary, const boggleBoard* boards, int boardCount, int rank, int size, int* pStart, int timing) { assert(size > 1); /* Use tag 0 for completion messages, 1 for steal requests, and 2 for work given */ int i, j, total, boardSize, target, completed, someoneWants, who, remaining, work; int gotWork, donorFinished; point pt; queue* queue = qinit(); int done[size-1]; int want[size-1]; int notDone[size-1]; MPI_Request doneRequests[size-1]; MPI_Request wantRequests[size-1]; MPI_Request workRequest; /* We don't want everyone choosing the same increments randomly, so add the rank to the seed */ struct mt19937p state; sgenrand(10302011UL + rank, &state); /* Index the requests such that current thread is -1 (i.e. not present), and all */ /* the other threads follow round robin, wrapping around at 'size'. We're not */ /* explicitly interested in the contents of 'done' or 'want', only the signals. */ for (i = 1; i < size; ++i) { want[i-1] = done[i-1] = 0; target = (rank + i) % size; MPI_Irecv(done + i - 1, 1, MPI_INT, target, 0, MPI_COMM_WORLD, doneRequests + i - 1); MPI_Irecv(want + i - 1, 1, MPI_INT, target, 1, MPI_COMM_WORLD, wantRequests + i - 1); } completed = 0; total = 0; boardSize = boards[0].n; /* Maintain a local work queue with assigned board indices */ for (i = pStart[rank]; i < pStart[rank+1]; ++i) qpush(queue, i); /* Do assigned work and listen for requests for extra work */ while (!qempty(queue)) { i = qpop(queue); /* Try to find someone who's asking for work */ MPI_Testany(size-1, wantRequests, &who, &someoneWants, MPI_STATUS_IGNORE); who = (rank + 1 + who) % size; if (someoneWants) { /* printf("Who let thread %d steal my (thread %d) work (#%d)?!\n", who, rank, i); */ MPI_Send(&i, 1, MPI_INT, who, 2, MPI_COMM_WORLD); /* Reopen asynchronous receive to thread */ MPI_Irecv(want + i - 1, 1, MPI_INT, who, 1, MPI_COMM_WORLD, wantRequests - 1 + (size + who - rank) % size); } else { for (j = 0; j < boardSize * boardSize; ++j) { pt.x = j / boardSize; pt.y = j % boardSize; total += exploreOne(dictionary, boards + i, pt, timing); } } } /* Broadcast that we are done (MPI_Scatter is a little annoying) */ completed = 1; for (i = 1; i < size; ++i) MPI_Send(&completed, 1, MPI_INT, (rank + i) % size, 0, MPI_COMM_WORLD); /* Loop while everyone isn't done */ while(!allDone(doneRequests, size)) { remaining = 0; /* Find all of the workers that have not completed */ for (i = 0; i < size - 1; ++i) { MPI_Test(doneRequests + i, &donorFinished, MPI_STATUS_IGNORE); if (!donorFinished) notDone[remaining++] = i; } if (remaining > 0) { i = notDone[genrand(&state) % remaining]; target = (rank + i + 1) % size; /* Pick one of the guys at random and send him a request */ MPI_Send(&target, 1, MPI_INT, target, 1, MPI_COMM_WORLD); MPI_Irecv(&work, 1, MPI_INT, target, 2, MPI_COMM_WORLD, &workRequest); gotWork = donorFinished = 0; /* Check if he wrote back or if he finished in the meantime */ while (!gotWork && !donorFinished) { MPI_Test(&workRequest, &gotWork, MPI_STATUS_IGNORE); MPI_Test(doneRequests + i, &donorFinished, MPI_STATUS_IGNORE); if (gotWork) { for (j = 0; j < boardSize * boardSize; ++j) { pt.x = j / boardSize; pt.y = j % boardSize; total += exploreOne(dictionary, boards + work, pt, timing); } } } } } qdest(queue); return total; }