示例#1
0
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;
}
示例#6
0
//
// 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;
}
示例#7
0
文件: tsearch.c 项目: siddhesh/glibc
/* 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;
}
示例#8
0
void get_left_fork(int mine)
{
    int item = LEFT(mine);
    set_busy(item);	
}
示例#9
0
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;
		}
示例#10
0
文件: tsearch.c 项目: siddhesh/glibc
/* 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);
		}
	    }
	}
    }
}
示例#11
0
文件: table.cpp 项目: alisonjoe/qpcpp
// ${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_;
}
示例#12
0
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();
}
示例#13
0
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*/
示例#15
0
//............................................................................
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);
}
示例#16
0
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);
	}
}
示例#17
0
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;
}
示例#18
0
void put_left_fork(int mine)
{
    int item = LEFT(mine);
    set_free(item);	
}
示例#19
0
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;
}
示例#20
0
文件: table.cpp 项目: alisonjoe/qpcpp
//${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_;
}
示例#21
0
//${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;
}
示例#23
0
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; }
}
示例#25
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);
}
示例#26
0
/*
 * 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;
        }
    }
}
示例#27
0
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;
  }
}