static void *Worker( void *arg ) {
	TYPE id = (size_t)arg;
	uint64_t entry;
#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST

	unsigned int lid;									// local id at each tree level

	for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
			lid = id;									// entry protocol
			for ( int lv = 0; lv < depth; lv += 1 ) {
				binary_prologue( lid & 1, &t[lv][lid >> 1] );
				lid >>= 1;								// advance local id for next tree level
			} // for

			CriticalSection( id );

			for ( int lv = depth - 1; lv >= 0; lv -= 1 ) { // exit protocol, retract reverse order
				lid = id >> lv;
				binary_epilogue( lid & 1, &t[lv][lid >> 1] );
			} // for
#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
	} // for
	return NULL;
} // Worker
Example #2
0
static void *Worker( void *arg ) {
    TYPE id = (size_t)arg;
    uint64_t entry;

	int other = inv( id );								// int is better than TYPE

#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST

    for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
			intents[id] = WantIn;						// entry protocol
			last = id;									// RACE
			Fence();									// force store before more loads
			if ( FASTPATH( intents[other] != DontWantIn ) )	// local spin
				while ( last == id ) Pause();			// busy wait
			CriticalSection( id );
			intents[id] = DontWantIn;					// exit protocol
			last = id;
#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			other = inv( id );
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
		other = inv( id );
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
    } // for
	return NULL;
} // Worker
Example #3
0
static void *Worker( void *arg ) {
	TYPE id = (size_t)arg;
#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST
	uint64_t entry;

	for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
		  L0: control[id] = WantIn;						// entry protocol
			Fence();									// force store before more loads
		  L1: for ( int j = turn; j != id; j = cycleDown( j, N ) )
				if ( control[j] != DontWantIn ) { Pause(); goto L1; } // restart search
			control[id] = EnterCS;
			Fence();									// force store before more loads
			for ( int j = N - 1; j >= 0; j -= 1 )
				if ( j != id && control[j] == EnterCS ) goto L0;
			CriticalSection( id );
			// cycle through threads
			if ( control[turn] == DontWantIn || turn == id ) // exit protocol
				turn = cycleDown( turn, N );
			control[id] = DontWantIn;
#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
	} // for
	return NULL;
} // Worker
static void *Worker( void *arg ) {
	const TYPE id = (size_t)arg;
	uint64_t entry;
#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST

	for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
		  L0: intents[id] = DontWantIn;					// entry protocol
			Fence();									// force store before more loads
			for ( int j = 0; j < id; j += 1 )
				if ( intents[j] == WantIn ) { Pause(); goto L0; }
			intents[id] = WantIn;
			Fence();									// force store before more loads
			for ( int j = 0; j < id; j += 1 )
				if ( intents[j] == WantIn ) goto L0;
		  L1: for ( int j = id + 1; j < N; j += 1 )
				if ( intents[j] == WantIn ) { Pause(); goto L1; }
			CriticalSection( id );						// critical section
			intents[id] = DontWantIn;					// exit protocol
#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
	} // for
	return NULL;
} // Worker
Example #5
0
static void *Worker( void *arg ) {
	TYPE id = (size_t)arg;
	uint64_t entry;

	int other = inv( id );								// int is better than TYPE

#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST

	for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
#ifdef FLICKER
			for ( int i = 0; i < 100; i += 1 ) cc[id] = i % 2; // flicker
#endif // FLICKER
			cc[id] = WantIn;							// declare intent
			Fence();									// force store before more loads
			while ( cc[other] == WantIn ) {
				if ( FASTPATH( last == id ) ) {
#ifdef FLICKER
					for ( int i = 0; i < 100; i += 1 ) cc[id] = i % 2; // flicker
#endif // FLICKER
					cc[id] = DontWantIn;
					while( cc[other] == WantIn && last == id ) Pause();	// low priority busy wait
#ifdef FLICKER
					for ( int i = 0; i < 100; i += 1 ) cc[id] = i % 2; // flicker
#endif // FLICKER
					cc[id] = WantIn;					// declare intent
					Fence();							// force store before more loads
				} // if
			} // while
			CriticalSection( id );
			if ( last != id ) {
#ifdef FLICKER
				for ( int i = id; i < 100; i += 1 ) last = i % 2; // flicker
#endif // FLICKER
				last = id;
			} // if
#ifdef FLICKER
			for ( int i = 0; i < 100; i += 1 ) cc[id] = i % 2; // flicker
#endif // FLICKER
			cc[id] = DontWantIn;

#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			other = inv( id );
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
		other = inv( id );
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
	} // for
	return NULL;
} // Worker
Example #6
0
static void *Worker( void *arg ) {
	TYPE id = (size_t)arg;
	uint64_t entry;

	int other = inv( id );								// int is better than TYPE

#ifdef FAST
	unsigned int cnt = 0, oid = id;
#endif // FAST

	for ( int r = 0; r < RUNS; r += 1 ) {
		entry = 0;
		while ( stop == 0 ) {
			for ( ;; ) {
#ifdef FLICKER
				for ( int i = 0; i < 100; i += 1 ) intents[id] = i % 2; // flicker
#endif // FLICKER
				intents[id] = WantIn;					// declare intent
				// Necessary to prevent the read of intents[other] from floating above the assignment
				// intents[id] = WantIn, when the hardware determines the two subscripts are different.
				Fence();								// force store before more loads
			  if ( FASTPATH( intents[other] == DontWantIn ) ) break;
				if ( last == id ) {
#ifdef FLICKER
					for ( int i = 0; i < 100; i += 1 ) intents[id] = i % 2; // flicker
#endif // FLICKER
					intents[id] = DontWantIn;
					// Optional fence to prevent LD of "last" from being lifted above store of
					// intends[id]=DontWantIn. Because a thread only writes its own id into "last",
					// and because of eventual consistency (writes eventually become visible),
					// the fence is conservative.
					//Fence();							// force store before more loads
					await( last != id );				// low priority busy wait
				} // if
			} // for
			CriticalSection( id );
#ifdef FLICKER
			for ( int i = id; i < 100; i += 1 ) last = i % 2; // flicker
#endif // FLICKER
			last = id;									// exit protocol
#ifdef FLICKER
			for ( int i = 0; i < 100; i += 1 ) intents[id] = i % 2; // flicker
#endif // FLICKER
			intents[id] = DontWantIn;

#ifdef FAST
			id = startpoint( cnt );						// different starting point each experiment
			other = inv( id );
			cnt = cycleUp( cnt, NoStartPoints );
#endif // FAST
			entry += 1;
		} // while
#ifdef FAST
		id = oid;
		other = inv( id );
#endif // FAST
		entries[r][id] = entry;
		__sync_fetch_and_add( &Arrived, 1 );
		while ( stop != 0 ) Pause();
		__sync_fetch_and_add( &Arrived, -1 );
	} // for
	return NULL;
} // Worker