static int sndcnv_convert(pcmobj_t *pcm, int lv, int outlen) { void *ibuf, *buf0, *bufl, *bufr, *bufrw, *buflw; int len, i; void *pr, *pl; LONG isample = 0, osample = 0; LONG osampler = LONG_MAX, osamplel = LONG_MAX; ibuf = g_malloc(outlen*2); // printf("pcm->src = %p, sample = %d, outlen = %d\n", pcm->src, pcm->conv.isample, outlen); len = pcm->src->read(pcm->src, ibuf, 1, pcm->conv.isample); if (len == 0) { g_free(ibuf); return 0; } buf0 = g_malloc(outlen*2); bufr = g_malloc(outlen*2); bufl = g_malloc(outlen*2); bufrw = g_malloc(outlen*2); buflw = g_malloc(outlen*2); // 8|16 bit -> LONG 変換 switch(pcm->fmt.bit) { case 8: // 8bit { unsigned char *src = ibuf; LONG *dst = buf0; isample = len; for (i = 0; i < isample; i++) { *dst = LEFT(*src-128, 23); src++; dst++; } break; } case 16: // 16 bit { unsigned short *src = ibuf; LONG *dst = buf0; isample = len / 2; for (i = 0; i < isample; i++) { *dst = LEFT(*src, 16); src++; dst++; } break; } } // change volume if (lv != 100) { double v = lv / 100.0, y; LONG *p = buf0; // puts("change vol"); for (i = 0; i < isample; i++) { y = v * *p; if (y < -2147483647.0) { y = -2147483647.0; } else if (y > 2147483647.0) { y = 2147483647.0; } *p++ = y + 0.5; } } // stereo 分解 if (pcm->fmt.ch == 2) { LONG *src = buf0, *dstl = bufl, *dstr = bufr; isample /= 2; for (i = 0; i < isample; i++) { *dstl = *src; dstl++; src++; *dstr = *src; dstr++; src++; } pl = bufl; pr = bufr; } else { pl = buf0; pr = NULL; } // rate 変換 left i = isample; osamplel = outlen; //printf("insample = %d, osample = %d\n", isample, osamplel); st_rate_flow(&pcm->conv, pl, buflw, &isample, &osamplel); //printf("insample = %d, osample = %d\n", isample, osamplel); // rate 変換 right if (pcm->fmt.ch == 2) { isample = i; osampler = outlen; //printf("insample = %d, osample = %d\n", isample, osampler); st_rate_flow(&pcm->conv, pr, bufrw, &isample, &osampler); //printf("insample = %d, osample = %d\n", isample, osampler); } osample = MIN(osampler, osamplel); // LONG -> 16bit 変換 if (pcm->fmt.ch == 2) { LONG *srcl, *srcr; unsigned short *dstl, *dstr; srcl = buflw; srcr = bufrw; dstl = bufl; dstr = bufr; for (i = 0; i < osample; i++) { *dstl = RIGHT(*srcl, 16); dstl++; srcl++; *dstr = RIGHT(*srcr, 16); dstr++; srcr++; } } else { LONG *src = buflw; unsigned short *dst = bufl; for (i = 0; i < osample; i++) { *dst = RIGHT(*src, 16); dst++; src++; } } // stereo 化 if (pcm->fmt.ch == 2) { unsigned short *srcl, *srcr, *dst; srcl = bufl; srcr = bufr; dst = pcm->conv.buf; for (i = 0; i < osample; i++) { *dst = *srcl; dst++; srcl++; *dst = *srcr; dst++; srcr++; } } else { unsigned short *src, *dst; src = bufl; dst = pcm->conv.buf; for (i = 0; i < osample; i++) { *dst = *src; dst++; *dst = *src; dst++; src++; } } g_free(buflw); g_free(bufrw); g_free(bufl); g_free(bufr); g_free(buf0); g_free(ibuf); //printf("outlen = %d\n", osample * 4); return osample * 4; // 変換後の長さ(byte数) }
int main (int argc, char *argv[]) { SUCCESS_OR_DIE (gaspi_proc_init (GASPI_BLOCK)); gaspi_rank_t iProc, nProc; SUCCESS_OR_DIE (gaspi_proc_rank (&iProc)); SUCCESS_OR_DIE (gaspi_proc_num (&nProc)); // number of threads const int NTHREADS = 2; // number of buffers const int NWAY = 2; // allocate segment for array for local vector, left halo and right halo gaspi_segment_id_t const segment_id = 0; SUCCESS_OR_DIE ( gaspi_segment_create ( segment_id, NWAY * (NTHREADS + 2) * 2 * VLEN * sizeof (double) , GASPI_GROUP_ALL, GASPI_BLOCK, GASPI_MEM_UNINITIALIZED)); gaspi_pointer_t array; SUCCESS_OR_DIE ( gaspi_segment_ptr ( segment_id, &array) ); // initial buffer id int buffer_id = 0; // set notification values gaspi_notification_id_t left_data_available[NWAY]; gaspi_notification_id_t right_data_available[NWAY]; for (gaspi_notification_id_t id = 0; id < NWAY; ++id) { left_data_available[id] = id; right_data_available[id] = NWAY + id; } // set queue id gaspi_queue_id_t queue_id = 0; // initialize slice data structures slice *ssl = (slice *) malloc (NTHREADS * sizeof (slice)); ASSERT (ssl); init_slices (ssl, NTHREADS); // initialize data data_init (NTHREADS,iProc, buffer_id, array); const int right_halo = NTHREADS+1; const int left_halo = 0; // issue initial write to left ngb wait_for_queue_max_half (&queue_id); SUCCESS_OR_DIE ( gaspi_write_notify ( segment_id, array_OFFSET_left (buffer_id, left_halo + 1, 0), LEFT(iProc, nProc) , segment_id, array_OFFSET_left (buffer_id, right_halo, 0), VLEN * sizeof (double) , right_data_available[buffer_id], 1, queue_id, GASPI_BLOCK)); // issue initial write to right ngb wait_for_queue_max_half (&queue_id); SUCCESS_OR_DIE ( gaspi_write_notify ( segment_id, array_OFFSET_right (buffer_id, right_halo - 1, 0), RIGHT(iProc, nProc) , segment_id, array_OFFSET_right (buffer_id, left_halo, 0), VLEN * sizeof (double) , left_data_available[buffer_id], 1, queue_id, GASPI_BLOCK)); // set total number of iterations per slice const int num = nProc * NTHREADS * NITER; omp_set_num_threads (NTHREADS); double time = -now(); #pragma omp parallel default (none) firstprivate (buffer_id, queue_id) \ shared (array, left_data_available, right_data_available, ssl, stderr) { slice* sl; while ((sl = get_slice_and_lock (ssl, NTHREADS, num))) { handle_slice ( sl, array, left_data_available, right_data_available , segment_id, queue_id, NWAY, NTHREADS, num); /* TODO ==== - Which functionality do we need in 'handle_slice' ? (asynchronous dataflow for 1-D halo-exchange) - Discuss. - Bonus question: Can we be at different iteration stages for left and right halo ? if yes: Why ? */ omp_unset_lock (&sl->lock); } #pragma omp barrier } time += now(); data_verify (NTHREADS, iProc, (NITER * nProc * NTHREADS) % NWAY, array); printf ("# gaspi %s nProc %d vlen %i niter %d nthreads %i nway %i time %g\n" , argv[0], nProc, VLEN, NITER, NTHREADS, NWAY, time ); gaspi_proc_term (GASPI_BLOCK); return EXIT_SUCCESS; }
// returns true if added node. returns false if did not add node bool TopTree::addNode ( TopNode *t , int32_t tnn ) { // respect the dom hashes //uint8_t domHash = g_titledb.getDomHash8((uint8_t*)t->m_docIdPtr); uint8_t domHash = g_titledb.getDomHash8FromDocId(t->m_docId); // if vcount is satisfied, only add if better score than tail if ( m_vcount >= m_docsWanted ) { int32_t i = m_lowNode; if ( m_useIntScores ) { if ( t->m_intScore < m_nodes[i].m_intScore ) { m_kickedOutDocIds = true; return false; } if ( t->m_intScore > m_nodes[i].m_intScore) goto addIt; } else { if ( t->m_score < m_nodes[i].m_score ) { m_kickedOutDocIds = true; return false; } if ( t->m_score > m_nodes[i].m_score ) goto addIt; } // . finally, compare docids, store lower ones first // . docids should not tie... if ( t->m_docId >= m_nodes[i].m_docId ) { m_kickedOutDocIds = true; return false; } // we got a winner goto addIt; /* if ( *(uint32_t *)(t->m_docIdPtr+1) > *(uint32_t *)(m_nodes[i].m_docIdPtr+1) ) { m_kickedOutDocIds = true; return false; } if ( *(uint32_t *)(t->m_docIdPtr+1) < *(uint32_t *)(m_nodes[i].m_docIdPtr+1) ) goto addIt; if ( (*(unsigned char *)(t->m_docIdPtr)&0xfc) > (*(unsigned char *)(m_nodes[i].m_docIdPtr)&0xfc)) { m_kickedOutDocIds = true; return false; } if ( (*(unsigned char *)(t->m_docIdPtr)&0xfc) < (*(unsigned char *)(m_nodes[i].m_docIdPtr)&0xfc) ) goto addIt; // a tie, skip it m_kickedOutDocIds = true; return false; */ } addIt: int32_t iparent = -1; // this is -1 iff there are no nodes used in the tree int32_t i = m_headNode; // JAB: gcc-3.4 char dir = 0; // if we're the first node we become the head node and our parent is -1 if ( m_numUsedNodes == 0 ) { m_headNode = 0; iparent = -1; } // . find the parent of node i and call it "iparent" // . if a node exists with our key then do NOT replace it else while ( i >= 0 ) { iparent = i; // . compare to the ith node if ( m_useIntScores ) { if ( t->m_intScore < m_nodes[i].m_intScore ) { i = LEFT(i); dir = 0; continue; } if ( t->m_intScore > m_nodes[i].m_intScore ) { i = RIGHT(i); dir = 1; continue; } } else { if ( t->m_score < m_nodes[i].m_score ) { i = LEFT(i); dir = 0; continue; } if ( t->m_score > m_nodes[i].m_score ) { i = RIGHT(i); dir = 1; continue; } } // . finally, compare docids, store lower ones first // . docids should not tie... if ( t->m_docId > m_nodes[i].m_docId ) { i = LEFT (i); dir = 0; continue; } if ( t->m_docId < m_nodes[i].m_docId ) { i = RIGHT(i); dir = 1; continue; } // if equal do not replace return false; /* if ( *(uint32_t *)(t->m_docIdPtr+1) > *(uint32_t *)(m_nodes[i].m_docIdPtr+1) ) { i = LEFT(i); dir = 0; continue; } if ( *(uint32_t *)(t->m_docIdPtr+1) < *(uint32_t *)(m_nodes[i].m_docIdPtr+1) ) { i = RIGHT(i); dir = 1; continue; } if ( (*(unsigned char *)(t->m_docIdPtr)&0xfc) > (*(unsigned char *)(m_nodes[i].m_docIdPtr)&0xfc) ) { i = LEFT(i); dir = 0; continue; } if ( (*(unsigned char *)(t->m_docIdPtr)&0xfc) < (*(unsigned char *)(m_nodes[i].m_docIdPtr)&0xfc) ) { i = RIGHT(i); dir = 1; continue; } // IF EQUAL DO NOT REPLACE IT return false; */ } // // this block of code here makes a new key and adds it to m_t2, // and RdbTree. This allows us to keep track of the top // "m_ridiculousMax" domains, and keep them in order of highest // to lowest scoring. Without limiting nodes from the same domHash // a single domain can easily flood/dominate the TopTree. We are seek // a variety of domains to make site clustering as "guaranteed" as // possible. If not doing site clustering we could skip this block. // // debug hack //m_ridiculousMax = 2; // . make our key the dom tree, m_t2 // . mask out 0x80 and 0x40 in bscore // . WARNING: if t->m_score is fractional, the fraction will be // dropped and could result in the lower scoring of the two docids // being kept. uint32_t cs ; if ( m_useIntScores ) cs = (uint32_t) t->m_intScore; else cs = ((uint32_t)t->m_score); key_t k; k.n1 = domHash << 24; // 1 byte domHash //k.n1 |= (t->m_bscore & ~0xc0) << 16; // 1 byte bscore k.n1 |= cs >> 16; // 4 byte score k.n0 = ((int64_t)cs) << (64-16); k.n0 |= t->m_docId; // getDocIdFromPtr ( t->m_docIdPtr ); // do not add dups //int32_t dd = m_t2.getNode ( 0 , k ); //if ( dd >= 0 ) return false; // get min node now for this dom int32_t min = m_domMinNode[domHash]; // the node we add ourselves to int32_t n; // delete this node SPTRTYPE deleteMe = -1; // do not even try to add if ridiculous count for this domain if ( m_domCount[domHash] >= m_ridiculousMax ) { // sanity check //if ( min < 0 ) { char *xx=NULL; *xx=0; } // if we are lesser or dup of min, just don't add! if ( k <= *((key_t *)m_t2.getKey(min)) ) return false; // . add ourselves. use 0 for collnum. // . dataPtr is not really a ptr, but the node n = m_t2.addNode ( 0 , k , NULL , 4 ); //if ( n == 52 ) // log("r2 node 52 has domHash=%"INT32"",domHash); // the next node before the current min will be the next min int32_t next = m_t2.getNextNode(min); // sanity check //if ( next < 0 ) { char *xx=NULL;*xx=0; } // sanity check //key_t *kp1 = (key_t *)m_t2.getKey(min); //if ( (kp1->n1) >>24 != domHash ) {char*xx=NULL;*xx=0;} //key_t *kp2 = (key_t *)m_t2.getKey(next); //if ( (kp2->n1) >>24 != domHash ) {char*xx=NULL;*xx=0;} // the new min is the "next" of the old min m_domMinNode[domHash] = next; // get his "node number" in the top tree, "nn" so we can // delete him from the top tree as well as m_t2. it is // "hidden" in the dataPtr deleteMe = (SPTRTYPE)m_t2.m_data[min]; // delete him from the top tree now as well //deleteNode ( nn , domHash ); // then delete him from the m_t2 tree m_t2.deleteNode3 ( min , false ); //logf(LOG_DEBUG,"deleting1 %"INT32"",min); } // if we have not violated the ridiculous max, just add ourselves else if ( m_doSiteClustering ) { n = m_t2.addNode ( 0 , k , NULL , 4 ); //if ( n == 52 ) // log("r2 nodeb 52 has domHash=%"INT32"",domHash); // sanity check //if ( min > 0 ) { // key_t *kp1 = (key_t *)m_t2.getKey(min); // if ( (kp1->n1) >>24 != domHash ) {char*xx=NULL;*xx=0;} //} // are we the new min? if so, assign it if ( min == -1 || k < *((key_t *)m_t2.getKey(min)) ) m_domMinNode[domHash] = n; } if ( m_doSiteClustering ) { // update the dataPtr so every node in m_t2 has a reference // to the equivalent node in this top tree if ( n < 0 || n > m_t2.m_numNodes ) { char *xx=NULL;*xx=0; } m_t2.m_data[n] = (char *)(PTRTYPE)tnn; } // // end special m_t2 code block // // increment count of domain hash of the docId added m_domCount[domHash]++; // do not count if over limit if ( m_domCount[domHash] < m_cap ) m_vcount += 1.0; // if equal, count partial else if ( m_domCount[domHash] == m_cap ) m_vcount += m_partial; // . we were the empty node, get the next in line in the linked list // . should be -1 if none left m_emptyNode = t->m_right; // stick ourselves in the next available node, "m_nextNode" t->m_parent = iparent; // make our parent, if any, point to us if ( iparent >= 0 ) { if ( dir == 0 ) LEFT(iparent) = tnn; // 0 else RIGHT(iparent) = tnn; // 1 } // our kids are -1 means none t->m_left = -1; t->m_right = -1; // our depth is now 1 since we're a leaf node (we include ourself) t->m_depth = 1; // . reset depths starting at i's parent and ascending the tree // . will balance if child depths differ by 2 or more setDepths ( iparent ); // are we the new low node? lower-scoring stuff is on the LEFT! if ( iparent == m_lowNode && dir == 0 ) m_lowNode = tnn; // count it m_numUsedNodes++; // we should delete this, it was delayed for the add... if ( deleteMe >= 0 ) deleteNode ( deleteMe , domHash ); // remove as many docids as we should while ( m_vcount-1.0 >= m_docsWanted || m_numUsedNodes == m_numNodes) { // he becomes the new empty node int32_t tn = m_lowNode; // sanity check if ( tn < 0 ) { char *xx=NULL; *xx=0; } // sanity check //if ( getNext(tn) == -1 ) { char *xx=NULL;*xx=0; } // get the min node TopNode *t = &m_nodes[tn]; // get its docid ptr //uint8_t domHash2 = g_titledb.getDomHash8((ui)t->m_docIdPtr); uint8_t domHash2 = g_titledb.getDomHash8FromDocId(t->m_docId); // . also must delete from m_t2 // . make the key key_t k; // WARNING: if t->m_score is fractional, the fraction will be // dropped and could result in the lower scoring of the two // docids being kept. uint32_t cs ; if ( m_useIntScores ) cs = (uint32_t) t->m_intScore; else cs = ((uint32_t)t->m_score); k.n1 = domHash2 << 24; // 1 byte domHash //k.n1 |= (t->m_bscore & ~0xc0) << 16; // 1 byte bscore k.n1 |= cs >> 16; // 4 byte score k.n0 = ((int64_t)cs) << (64-16); k.n0 |= t->m_docId; // getDocIdFromPtr ( t->m_docIdPtr ); // delete the low node, this might do a rotation deleteNode ( tn , domHash2 ); // the rest is for site clustering only if ( ! m_doSiteClustering ) continue; // get the node from t2 int32_t min = m_t2.getNode ( 0 , (char *)&k ); // sanity check. LEAVE THIS HERE! if ( min < 0 ) { break; char *xx=NULL; *xx=0; } // sanity check //key_t *kp1 = (key_t *)m_t2.getKey(min); //if ( (kp1->n1) >>24 != domHash2 ) {char*xx=NULL;*xx=0;} // get next node from t2 int32_t next = m_t2.getNextNode ( min ); // delete from m_t2 m_t2.deleteNode3 ( min , false ); // skip if not th emin if ( m_domMinNode[domHash2] != min ) continue; // if we were the last, that's it if ( m_domCount[domHash2] == 0 ) { // no more entries for this domHash2 m_domMinNode[domHash2] = -1; // sanity check //if ( next > 0 ) { //key_t *kp2 = (key_t *)m_t2.getKey(next); //if ( (kp2->n1) >>24 == domHash2 ) {char*xx=NULL;*xx=0;} //} continue; } // sanity check //if ( next < 0 ) { char *xx=NULL;*xx=0; } // sanity check //key_t *kp2 = (key_t *)m_t2.getKey(next); //if ( (kp2->n1) >>24 != domHash2 ) {char*xx=NULL;*xx=0;} // the new min is the "next" of the old min m_domMinNode[domHash2] = next; //logf(LOG_DEBUG,"deleting %"INT32"",on); } return true; }
// this is the same as above but LEFT and RIGHT are swapped int32_t TopTree::rotateLeft ( int32_t i ) { // i's left kid's LEFT kid takes his place int32_t A = i; int32_t N = RIGHT ( A ); int32_t W = RIGHT ( N ); int32_t X = LEFT ( N ); int32_t Q = -1; int32_t T = -1; if ( X >= 0 ) { Q = RIGHT ( X ); T = LEFT ( X ); } // let AP be A's parent int32_t AP = PARENT ( A ); // whose the bigger subtree, W or X? (depth includes W or X itself) int32_t Wdepth = 0; int32_t Xdepth = 0; if ( W >= 0 ) Wdepth = DEPTH(W); if ( X >= 0 ) Xdepth = DEPTH(X); // debug msg //fprintf(stderr,"A=%"INT32" AP=%"INT32" N=%"INT32" W=%"INT32" X=%"INT32" Q=%"INT32" T=%"INT32" " //"Wdepth=%"INT32" Xdepth=%"INT32"\n",A,AP,N,W,X,Q,T,Wdepth,Xdepth); // goto Xdeeper if X is deeper if ( Wdepth < Xdepth ) goto Xdeeper; // N's parent becomes A's parent PARENT ( N ) = AP; // A's parent becomes N PARENT ( A ) = N; // X's parent becomes A if ( X >= 0 ) PARENT ( X ) = A; // A's parents kid becomes N if ( AP >= 0 ) { if ( RIGHT ( AP ) == A ) RIGHT ( AP ) = N; else LEFT ( AP ) = N; } // if A had no parent, it was the headNode else { //fprintf(stderr,"changing head node from %"INT32" to %"INT32"\n", //m_headNode,N); m_headNode = N; } // N's LEFT kid becomes A LEFT ( N ) = A; // A's RIGHT kid becomes X RIGHT ( A ) = X; // . compute A's depth from it's X and B kids // . it should be one less if Xdepth smaller than Wdepth // . might set DEPTH(A) to computeDepth(A) if we have problems if ( Xdepth < Wdepth ) DEPTH ( A ) -= 2; else DEPTH ( A ) -= 1; // N gains a depth iff W and X were of equal depth if ( Wdepth == Xdepth ) DEPTH ( N ) += 1; // now we're done, return the new pivot that replaced A return N; // come here if X is deeper Xdeeper: // X's parent becomes A's parent PARENT ( X ) = AP; // A's parent becomes X PARENT ( A ) = X; // N's parent becomes X PARENT ( N ) = X; // Q's parent becomes N if ( Q >= 0 ) PARENT ( Q ) = N; // T's parent becomes A if ( T >= 0 ) PARENT ( T ) = A; // A's parent's kid becomes X if ( AP >= 0 ) { if ( RIGHT ( AP ) == A ) RIGHT ( AP ) = X; else LEFT ( AP ) = X; } // if A had no parent, it was the headNode else { //fprintf(stderr,"changing head node2 from %"INT32" to %"INT32"\n", //m_headNode,X); m_headNode = X; } // A's RIGHT kid becomes T RIGHT ( A ) = T; // N's LEFT kid becomes Q LEFT ( N ) = Q; // X's RIGHT kid becomes N RIGHT ( X ) = N; // X's LEFT kid becomes A LEFT ( X ) = A; // X's depth increases by 1 since it gained 1 level of 2 new kids DEPTH ( X ) += 1; // N's depth decreases by 1 DEPTH ( N ) -= 1; // A's depth decreases by 2 DEPTH ( A ) -= 2; // now we're done, return the new pivot that replaced A return X; }
int main (int argc, char *argv[]) { SUCCESS_OR_DIE (gaspi_proc_init (GASPI_BLOCK)); gaspi_rank_t iProc, nProc; SUCCESS_OR_DIE (gaspi_proc_rank (&iProc)); SUCCESS_OR_DIE (gaspi_proc_num (&nProc)); // number of threads const int NTHREADS = 2; // number of buffers const int NWAY = 2; gaspi_segment_id_t const segment_id = 0; // allocate segment for array for local vector, left halo and right halo SUCCESS_OR_DIE ( gaspi_segment_create ( segment_id, NWAY * (NTHREADS + 2) * 2 * VLEN * sizeof (double) , GASPI_GROUP_ALL, GASPI_BLOCK, GASPI_MEM_UNINITIALIZED)); gaspi_pointer_t array; SUCCESS_OR_DIE ( gaspi_segment_ptr ( segment_id, &array) ); // initial buffer id int buffer_id = 0; // set notification values gaspi_notification_id_t left_data_available[NWAY]; gaspi_notification_id_t right_data_available[NWAY]; for (gaspi_notification_id_t id = 0; id < NWAY; ++id) { left_data_available[id] = id; right_data_available[id] = NWAY + id; } // set queue id gaspi_queue_id_t queue_id = 0; // initialize data data_init (NTHREADS, iProc, buffer_id, array); omp_set_num_threads (NTHREADS); double time = -now(); #pragma omp parallel default (shared) firstprivate (buffer_id) { const int tid = omp_get_thread_num(); for (int k = 0; k < NITER; ++k) { for ( int i = 0; i < nProc * NTHREADS; ++i ) { const int left_halo = 0; const int slice_id = tid + 1; const int right_halo = NTHREADS+1; if (tid == 0) { // issue write wait_for_queue_max_half (&queue_id); SUCCESS_OR_DIE ( gaspi_write_notify ( segment_id, array_OFFSET_left (buffer_id, left_halo + 1, 0), LEFT(iProc, nProc) , segment_id, array_OFFSET_left (buffer_id, right_halo, 0), VLEN * sizeof (double) , right_data_available[buffer_id], 1 + i, queue_id, GASPI_BLOCK)); // issue write wait_for_queue_max_half (&queue_id); SUCCESS_OR_DIE ( gaspi_write_notify ( segment_id, array_OFFSET_right (buffer_id, right_halo - 1, 0), RIGHT(iProc, nProc) , segment_id, array_OFFSET_right (buffer_id, left_halo, 0), VLEN * sizeof (double) , left_data_available[buffer_id], 1 + i, queue_id, GASPI_BLOCK)); // wait for data notification wait_or_die (segment_id, right_data_available[buffer_id], 1 + i); // wait for data notification wait_or_die (segment_id, left_data_available[buffer_id], 1 + i); } #pragma omp barrier // compute data, read from id "buffer_id", write to id "1 - buffer_id" data_compute ( NTHREADS, array, 1 - buffer_id, buffer_id, slice_id); #pragma omp barrier // alternate the buffer buffer_id = 1 - buffer_id; } } } time += now(); data_verify (NTHREADS, iProc, (NITER * nProc * NTHREADS) % NWAY, array); printf ("# gaspi %s nProc %d vlen %i niter %d nthreads %i nway %i time %g\n" , argv[0], nProc, VLEN, NITER, NTHREADS, NWAY, time ); gaspi_proc_term (GASPI_BLOCK); return EXIT_SUCCESS; }
// // CastThroughIntersections // float Raycaster::CastThroughIntersections(float angle, IntersectionDir dir, int *texIndex, float *texelX) { float fx, fy; float dx, dy; float distance; float a, b; int mapX, mapY; switch(dir) { case ID_HORIZONTAL: if(UP(angle)) { fy = -(posY - (int)posY); dy = -1; } else { fy = (int)posY + 1 - posY; dy = 1; } fx = (float)(ABS(fy)) / (float)(TAN(angle)); dx = (float)(ABS(dy)) / (float)(TAN(angle)); fx = ABS(fx); dx = ABS(dx); if(LEFT(angle)) { dx = -dx; fx = -fx; } fx = posX + fx; fy = posY + fy; break; case ID_VERTICAL: if(LEFT(angle)) { fx = -(posX - (int)posX); dx = -1; } else { fx = (int)posX + 1 - posX; dx = 1; } fy = (float)(TAN(angle)) * (float)(ABS(fx)); dy = (float)(TAN(angle)) * (float)(ABS(dx)); fy = ABS(fy); dy = ABS(dy); if(UP(angle)) { fy = -fy; dy = -dy; } fx = posX + fx; fy = posY + fy; break; } while(true) { mapY = (int)fy; mapX = (int)fx; if(dy == -1 && dir == ID_HORIZONTAL) mapY -= 1; else if(dx == -1 && dir == ID_VERTICAL) mapX -= 1; if(mapX < 0 || mapY < 0 || mapX >= mapW || mapY >= mapH) break; else if(map[mapY][mapX] > 0 && map[mapY][mapX] != DOOR_INDEX && map[mapY][mapX] != LOCKED_DOOR_INDEX) { hit: if(dir == ID_HORIZONTAL) *texelX = fx - (float)mapX; else *texelX = fy - (float)mapY; *texIndex = map[mapY][mapX] - 1; break; } else if(map[mapY][mapX] == DOOR_INDEX || map[mapY][mapX] == LOCKED_DOOR_INDEX) { Door *door = GetDoorAt(mapX, mapY); if(door->GetOpening() || door->GetClosing()) { float xval; if(dir == ID_HORIZONTAL) xval = fx - (float)mapX; else xval = fy - (float)mapY; if(door->GetOpenedWidth() < xval) goto hit; } else if(!door->IsOpen()) goto hit; } fx += dx; fy += dy; } a = ABS((fy - posY)); b = ABS((fx - posX)); distance = sqrt(a*a+b*b); return distance; }
/* Delete node with given key. KEY is the key to be deleted, ROOTP is the address of the root of tree, COMPAR the comparison function. */ void * __tdelete (const void *key, void **vrootp, __compar_fn_t compar) { node p, q, r, retval; int cmp; node *rootp = (node *) vrootp; node root, unchained; /* Stack of nodes so we remember the parents without recursion. It's _very_ unlikely that there are paths longer than 40 nodes. The tree would need to have around 250.000 nodes. */ int stacksize = 40; int sp = 0; node **nodestack = alloca (sizeof (node *) * stacksize); if (rootp == NULL) return NULL; p = DEREFNODEPTR(rootp); if (p == NULL) return NULL; CHECK_TREE (p); root = DEREFNODEPTR(rootp); while ((cmp = (*compar) (key, root->key)) != 0) { if (sp == stacksize) { node **newstack; stacksize += 20; newstack = alloca (sizeof (node *) * stacksize); nodestack = memcpy (newstack, nodestack, sp * sizeof (node *)); } nodestack[sp++] = rootp; p = DEREFNODEPTR(rootp); if (cmp < 0) { rootp = LEFTPTR(p); root = LEFT(p); } else { rootp = RIGHTPTR(p); root = RIGHT(p); } if (root == NULL) return NULL; } /* This is bogus if the node to be deleted is the root... this routine really should return an integer with 0 for success, -1 for failure and errno = ESRCH or something. */ retval = p; /* We don't unchain the node we want to delete. Instead, we overwrite it with its successor and unchain the successor. If there is no successor, we really unchain the node to be deleted. */ root = DEREFNODEPTR(rootp); r = RIGHT(root); q = LEFT(root); if (q == NULL || r == NULL) unchained = root; else { node *parentp = rootp, *up = RIGHTPTR(root); node upn; for (;;) { if (sp == stacksize) { node **newstack; stacksize += 20; newstack = alloca (sizeof (node *) * stacksize); nodestack = memcpy (newstack, nodestack, sp * sizeof (node *)); } nodestack[sp++] = parentp; parentp = up; upn = DEREFNODEPTR(up); if (LEFT(upn) == NULL) break; up = LEFTPTR(upn); } unchained = DEREFNODEPTR(up); } /* We know that either the left or right successor of UNCHAINED is NULL. R becomes the other one, it is chained into the parent of UNCHAINED. */ r = LEFT(unchained); if (r == NULL) r = RIGHT(unchained); if (sp == 0) SETNODEPTR(rootp,r); else { q = DEREFNODEPTR(nodestack[sp-1]); if (unchained == RIGHT(q)) SETRIGHT(q,r); else SETLEFT(q,r); } if (unchained != root) root->key = unchained->key; if (!RED(unchained)) { /* Now we lost a black edge, which means that the number of black edges on every path is no longer constant. We must balance the tree. */ /* NODESTACK now contains all parents of R. R is likely to be NULL in the first iteration. */ /* NULL nodes are considered black throughout - this is necessary for correctness. */ while (sp > 0 && (r == NULL || !RED(r))) { node *pp = nodestack[sp - 1]; p = DEREFNODEPTR(pp); /* Two symmetric cases. */ if (r == LEFT(p)) { /* Q is R's brother, P is R's parent. The subtree with root R has one black edge less than the subtree with root Q. */ q = RIGHT(p); if (RED(q)) { /* If Q is red, we know that P is black. We rotate P left so that Q becomes the top node in the tree, with P below it. P is colored red, Q is colored black. This action does not change the black edge count for any leaf in the tree, but we will be able to recognize one of the following situations, which all require that Q is black. */ SETBLACK(q); SETRED(p); /* Left rotate p. */ SETRIGHT(p,LEFT(q)); SETLEFT(q,p); SETNODEPTR(pp,q); /* Make sure pp is right if the case below tries to use it. */ nodestack[sp++] = pp = LEFTPTR(q); q = RIGHT(p); } /* We know that Q can't be NULL here. We also know that Q is black. */ if ((LEFT(q) == NULL || !RED(LEFT(q))) && (RIGHT(q) == NULL || !RED(RIGHT(q)))) { /* Q has two black successors. We can simply color Q red. The whole subtree with root P is now missing one black edge. Note that this action can temporarily make the tree invalid (if P is red). But we will exit the loop in that case and set P black, which both makes the tree valid and also makes the black edge count come out right. If P is black, we are at least one step closer to the root and we'll try again the next iteration. */ SETRED(q); r = p; } else { /* Q is black, one of Q's successors is red. We can repair the tree with one operation and will exit the loop afterwards. */ if (RIGHT(q) == NULL || !RED(RIGHT(q))) { /* The left one is red. We perform the same action as in maybe_split_for_insert where two red edges are adjacent but point in different directions: Q's left successor (let's call it Q2) becomes the top of the subtree we are looking at, its parent (Q) and grandparent (P) become its successors. The former successors of Q2 are placed below P and Q. P becomes black, and Q2 gets the color that P had. This changes the black edge count only for node R and its successors. */ node q2 = LEFT(q); if (RED(p)) SETRED(q2); else SETBLACK(q2); SETRIGHT(p,LEFT(q2)); SETLEFT(q,RIGHT(q2)); SETRIGHT(q2,q); SETLEFT(q2,p); SETNODEPTR(pp,q2); SETBLACK(p); } else { /* It's the right one. Rotate P left. P becomes black, and Q gets the color that P had. Q's right successor also becomes black. This changes the black edge count only for node R and its successors. */ if (RED(p)) SETRED(q); else SETBLACK(q); SETBLACK(p); SETBLACK(RIGHT(q)); /* left rotate p */ SETRIGHT(p,LEFT(q)); SETLEFT(q,p); SETNODEPTR(pp,q); } /* We're done. */ sp = 1; r = NULL; } } else { /* Comments: see above. */ q = LEFT(p); if (RED(q)) { SETBLACK(q); SETRED(p); SETLEFT(p,RIGHT(q)); SETRIGHT(q,p); SETNODEPTR(pp,q); nodestack[sp++] = pp = RIGHTPTR(q); q = LEFT(p); } if ((RIGHT(q) == NULL || !RED(RIGHT(q))) && (LEFT(q) == NULL || !RED(LEFT(q)))) { SETRED(q); r = p; } else { if (LEFT(q) == NULL || !RED(LEFT(q))) { node q2 = RIGHT(q); if (RED(p)) SETRED(q2); else SETBLACK(q2); SETLEFT(p,RIGHT(q2)); SETRIGHT(q,LEFT(q2)); SETLEFT(q2,q); SETRIGHT(q2,p); SETNODEPTR(pp,q2); SETBLACK(p); } else { if (RED(p)) SETRED(q); else SETBLACK(q); SETBLACK(p); SETBLACK(LEFT(q)); SETLEFT(p,RIGHT(q)); SETRIGHT(q,p); SETNODEPTR(pp,q); } sp = 1; r = NULL; } } --sp; } if (r != NULL) SETBLACK(r); } free (unchained); return retval; }
void get_left_fork(int mine) { int item = LEFT(mine); set_busy(item); }
mlib_status __mlib_GraphicsFillArc_X_8( mlib_image *buffer, mlib_s16 xx, mlib_s16 yy, mlib_s32 r, mlib_f32 t1, mlib_f32 t2, mlib_s32 c0, mlib_s32 c2) { mlib_s32 stride = mlib_ImageGetStride(buffer); mlib_s32 width = mlib_ImageGetWidth(buffer); mlib_s32 height = mlib_ImageGetHeight(buffer); mlib_u8 *data = mlib_ImageGetData(buffer); mlib_u8 *line0 = NULL, *line = NULL; mlib_s32 cx, cy, del, mask; mlib_s32 sin1, cos1, sin2, cos2, oct1, oct2, flagd, flagc; mlib_s32 sn1, cs1, sn2, cs2, xl, xr; mlib_s32 buf0[BUFSIZE], *buf = NULL, count_arc; mlib_s32 line_fill_1_0[RADMAX], line_fill_2_0[RADMAX]; mlib_s32 *line_fill_1 = NULL, *line_fill_2 = NULL, *point_line = NULL; mlib_s32 start, start_1, start_2, end, help; mlib_d64 dc; mlib_s32 xb, xe, clip, side, count_repeat, repeat; mlib_f32 help_t2, start_sin1; mlib_s32 x = xx, y = yy, cxor = c0 ^ c2, xb_last, xe_last; if (!data) return (MLIB_NULLPOINTER); if (r < 0) return (MLIB_FAILURE); if (r == 0) { if (y < height && y >= 0 && x < width && x >= 0) *(data + (stride * y + x)) ^= cxor; return (MLIB_SUCCESS); } if (x - r >= width || x + r < 0 || y - r >= height || y + r < 0) return (MLIB_SUCCESS); if (mlib_fabs(t1 - t2) >= PIx2) return (__mlib_GraphicsFillCircle_X_8 (buffer, xx, yy, r, c0, c2)); xb_last = width; xe_last = -1; count_repeat = 1; repeat = 0; { mlib_f32 tt = t1; t1 = -t2; t2 = -tt; } if (t1 > t2) t2 += PIx2; { mlib_s32 n2p = t1 / PIx2; mlib_f32 sh = PIx2 * (mlib_f32)n2p; if (t1 < 0.0f) sh -= PIx2; t1 -= sh; t2 -= sh; } line0 = data + stride * y + x; MLIB_GRAPHICS_COLOR_8(cxor); MLIB_GRAPHICS_TO_DOUBLE(dc, cxor); if (r >= RADMAX) { buf = __mlib_malloc(sizeof (mlib_s32) * (r + 1)); if (!buf) return (MLIB_FAILURE); line_fill_1 = __mlib_malloc(sizeof (mlib_s32) * (r + 1)); if (!line_fill_1) { __mlib_free(buf); return (MLIB_FAILURE); } line_fill_2 = __mlib_malloc(sizeof (mlib_s32) * (r + 1)); if (!line_fill_2) { __mlib_free(buf); __mlib_free(line_fill_1); return (MLIB_FAILURE); } } else { buf = buf0; line_fill_1 = line_fill_1_0; line_fill_2 = line_fill_2_0; } FILL_BUF; if (t2 > PIx2) { help_t2 = t2 - PIx2; t2 = PIx2; count_repeat = 0; } for (; count_repeat < 2; count_repeat++) { GET_X_Y_COORDINATE; if (oct2 < oct1) { mask = __mlib_GraphicsDrawLine_X_8(buffer, xx, yy, xx + cs1, yy + sn1, c0, c2); if (mask == MLIB_SUCCESS) { FINISH_STEP; } else return (mask); } if (oct2 == 8) oct2 = 7; if ((sn1 == 0) && (sn2 == 0) && (cs1 >= 0) && (cs2 >= 0) && (oct2 - oct1 > 4)) return __mlib_GraphicsFillCircle_X_8(buffer, xx, yy, r, c0, c2); if (count_repeat == 0) start_sin1 = sn1; point_line = &line_fill_1[0]; FILL_LINE_POINT(cs1, sn1, 0); point_line = &line_fill_2[0]; FILL_LINE_POINT(cs2, sn2, -1); FILL_FLAGD; if ((y | (height - 1 - y)) >= 0) { if (sn1 | sn2) { if (sn1 >= 0) { if (sn2 > 0) { LEFT(x + line_fill_2[0], xb); RIGHT(x + line_fill_1[0], xe); } else { LEFT(x - buf[0], xb); if (line_fill_1[0] >= line_fill_2[0]) RIGHT(x + line_fill_1[0], xe) else RIGHT(x + line_fill_2[0], xe); } } else { LEFT(x + line_fill_1[0], xb); RIGHT(x + line_fill_2[0], xe); } } else if ((cs1 | cs2) > 0) { LEFT(x, xb); RIGHT(x + r, xe); if (xb_last > xb) xb_last = xb; if (xe_last < xe) xe_last = xe; FINISH_STEP; } else if ((cs2 & cs1) < 0) { LEFT(x - r, xb); RIGHT(x, xe); if (xb_last > xb) xb_last = xb; if (xe_last < xe) xe_last = xe; FINISH_STEP; } else { LEFT(x - r, xb); RIGHT(x + r, xe); } if (xb < xb_last) xb_last = xb; if (xe > xe_last) xe_last = xe; }
/* Possibly "split" a node with two red successors, and/or fix up two red edges in a row. ROOTP is a pointer to the lowest node we visited, PARENTP and GPARENTP pointers to its parent/grandparent. P_R and GP_R contain the comparison values that determined which way was taken in the tree to reach ROOTP. MODE is 1 if we need not do the split, but must check for two red edges between GPARENTP and ROOTP. */ static void maybe_split_for_insert (node *rootp, node *parentp, node *gparentp, int p_r, int gp_r, int mode) { node root = DEREFNODEPTR(rootp); node *rp, *lp; node rpn, lpn; rp = RIGHTPTR(root); rpn = RIGHT(root); lp = LEFTPTR(root); lpn = LEFT(root); /* See if we have to split this node (both successors red). */ if (mode == 1 || ((rpn) != NULL && (lpn) != NULL && RED(rpn) && RED(lpn))) { /* This node becomes red, its successors black. */ SETRED(root); if (rpn) SETBLACK(rpn); if (lpn) SETBLACK(lpn); /* If the parent of this node is also red, we have to do rotations. */ if (parentp != NULL && RED(DEREFNODEPTR(parentp))) { node gp = DEREFNODEPTR(gparentp); node p = DEREFNODEPTR(parentp); /* There are two main cases: 1. The edge types (left or right) of the two red edges differ. 2. Both red edges are of the same type. There exist two symmetries of each case, so there is a total of 4 cases. */ if ((p_r > 0) != (gp_r > 0)) { /* Put the child at the top of the tree, with its parent and grandparent as successors. */ SETRED(p); SETRED(gp); SETBLACK(root); if (p_r < 0) { /* Child is left of parent. */ SETLEFT(p,rpn); SETNODEPTR(rp,p); SETRIGHT(gp,lpn); SETNODEPTR(lp,gp); } else { /* Child is right of parent. */ SETRIGHT(p,lpn); SETNODEPTR(lp,p); SETLEFT(gp,rpn); SETNODEPTR(rp,gp); } SETNODEPTR(gparentp,root); } else { SETNODEPTR(gparentp,p); /* Parent becomes the top of the tree, grandparent and child are its successors. */ SETBLACK(p); SETRED(gp); if (p_r < 0) { /* Left edges. */ SETLEFT(gp,RIGHT(p)); SETRIGHT(p,gp); } else { /* Right edges. */ SETRIGHT(gp,LEFT(p)); SETLEFT(p,gp); } } } } }
// ${AOs::Table::SM::active::serving} QP::QState Table::serving(Table * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // ${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP_displayPhilStat(n, HUNGRY); uint8_t m = LEFT(n); // ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) { me->m_fork[m] = USED; me->m_fork[n] = USED; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, n), me); BSP_displayPhilStat(n, EATING); status_ = QM_HANDLED(); } // ${AOs::Table::SM::active::serving::HUNGRY::[else]} else { me->m_isHungry[n] = true; status_ = QM_HANDLED(); } break; } // ${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP_displayPhilStat(n, THINKING); uint8_t m = LEFT(n); // both forks of Phil[n] must be used Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); me->m_fork[m] = FREE; me->m_fork[n] = FREE; m = RIGHT(n); // check the right neighbor if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { me->m_fork[n] = USED; me->m_fork[m] = USED; me->m_isHungry[m] = false; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, m), me); BSP_displayPhilStat(m, EATING); } m = LEFT(n); // check the left neighbor n = LEFT(m); // left fork of the left neighbor if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { me->m_fork[m] = USED; me->m_fork[n] = USED; me->m_isHungry[m] = false; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, m), me); BSP_displayPhilStat(m, EATING); } status_ = QM_HANDLED(); break; } // ${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = QM_HANDLED(); break; } // ${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { static struct { QP::QMState const *target; QP::QActionHandler act[2]; } const tatbl_ = { // transition-action table &paused_s, { Q_ACTION_CAST(&paused_e), // entry Q_ACTION_CAST(0) // zero terminator } }; status_ = QM_TRAN(&tatbl_); break; } default: { status_ = QM_SUPER(); break; } } return status_; }
void seeding(){ msleep(WAIT_FOR_CREATE); //starts driving to the black line LEFT(100); RIGHT(100); while (1) { if (analog10(LEFTSENSOR) > LEFTDARK) { break; } } ao(); //turns on the black line msleep(1500); RIGHT(50); LEFT(-50); msleep(880); LFREEZE(); RFREEZE(); msleep(1500); //starts driving to end of black line LEFT(100); RIGHT(100); while(1) { if (analog10(RIGHTSENSOR) < RIGHTLIGHT && analog10(CENTERSENSOR) < CENTERLIGHT) { break; } } LFREEZE(); RFREEZE(); RIGHT(100); LEFT(100); msleep(200); LFREEZE(); RFREEZE(); //opens servo to score position set_servo_position(1, 2047); msleep(500); // turns to botguy RIGHT(-50); LEFT(50); msleep(760); LFREEZE(); RFREEZE(); center_on_blob(90, RED, 1); //drives to botguy RIGHT(100); LEFT(100); msleep(800); LFREEZE(); RFREEZE(); /*while(1){ RIGHT(100); LEFT(100); msleep(200); center_on_blob(90, RED, 0); }*/ //close the claw around botguy set_servo_position(1, 853); msleep(500); //backs up with botguy RIGHT(-100); LEFT(-100); msleep(1200); LFREEZE(); RFREEZE(); //turns to FMT RIGHT(50); LEFT(-50); msleep(1750); LFREEZE(); RFREEZE(); //drives to FMT RIGHT(100); LEFT(100); msleep(3900); LFREEZE(); RFREEZE(); disable_servos(); ao(); }
static int sndcnv_norateconvert(pcmobj_t *pcm, int lv, int outlen) { void *ibuf, *buf0, *pd; int len, i; int isample; if (pcm->conv.ifmt.ch == pcm->conv.ofmt.ch && pcm->conv.ifmt.bit == pcm->conv.ofmt.bit && lv == 100) { // puts("norateconv"); len = pcm->src->read(pcm->src, pcm->conv.buf, 1, pcm->conv.isample); return len; } ibuf = g_malloc(outlen*2); len = pcm->src->read(pcm->src, ibuf, 1, pcm->conv.isample); if (len == 0) { g_free(ibuf); return 0; } buf0 = g_malloc(outlen*2); // 8bit -> 16bit switch(pcm->fmt.bit) { case 8: // 8bit { unsigned char *src = ibuf; WORD *dst = buf0; isample = len; for (i = 0; i < isample; i++) { *dst = LEFT(*src-128, 7); src++; dst++; } pd = buf0; break; } case 16: isample = len / 2; pd = ibuf; break; default: isample = 0; printf("no supported\n"); g_free(ibuf); g_free(buf0); return 0; } // change volume if (lv != 100) { double v = lv / 100.0, y; short *p = pd; for (i = 0; i < isample; i++) { y = v * *p; if (y < -32767.0) { y = -32767.0; } else if (y > 32767.0) { y = 32767.0; } *p++ = y + 0.5; } } // stereo 化 if (pcm->fmt.ch == 1) { unsigned short *src, *dst; src = pd; dst = pcm->conv.buf; for (i = 0; i < isample; i++) { *dst = *src; dst++; *dst = *src; dst++; src++; } isample *= 4; } else { memcpy(pcm->conv.buf, pd, isample * 2); isample *= 2; } g_free(buf0); g_free(ibuf); return isample; }
int main() { DDRC = 0xFF; PORTC = 0x00; DDRD = 0x00; PORTD = 0xFF; UCSR0B = 0x00; while(1) { while(tst_bit(PIND, B_ENABLE)); _delay_ms(10); set_bit(PORTC, ENA); set_bit(PORTC, ENB); while(!tst_bit(PIND, B_ENABLE)) { if(!tst_bit(PIND, B_FORWARD)) { _delay_ms(10); FORWARD(); while(!tst_bit(PIND, B_FORWARD)); _delay_ms(10); } if(!tst_bit(PIND, B_BACKWARD)) { _delay_ms(10); BACKWARD(); while(!tst_bit(PIND, B_BACKWARD)); _delay_ms(10); } if(!tst_bit(PIND, B_STOP)) { _delay_ms(10); STOP(); while(!tst_bit(PIND, B_STOP)); _delay_ms(10); } if(!tst_bit(PIND, B_RIGHT)) { _delay_ms(10); RIGHT(); while(!tst_bit(PIND, B_RIGHT)); _delay_ms(10); } if(!tst_bit(PIND, B_LEFT)) { _delay_ms(10); LEFT(); while(!tst_bit(PIND, B_LEFT)); _delay_ms(10); } if(!tst_bit(PIND, B_MOVE_ON)) { _delay_ms(10); MOVE_ON(); while(!tst_bit(PIND, B_MOVE_ON)); _delay_ms(10); } } _delay_ms(10); clr_bit(PORTC, ENA); clr_bit(PORTC, ENB); } } /*MAIN*/
//............................................................................ QState Table::serving(Table *me, QEvt const *e) { uint8_t n, m; TableEvt *pe; switch (e->sig) { case HUNGRY_SIG: { lib1_test(); lib2_test(); n = ((TableEvt const *)e)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP_displyPhilStat(n, "hungry "); m = LEFT(n); if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) { me->m_fork[m] = me->m_fork[n] = USED; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = n; QF::PUBLISH(pe, me); BSP_displyPhilStat(n, "eating "); } else { me->m_isHungry[n] = 1; } return Q_HANDLED(); } case DONE_SIG: { lib1_test(); lib2_test(); n = ((TableEvt const *)e)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP_displyPhilStat(n, "thinking"); m = LEFT(n); // both forks of Phil[n] must be used Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); me->m_fork[m] = me->m_fork[n] = FREE; m = RIGHT(n); // check the right neighbor if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { me->m_fork[n] = me->m_fork[m] = USED; me->m_isHungry[m] = 0; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; QF::PUBLISH(pe, me); BSP_displyPhilStat(m, "eating "); } m = LEFT(n); // check the left neighbor n = LEFT(m); // left fork of the left neighbor if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { me->m_fork[m] = me->m_fork[n] = USED; me->m_isHungry[m] = 0; pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; QF::PUBLISH(pe, me); BSP_displyPhilStat(m, "eating "); } return Q_HANDLED(); } case TEST_SIG: { lib1_test(); lib2_test(); return Q_HANDLED(); } case TERMINATE_SIG: { QF::stop(); return Q_HANDLED(); } } return Q_SUPER(&QHsm::top); }
void mkheap_verify_heap(MKHeap *heap, int top) { int empty_cnt = 0; int i; MKEntry e; if (heap->count == 0) return; Assert(heap->count > 0); Assert(heap->maxentry > 0); Assert(heap->count <= heap->maxentry); Assert(heap->maxentry <= heap->alloc_size); e = heap->p[0]; mke_set_lv(&e, 0); mke_clear_refc_copied(&e); /* Checking for lvtops */ for (i = 0; i < mke_get_lv(heap->p); ++i) { int c; /* Too much trouble dealing with ref counters. Just don't */ /* * if(!mke_test_flag(heap->lvtops+i, MKE_RefCnt | MKE_Copied)) { */ mke_set_lv(&e, i); if (heap->mkctxt->fetchForPrep) tupsort_prepare(&e, heap->mkctxt, i); c = mkheap_compare(heap, &e, heap->lvtops + i); Assert(c == 0); /* * } */ } /* Verify Heap property */ for (i = top; i < heap->maxentry; ++i) { int left = LEFT(i); int right = RIGHT(i); int cl, cr; if (mke_is_empty(heap->p + i)) ++empty_cnt; if (left >= heap->maxentry) continue; cl = mkheap_compare(heap, heap->p + i, heap->p + left); Assert(cl <= 0); if (i == 0 && cl == 0) Assert(mke_get_lv(heap->p) == heap->mkctxt->total_lv - 1); if (right >= heap->maxentry) continue; cr = mkheap_compare(heap, heap->p + i, heap->p + right); Assert(cr <= 0); if (i == 0 && cr == 0) Assert(mke_get_lv(heap->p) == heap->mkctxt->total_lv - 1); } }
int main (int argc, char *argv[]) { MPI_Init (&argc, &argv); int nProc, iProc; MPI_Comm_rank (MPI_COMM_WORLD, &iProc); MPI_Comm_size (MPI_COMM_WORLD, &nProc); // number of threads const int NTHREADS = 1; // number of buffers const int NWAY = 2; // left neighbour const int left = LEFT(iProc, nProc); // right neighbour const int right = RIGHT(iProc, nProc); // allocate array of for local vector, left halo and right halo double* array = malloc (NWAY * (NTHREADS+2) * 2 * VLEN * sizeof (double)); ASSERT (array != 0); // initial buffer id int buffer_id = 0; // initialize data data_init (NTHREADS, iProc, buffer_id, array); MPI_Barrier (MPI_COMM_WORLD); double time = -now(); for (int k = 0; k < NITER; ++k) { for (int i = 0; i < nProc; ++i) { MPI_Request send_req[2]; MPI_Request recv_req[2]; int slice_id = 1; int left_halo = 0; int right_halo = 2; // post recv MPI_Irecv ( &array_ELEM_right (buffer_id, left_halo, 0), VLEN, MPI_DOUBLE , left, i, MPI_COMM_WORLD, &recv_req[0]); MPI_Irecv ( &array_ELEM_left (buffer_id, right_halo, 0), VLEN, MPI_DOUBLE , right, i, MPI_COMM_WORLD, &recv_req[1]); // issue send MPI_Isend ( &array_ELEM_right (buffer_id, right_halo - 1, 0), VLEN, MPI_DOUBLE , right, i, MPI_COMM_WORLD, &send_req[0]); MPI_Isend ( &array_ELEM_left (buffer_id, left_halo + 1, 0), VLEN, MPI_DOUBLE , left, i, MPI_COMM_WORLD, &send_req[1]); // wait for recv MPI_Waitall (2, recv_req, MPI_STATUSES_IGNORE); // compute data, read from id "buffer_id", write to id "1 - buffer_id" data_compute (NTHREADS, array, 1 - buffer_id, buffer_id, slice_id); // wait for send MPI_Waitall (2, send_req, MPI_STATUSES_IGNORE); // alternate the buffer buffer_id = 1 - buffer_id; } } time += now(); data_verify (NTHREADS, iProc, (NITER * nProc) % NWAY, array); printf ("# mpi %s nProc %d vlen %i niter %d nthreads %i nway %i time %g\n" , argv[0], nProc, VLEN, NITER, NTHREADS, NWAY, time ); MPI_Finalize(); free (array); return EXIT_SUCCESS; }
void put_left_fork(int mine) { int item = LEFT(mine); set_free(item); }
int bstree_balance_delete( bstree_t *tree_in, long idx_in ) { long x,w; x = idx_in; while( x != tree_in->root && COLOR(x) == BLACK ) { if( PARENT_LEFT(x) == x ) { w = PARENT_RIGHT(x); if( COLOR(w) == RED ) { COLOR(w) = BLACK; COLOR(PARENT(x)) = RED; bstree_left_rotate( tree_in, PARENT(x) ); w = PARENT_RIGHT(x); } if( COLOR(LEFT(w)) == BLACK && COLOR(RIGHT(w)) == BLACK ) { /* Decrement the "blackness" of both x and w, making x black and w red */ COLOR(w) = RED; x = PARENT(x); } else { if( COLOR(RIGHT(w)) == BLACK ) { COLOR(LEFT(w)) = BLACK; /* Swap color pre-rotate */ COLOR(w) = RED; /* Swap color pre-rotate */ bstree_right_rotate( tree_in, w ); /* Rotate to maintain black count */ w = PARENT_RIGHT(x); /* Set it back to where it was in the tree */ } COLOR(w) = COLOR(PARENT(x)); COLOR(PARENT(x)) = BLACK; COLOR(RIGHT(w)) = BLACK; bstree_left_rotate( tree_in, PARENT(x) ); x = tree_in->root; /* Force termination; probably a better way */ } } else { w = PARENT_LEFT(x); if( COLOR(w) == RED ) { COLOR(w) = BLACK; COLOR(PARENT(x)) = RED; bstree_right_rotate( tree_in, PARENT(x) ); w = PARENT_LEFT(x); } if( COLOR(LEFT(w)) == BLACK && COLOR(RIGHT(w)) == BLACK ) { /* Decrement the "blackness" of both x and w, making x black and w red */ COLOR(w) = RED; x = PARENT(x); } else { if( COLOR(LEFT(w)) == BLACK ) { COLOR(RIGHT(w)) = BLACK; /* Swap color pre-rotate */ COLOR(w) = RED; /* Swap color pre-rotate */ bstree_left_rotate( tree_in, w ); /* Rotate to maintain black count */ w = PARENT_LEFT(x); /* Set it back to where it was in the tree */ } COLOR(w) = COLOR(PARENT(x)); COLOR(PARENT(x)) = BLACK; COLOR(LEFT(w)) = BLACK; bstree_right_rotate( tree_in, PARENT(x) ); x = tree_in->root; /* Force termination; probably a better way */ } } } COLOR(x) = BLACK; return 0; }
//${AOs::Table::SM::active::serving} ......................................... QP::QState Table::serving(Table * const me, QP::QEvt const * const e) { QP::QState status_; switch (e->sig) { // ${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if (me->m_isHungry[n] && (me->m_fork[LEFT(n)] == FREE) && (me->m_fork[n] == FREE)) { me->m_fork[LEFT(n)] = USED; me->m_fork[n] = USED; TableEvt *te = Q_NEW(TableEvt, EAT_SIG); te->philoNum = n; AO_Philo[n]->POST(te, me); me->m_isHungry[n] = false; BSP::displayPhilStat(n, EATING); } } status_ = Q_HANDLED(); break; } // ${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP::displayPhilStat(n, HUNGRY); uint8_t m = LEFT(n); // ${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((me->m_fork[m] == FREE) && (me->m_fork[n] == FREE)) { me->m_fork[m] = USED; me->m_fork[n] = USED; TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = n; QP::QF::PUBLISH(pe, me); BSP::displayPhilStat(n, EATING); status_ = Q_HANDLED(); } // ${AOs::Table::SM::active::serving::HUNGRY::[else]} else { me->m_isHungry[n] = true; status_ = Q_HANDLED(); } break; } // ${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!me->m_isHungry[n])); BSP::displayPhilStat(n, THINKING); uint8_t m = LEFT(n); // both forks of Phil[n] must be used Q_ASSERT((me->m_fork[n] == USED) && (me->m_fork[m] == USED)); me->m_fork[m] = FREE; me->m_fork[n] = FREE; m = RIGHT(n); // check the right neighbor if (me->m_isHungry[m] && (me->m_fork[m] == FREE)) { me->m_fork[n] = USED; me->m_fork[m] = USED; me->m_isHungry[m] = false; TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; QP::QF::PUBLISH(pe, me); BSP::displayPhilStat(m, EATING); } m = LEFT(n); // check the left neighbor n = LEFT(m); // left fork of the left neighbor if (me->m_isHungry[m] && (me->m_fork[n] == FREE)) { me->m_fork[m] = USED; me->m_fork[n] = USED; me->m_isHungry[m] = false; TableEvt *pe = Q_NEW(TableEvt, EAT_SIG); pe->philoNum = m; QP::QF::PUBLISH(pe, me); BSP::displayPhilStat(m, EATING); } status_ = Q_HANDLED(); break; } // ${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_HANDLED(); break; } // ${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = Q_TRAN(&paused); break; } default: { status_ = Q_SUPER(&active); break; } } return status_; }
//${AOs::Table::SM::active::serving} ......................................... Q_STATE_DEF(Table, serving) { QP::QState status_; switch (e->sig) { //${AOs::Table::SM::active::serving} case Q_ENTRY_SIG: { for (uint8_t n = 0U; n < N_PHILO; ++n) { // give permissions to eat... if (m_isHungry[n] && (m_fork[LEFT(n)] == FREE) && (m_fork[n] == FREE)) { m_fork[LEFT(n)] = USED; m_fork[n] = USED; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, n), this); m_isHungry[n] = false; BSP_displayPhilStat(n, EATING); } } status_ = Q_RET_HANDLED; break; } //${AOs::Table::SM::active::serving::HUNGRY} case HUNGRY_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!m_isHungry[n])); BSP_displayPhilStat(n, HUNGRY); uint8_t m = LEFT(n); //${AOs::Table::SM::active::serving::HUNGRY::[bothfree]} if ((m_fork[m] == FREE) && (m_fork[n] == FREE)) { m_fork[m] = USED; m_fork[n] = USED; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, n), this); BSP_displayPhilStat(n, EATING); status_ = Q_RET_HANDLED; } //${AOs::Table::SM::active::serving::HUNGRY::[else]} else { m_isHungry[n] = true; status_ = Q_RET_HANDLED; } break; } //${AOs::Table::SM::active::serving::DONE} case DONE_SIG: { uint8_t n = Q_EVT_CAST(TableEvt)->philoNum; // phil ID must be in range and he must be not hungry Q_ASSERT((n < N_PHILO) && (!m_isHungry[n])); BSP_displayPhilStat(n, THINKING); uint8_t m = LEFT(n); // both forks of Phil[n] must be used Q_ASSERT((m_fork[n] == USED) && (m_fork[m] == USED)); m_fork[m] = FREE; m_fork[n] = FREE; m = RIGHT(n); // check the right neighbor if (m_isHungry[m] && (m_fork[m] == FREE)) { m_fork[n] = USED; m_fork[m] = USED; m_isHungry[m] = false; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, m), this); BSP_displayPhilStat(m, EATING); } m = LEFT(n); // check the left neighbor n = LEFT(m); // left fork of the left neighbor if (m_isHungry[m] && (m_fork[n] == FREE)) { m_fork[m] = USED; m_fork[n] = USED; m_isHungry[m] = false; QP::QF::PUBLISH(Q_NEW(TableEvt, EAT_SIG, m), this); BSP_displayPhilStat(m, EATING); } status_ = Q_RET_HANDLED; break; } //${AOs::Table::SM::active::serving::EAT} case EAT_SIG: { Q_ERROR(); status_ = Q_RET_HANDLED; break; } //${AOs::Table::SM::active::serving::PAUSE} case PAUSE_SIG: { status_ = tran(&paused); break; } default: { status_ = super(&active); break; } } return status_; }
// returns false if tree had problem, true otherwise bool TopTree::checkTree ( bool printMsgs ) { // now check parent kid correlations for ( int32_t i = 0 ; i < m_numUsedNodes ; i++ ) { // skip node if parents is -2 (unoccupied) if ( PARENT(i) == -2 ) continue; // if no left/right kid it MUST be -1 if ( LEFT(i) < -1 ) return log("query: toptree: checktree: left " "kid %"INT32" < -1",i); if ( RIGHT(i) < -1 ) return log("query: toptree: checktree: right " "kid %"INT32" < -1",i); // check left kid if ( LEFT(i) >= 0 && PARENT(LEFT(i)) != i ) return log("query: toptree: checktree: tree has " "error %"INT32"",i); // then right kid if ( RIGHT(i) >= 0 && PARENT(RIGHT(i)) != i ) return log("query: toptree: checktree: tree has " "error2 %"INT32"",i); } // now return if we aren't doing active balancing //if ( ! DEPTH ) return true; // debug -- just always return now if ( printMsgs ) log("***m_headNode=%"INT32", m_numUsedNodes=%"INT32"", m_headNode,m_numUsedNodes); // verify that parent links correspond to kids for ( int32_t i = 0 ; i < m_numUsedNodes ; i++ ) { int32_t P = PARENT (i); if ( P == -2 ) continue; // deleted node if ( P == -1 && i != m_headNode ) return log("query: toptree: checktree: node %"INT32" has " "no parent",i); // check kids if ( P>=0 && LEFT(P) != i && RIGHT(P) != i ) return log("query: toptree: checktree: node %"INT32"'s " "parent disowned",i); // ensure i goes back to head node int32_t j = i; while ( j >= 0 ) { if ( j == m_headNode ) break; j = PARENT(j); } if ( j != m_headNode ) return log("query: toptree: checktree: node %"INT32"'s no " "head node above",i); if ( printMsgs ) fprintf(stderr,"***node=%"INT32" left=%"INT32" rght=%"INT32" " "prnt=%"INT32", depth=%"INT32"\n", i,LEFT(i),RIGHT(i),PARENT(i), (int32_t)DEPTH(i)); //ensure depth int32_t newDepth = computeDepth ( i ); if ( DEPTH(i) != newDepth ) return log("query: toptree: checktree: node %"INT32"'s " "depth should be %"INT32"",i,newDepth); } if ( printMsgs ) log("query: ---------------"); // no problems found return true; }
void take_fork(int i){ extern sem_t mutex, s[N]; extern status state[N]; sem_wait(&mutex); state[i]=HUNGRY; try(i); sem_post(&mutex); sem_wait(&s[i]); } void leave_fork(int i){ extern sem_t mutex; extern status state[N]; sem_wait(&mutex); state[i]=THINKING; try(LEFT(i)); try(RIGHT(i)); sem_post(&mutex); } void try(int i){ extern sem_t s[N]; extern status state[N]; if(state[i]==HUNGRY && state[LEFT(i)]!=EATING && state[RIGHT(i)]!=EATING){ state[i]=EATING; sem_post(&s[i]); } } void *cook(){ //pop out food every 5 sec //There is a cooking process that produces food at regular intervals of 5 seconds. //The amount produced each time is a random value in the range [0, 100]. extern int food; while(1){ food+=randint(101); printf("food produced. food=%d\n",food); sleep(5); } } int main (){ pthread_t t[N],tc; //init threads, each running a philosopher int i,j; initVar(); //staring cooking thread: printf("starting cook thread:\n"); pthread_create(&tc,NULL,cook,NULL); for (i=0;i<N;i++){ printf("starting new phil=%d\n",i); pthread_create(&t[i],NULL,philosopher,&i); //sleeping for 100 usec so the i value doesnt change before the philosopher //func creates a local copy; usleep(100); } for (i=0;i<N;i++){ pthread_join(t[i],NULL); } //recycle cook thread: pthread_join(tc,NULL); return 0; }
// . remove this node from the tree // . used to remove the last node and replace it with a higher scorer void TopTree::deleteNode ( int32_t i , uint8_t domHash ) { // sanity check if ( PARENT(i) == -2 ) { char *xx=NULL;*xx=0; } // get node //TopNode *t = &m_nodes[i]; // debug //if ( ! checkTree ( false ) ) { char *xx = NULL; *xx = 0; } //if ( i == 262 ) // log("HEY"); // if it was the low node, update it if ( i == m_lowNode ) { m_lowNode = getNext ( i ); if ( m_lowNode == -1 ) { log("toptree: toptree delete error node #%"INT32" " "domHash=%"INT32" because next node is -1 numnodes=%"INT32"", i,(int32_t)domHash,m_numUsedNodes); //char *xx=NULL;*xx=0; } //return; } } // update the vcount if ( m_domCount[domHash] < m_cap ) m_vcount -= 1.0; else if ( m_domCount[domHash] == m_cap ) m_vcount -= m_partial; // update the dom count m_domCount[domHash]--; // debug //if ( domHash == 0x35 ) // log("top: domCount down for 0x%"XINT32" now %"INT32"",domHash,m_domCount[domHash]); // parent of i int32_t iparent ; int32_t jparent ; // j will be the node that replace node #i int32_t j = i; // . now find a node to replace node #i // . get a node whose key is just to the right or left of i's key // . get i's right kid // . then get that kid's LEFT MOST leaf-node descendant // . this little routine is stolen from getNextNode(i) // . try to pick a kid from the right the same % of time as from left if ( ( m_pickRight && RIGHT(j) >= 0 ) || ( LEFT(j) < 0 && RIGHT(j) >= 0 ) ) { // try to pick a left kid next time m_pickRight = 0; // go to the right kid j = RIGHT ( j ); // now go left as much as we can while ( LEFT ( j ) >= 0 ) j = LEFT ( j ); // use node j (it's a leaf or has a right kid) goto gotReplacement; } // . now get the previous node if i has no right kid // . this little routine is stolen from getPrevNode(i) if ( LEFT(j) >= 0 ) { // try to pick a right kid next time m_pickRight = 1; // go to the left kid j = LEFT ( j ); // now go right as much as we can while ( RIGHT ( j ) >= 0 ) j = RIGHT ( j ); // use node j (it's a leaf or has a left kid) goto gotReplacement; } // . come here if i did not have any kids (i's a leaf node) // . get i's parent iparent = PARENT(i); // make i's parent, if any, disown him if ( iparent >= 0 ) { if ( LEFT(iparent) == i ) LEFT (iparent) = -1; else RIGHT(iparent) = -1; } // empty him PARENT(i) = -2; // . reset the depths starting at iparent and going up until unchanged // . will balance at pivot nodes that need it //if ( m_doBalancing ) setDepths ( iparent ); // debug //if ( ! checkTree ( false ) ) { char *xx = NULL; *xx = 0; } goto done; // . now replace node #i with node #j // . i should not equal j at this point gotReplacement: // . j's parent should take j's one kid // . that child should likewise point to j's parent // . j should only have <= 1 kid now because of our algorithm above // . if j's parent is i then j keeps his kid jparent = PARENT(j); if ( jparent != i ) { // parent: if j is my left kid, then i take j's right kid // otherwise, if j is my right kid, then i take j's left kid if ( LEFT ( jparent ) == j ) { LEFT ( jparent ) = RIGHT ( j ); if (RIGHT(j)>=0) PARENT ( RIGHT(j) ) = jparent; } else { RIGHT ( jparent ) = LEFT ( j ); if (LEFT (j)>=0) PARENT ( LEFT(j) ) = jparent; } } // . j inherits i's children (providing i's child is not j) // . those children's parent should likewise point to j if ( LEFT (i) != j ) { LEFT (j) = LEFT (i); if ( LEFT(j) >= 0 ) PARENT(LEFT (j)) = j; } if ( RIGHT(i) != j ) { RIGHT(j) = RIGHT(i); if ( RIGHT(j) >= 0 ) PARENT(RIGHT(j)) = j; } // j becomes the kid of i's parent, if any iparent = PARENT(i); if ( iparent >= 0 ) { if ( LEFT(iparent) == i ) LEFT (iparent) = j; else RIGHT(iparent) = j; } // iparent may be -1 PARENT(j) = iparent; // if i was the head node now j becomes the head node if ( m_headNode == i ) m_headNode = j; // kill i PARENT(i) = -2; // return if we don't have to balance //if ( ! m_doBalancing ) return; // our depth becomes that of the node we replaced, unless moving j // up to i decreases the total depth, in which case setDepths() fixes DEPTH ( j ) = DEPTH ( i ); // debug msg //fprintf(stderr,"... replaced %"INT32" it with %"INT32" (-1 means none)\n",i,j); // . recalculate depths starting at old parent of j // . stops at the first node to have the correct depth // . will balance at pivot nodes that need it if ( jparent != i ) setDepths ( jparent ); else setDepths ( j ); done: // the guy we are deleting is now the first "empty node" and // he must link to the old empty node m_nodes[i].m_right = m_emptyNode; m_emptyNode = i; //m_lastKickedOutDocId = m_nodes[i].m_docId; // count it m_numUsedNodes--; // flag it m_kickedOutDocIds = true; // debug //if ( ! checkTree ( true ) ) { char *xx = NULL; *xx = 0; } }
void rb_delete_fixup(Node* &T, Node *x) { while ((NIL!= x) && !IS_ROOT(x) && IS_BLACK(x)) { if (IS_LEFT(x)) { // w是x的右兄弟,w是下面不同处理方式的选择依据 // 总共四种处理方式: // case 1: w是红色,两个孩子的颜色无所谓 // case 2: w是黑色,左孩子黑色,右孩子黑色 // case 3: w是黑色,左孩子红色,右孩子黑色 // case 4: w是黑色,右孩子红色,左孩子的颜色无所谓 Node *w = RIGHT(PARENT(x)); // case1: w是红色,则通过一次左旋,并刷成黑色,转成case 2、3、4 if (IS_RED(w)) { SET_BLACK(w); SET_RED(PARENT(x)); left_rotate(T, PARENT(x)); } // case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,向上递归处理 if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) { SET_RED(w); x = PARENT(x); continue; } // case 3: w的左孩子红色,右孩子黑色,把w左孩子刷成黑色,w刷成红色,做一次右旋,转成case 4 if (IS_BLACK(RIGHT(w))) { SET_BLACK(LEFT(w)); SET_RED(w); right_rotate(T, w); w = PARENT(w); // 转成case 4 } // case 4: w的右孩子为红色,把w刷成红色,w右节点刷成黑色,x父亲刷成黑色,做一次左旋,满足红黑性质,结束处理 COLOR(w) = COLOR(PARENT(x)); SET_BLACK(RIGHT(w)); SET_BLACK(PARENT(x)); left_rotate(T, PARENT(x)); x = T; } else { // w是x的左兄弟,w是下面不同处理方式的选择依据 // 总共四种处理方式: // case 1: w是红色,两个孩子的颜色无所谓 // case 2: w是黑色,左孩子黑色,右孩子黑色 // case 3: w是黑色,左孩子红色,右孩子黑色 // case 4: w是黑色,右孩子红色,左孩子的颜色无所谓 Node *w = LEFT(PARENT(x)); // case1: w是红色,则通过一次右旋,并刷成黑色,转成case 2、3、4 if (IS_RED(w)) { SET_BLACK(w); SET_RED(PARENT(x)); right_rotate(T, PARENT(x)); } // case 2: w的两个孩子都是黑色,把w刷成红色,x的父亲取代x,线上递归处理 if (IS_BLACK(LEFT(w)) && IS_BLACK(RIGHT(w))) { SET_RED(w); x = PARENT(x); continue; } // case 3: w的左孩子黑色,右孩子红色,把w右孩子刷成黑色,w刷成红色,做一次左旋,转成case 4 if (IS_BLACK(LEFT(w))) { SET_BLACK(RIGHT(w)); SET_RED(w); left_rotate(T, w); w = PARENT(w); // 转成case 4 } // case 4: w的左孩子为红色,把w刷成红色,w左节点刷成黑色,x父亲刷成黑色,做一次右旋,满足红黑性质,结束处理 COLOR(w) = COLOR(PARENT(x)); SET_BLACK(LEFT(w)); SET_BLACK(PARENT(x)); right_rotate(T, PARENT(x)); x = T; } } // 如果x是根节点,或为红色,则都刷成黑色,即可保持红黑树性质 SET_BLACK(x); }
/* * Labeling the even lines for hexagonal grid. * * \param plines_out pointer on the current line in the destination image * \param plines_in pointer on the current line in the source image * \param index line being processed * \param bytes_in number of bytes inside the line * \param labels the labels arrays and context */ static INLINE void HLAB_LINE_EVEN(PLINE *plines_out, PLINE *plines_in, Uint32 index, Uint32 bytes_in, MB_Label_struct *labels) { Uint32 i,j; MB_Vector1 pix_reg_cur, pix_reg_pre, previous_pix_cur, previous_pix_pre; MB_Vector1 neighbor_state; MB_Vector1 *pin = (MB_Vector1 *) (plines_in[index]); MB_Vector1 *pinpre = (MB_Vector1 *) (plines_in[index-1]); PIX32 *pout = (PIX32 *) (plines_out[index]); PIX32 *poutpre = (PIX32 *) (plines_out[index-1]); /* Previous values initialisation */ previous_pix_cur = 0; previous_pix_pre = 0; for(i=0;i<bytes_in;i+=sizeof(MB_Vector1),pin++,pinpre++) { /* Reading a register of pixels in the two sources lines*/ pix_reg_cur = (*pin); pix_reg_pre = (*pinpre); for(j=0; j<MB_vec1_size; j++,pout++,poutpre++) { /* For all the pixels in the registers */ if (pix_reg_cur&1) { neighbor_state = (previous_pix_cur&1) | ((previous_pix_pre&1)<<1) | ((pix_reg_pre&1)<<2); /* The neighbor state gives the values of the neighbor bit of the currently */ /* evaluated bit (a&1). It allows to determine which value will take the label */ /* in the output image (pout).*/ /* We always take the label of the last labelled neighbor */ /* in case more than one neighbor is labelled, the equivalence */ /* table is updated */ switch(neighbor_state) { case 1: VAL(pout) = MB_find_above_label(labels, LEFT(pout)); break; case 2: VAL(pout) = MB_find_above_label(labels, LEFT(poutpre)); break; case 3: VAL(pout) = MB_find_above_label(labels, LEFT(pout)); if (LEFT(poutpre) != VAL(pout)) labels->EQ[VAL(pout)] = MB_find_above_label(labels, LEFT(poutpre)); break; case 4: case 6: VAL(pout) = MB_find_above_label(labels, VAL(poutpre)); break; case 5: case 7: VAL(pout) = MB_find_above_label(labels, LEFT(pout)); if (VAL(poutpre) != VAL(pout)) labels->EQ[VAL(pout)] = MB_find_above_label(labels, VAL(poutpre)); break; default: /* Case 0 */ VAL(pout) = (labels->current); /* No neighbors labelled we take one */ labels->EQ[labels->current] = labels->current; labels->current++; break; } } previous_pix_cur = pix_reg_cur; previous_pix_pre = pix_reg_pre; /* Next pixel */ pix_reg_cur = pix_reg_cur>>1; pix_reg_pre = pix_reg_pre>>1; } } }
void doComputer(int player, int target) { AI *ai; Data *data; Player *me, *him; int i, j, level, x, y; int rdist = 0, ldist = 0; me = &(game->player[ player ]); him = &(game->player[ target ]); if(me->ai == NULL) { printf("This player has no AI data!\n"); return; } data = me->data; ai = me->ai; level = game2->settingsCache.ai_level; ai->moves++; /* avoid to short turns */ if(game2->time.current - ai->lasttime < turn_time[level]) return; /* first, check if we are in danger */ /* check the highest level first! */ for(i = level; i >= 0; i++) { for(j = probe_dists[i][0]; j <= probe_dists[i][1]; j++) { setPos(data, &x, &y); getDistPoint(data->dir, j, &x, &y); if(getCol(x, y)) { ai->danger = j; break; } } if(ai->danger != 0) break; } if(ai->danger != 0 || ai->moves > max_moves[level] * game2->rules.grid_size) { ai->moves = 0; /* figure out how far it's to either side */ for(i = 1; i < MAX_PROBE_DIST; i++) { setPos(data, &x, &y); getDistPoint(LEFT(data->dir), i, &x, &y); if(getCol(x, y)) { ldist = i; break; } else { ldist = i; } } for(i = 1; i < MAX_PROBE_DIST; i++) { setPos(data, &x, &y); getDistPoint(RIGHT(data->dir), i, &x, &y); if(getCol(x, y)) { rdist = i; break; } else { rdist = i; } } /* decide where to turn */ if(ai->danger > rdist && ai->danger > ldist) { ai->danger--; return; } else if(rdist > ldist && ai->tdiff > -spiral[level] ) { createEvent(player, EVENT_TURN_RIGHT); ai->tdiff--; } else if(rdist < ldist && ai->tdiff < spiral[level] ) { createEvent(player, EVENT_TURN_LEFT); ai->tdiff++; } else { if(ai->tdiff > 0) { createEvent(player, EVENT_TURN_RIGHT); ai->tdiff--; } else { createEvent(player, EVENT_TURN_LEFT); ai->tdiff++; } } ai->danger = 0; ai->lasttime = game2->time.current; } }