static inline bool trylock( TYPE id ) {					// based on Lamport-Fast algorithm
	b[id] = true;
	x = id;
	Fence();											// force store before more loads
	if ( FASTPATH( y != N ) ) {
		b[id] = false;
		return false;
	} // if
	y = id;
	Fence();											// force store before more loads
	if ( FASTPATH( x != id ) ) {
		b[id] = false;
		Fence();										// OPTIONAL, force store before more loads
		for ( int k = 0; k < N; k += 1 )
			await( ! b[k] );
		if ( FASTPATH( y != id ) ) return false;
	} // if
	bool leader;
	if ( ! fast ) { fast = true; leader = true; }
	else leader = false;
	y = N;
	b[id] = false;
	return leader;
} // WCas
static inline bool trylock( TYPE id ) {					// based on Burns-Lamport algorithm
	b[id] = true;
	Fence();											// force store before more loads
	for ( typeof(id) thr = 0; thr < id; thr += 1 ) {
		if ( FASTPATH( b[thr] ) ) {
			b[id] = false;
			return false ;
		} // if
	} // for
	for ( typeof(id) thr = id + 1; thr < N; thr += 1 ) {
		await( ! b[thr] );
	} // for
	bool leader;
	if ( ! fast ) { fast = true; leader = true; }
	else leader = false;
	b[id] = false;
	return leader;
} // WCas
示例#3
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
示例#4
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
示例#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 ) {
			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