예제 #1
0
THREAD_RETURN WINAPI bgThread4SemTest( LPVOID dum )
{ unsigned long ret;
  double tEnd;
  HANDLE hh;
	MSEmul_UseSharedMemory(true);
	hh = OpenSemaphore( DELETE|SYNCHRONIZE|SEMAPHORE_MODIFY_STATE, false, (char*)"cseSem");
	if( hh ){
#if defined(__windows__)
		fprintf( stderr, "##%lx bgThread4SemTest starting to wait for semaphore (0x%p) release at t=%g\n",
			   GetCurrentThreadId(), hh, HRTime_Time() - tStart );
#else
		fprintf( stderr, "##%lx bgThread4SemTest starting to wait for semaphore (0x%p,%s,%p) release at t=%g\n",
			   GetCurrentThreadId(), hh, hh->d.s.name, hh->d.s.sem, HRTime_Time() - tStart );
#endif
		ret = WaitForSingleObject( hh, INFINITE ); tEnd = HRTime_Time();
		fprintf( stderr, "##%lx WaitForSingleObject( hh, INFINITE ) = %lu at t=%g; sleep(1ms) and ReleaseSemaphore(hh,1,NULL)\n",
			   GetCurrentThreadId(), ret, tEnd - tStart );
		Sleep(1);
		fprintf( stderr, "##%lx t=%g ReleaseSemaphore(hh,1,NULL) = %d\n",
			   GetCurrentThreadId(), HRTime_Time() - tStart, ReleaseSemaphore(hh, 1, NULL) );
		CloseHandle(hh);
  	}
	else{
		fprintf( stderr, "##%lx bgThread4SemTest() couldn't obtain semaphore '%s', will exit\n", GetCurrentThreadId(), "cseSem" );
	}
	return (THREAD_RETURN)3;
}
예제 #2
0
THREAD_RETURN WINAPI bgThread2Nudge( LPVOID dum )
{ unsigned long ret;
  double tEnd;
	fprintf( stderr, "##%lx bgThread2Nudge starting to wait for nudge event at t=%g\n", GetCurrentThreadId(), HRTime_Time() - tStart );
	ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time();
	fprintf( stderr, "##%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g; sleep(1ms) and then send return nudge\n", GetCurrentThreadId(), ret, tEnd - tStart );
	Sleep(1);
	fprintf( stderr, "##%lx t=%g SetEvent(nudgeEvent) = %d\n", GetCurrentThreadId(), HRTime_Time() - tStart, SetEvent(nudgeEvent) );
	return (THREAD_RETURN)2;
}
예제 #3
0
BOOL ReceiveMessageFromNet( SOCK ss, NetMessage *msg, int timeOutMs, BOOL block, const char *caller )
{ BOOL ret = FALSE;
	if( msg && ss != NULLSOCKET ){
	  CritSectEx::Scope scope(ReceiveMutex);
		ret = BasicReceiveNetMessage( ss, msg, sizeof(NetMessage), timeOutMs, block );
		if( ret ){
			if( msg->size != sizeof(NetMessage) || msg->protocol != NETMESSAGE_PROTOCOL ){
				QTils_LogMsgEx(
							"ReceiveMessageFromNet: ignoring NetMessage with size %hu!=%hu and/or protocol %hu!=%hu",
							msg->size, sizeof(NetMessage), msg->protocol, NETMESSAGE_PROTOCOL );
				ret = FALSE;
				receiveError();
			}
#ifdef COMMTIMING
			msg->recdTime = HRTime_Time();
			if( msg->sentTime >= 0.0 ){
				cumSendRcvDelay += msg->recdTime - msg->sentTime;
				sendRcvDelays += 1;
			}
#endif
		}
		else{
			if( errSock ){
				NetMessageToLogMsg( caller, "Receive error)", msg );
				receiveError();
				errSock = 0;
			}
		}
	}
	return ret;
}
예제 #4
0
BOOL SendMessageToNet( SOCK ss, NetMessage *msg, int timeOutMs, BOOL block, const char *caller )
{ BOOL ret = FALSE;
	if( msg && ss != NULLSOCKET ){
	  CritSectEx::Scope scope(SendMutex);
		errSock = 0;
		msg->size = sizeof(*msg);
		msg->protocol = NETMESSAGE_PROTOCOL;
#ifdef COMMTIMING
		msg->sentTime = HRTime_Time();
		msg->recdTime = -1;
#endif
		ret = BasicSendNetMessage( ss, msg, sizeof(NetMessage), timeOutMs, block );
		if( ret ){
			NetMessageToLogMsg( caller, "(sent)", msg );
		}
		else{
			NetMessageToLogMsg( caller, "(failure)", msg );
			if( errSock ){
				SendErrors += 1;
				if( HandleSendErrors ){
					HandleSendErrors(SendErrors);
				}
			}
		}
	}
	return ret;
}
예제 #5
0
THREAD_RETURN WINAPI bgThreadSleeper( LPVOID dum )
{
	fprintf( stderr, "## GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);
	fprintf( stderr, "## GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);
	fprintf( stderr, "## GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);
	fprintf( stderr, "##%lx bgThreadSleeper starting to sleep for 5s at t=%g\n", GetCurrentThreadId(), HRTime_Time() - tStart );
	Sleep(5000);
	fprintf( stderr, "##%lx bgThreadSleeper will exit at t=%g\n", GetCurrentThreadId(), HRTime_Time() - tStart );
	return (THREAD_RETURN)1;
}
예제 #6
0
int ParallelFileProcessor::run()
{ FileEntry entry;
  int i, nRequested = nJobs;
  double N = size(), prevPerc = 0;
	if( nJobs >= 1 ){
		allDoneEvent = CreateEvent( NULL, false, false, NULL );
	}
	for( i = 0 ; i < nJobs ; ++i ){
		// workers attacking the item list rear are created last
		// (not that this makes any difference except in the stats summary print out...)
		bool fromRear = i >= nJobs - nReverse;
		FileProcessor *thread = new FileProcessor(this, fromRear, i);
		if( thread ){
			threadPool.push_back(thread);
		}
		else{
			nJobs -= 1;
		}
	}
	if( nJobs != nRequested ){
		fprintf( stderr, "Parallel processing with %ld instead of %d threads\n", nJobs, nRequested );
	}
	const double startTime = HRTime_Time();
	for( i = 0 ; i < nJobs ; ++i ){
		threadPool[i]->Start();
	}
	if( allDoneEvent ){
	 DWORD waitResult = ~WAIT_OBJECT_0;
		// contrary to what one might expect, we should NOT use size()==0 as a stopping criterium.
		// The queue size is decreased when a worker picks a new file to process, not when it's
		// finished. Using size()==0 as a stopping criterium caused the processing interrupts
		// that were observed with large files.
		while( nJobs >= 1 && !quitRequested() && waitResult != WAIT_OBJECT_0 ){
			if( nJobs ){
			 double perc = 100.0 * nProcessed / N;
				 if( perc >= prevPerc + 10 ){
					 fprintf( stderr, "%s %d%%", (prevPerc > 0)? " .." : "", int(perc + 0.5) );
					 if( verboseLevel > 1 ){
					   double avCPUUsage = 0;
						for( i = 0 ; i < nJobs ; ++i ){
							if( threadPool[i]->nProcessed && threadPool[i]->avCPUUsage > 0){
								avCPUUsage += threadPool[i]->avCPUUsage / threadPool[i]->nProcessed;
							}
						}
						if (avCPUUsage >= 0) {
							// we report the combined, not the average CPU time, so N threads
							// having run at 100% CPU will print as N00% CPU.
							fprintf( stderr, " [%0.2lf%%]", avCPUUsage );
						}
					 }
					 fflush(stderr);
					 prevPerc = perc;
				 }
			}
			waitResult = WaitForSingleObject( allDoneEvent, 2000 );
		}
		if( (quitRequested() && !threadPool.empty()) || nProcessing > 0 ){
			// the WaitForSingleObject() call above was interrupted by the signal that
			// led to quitRequested() being set and as a result the workers haven't yet
			// had the chance to exit cleanly. Give them that chance now.
			fprintf( stderr, " quitting [%ld]...", nProcessing ); fflush(stderr);
			waitResult = WaitForSingleObject( allDoneEvent, nProcessing * 500 );
			for( i = 0 ; i < nProcessing && waitResult == WAIT_TIMEOUT ; ++i ){
				fprintf( stderr, " [%ld]...", nProcessing) ; fflush(stderr);
				waitResult = WaitForSingleObject( allDoneEvent, nProcessing * 500 );
			}
		}
		fputc( '\n', stderr );
		CloseHandle(allDoneEvent);
		allDoneEvent = NULL;
	}
	i = 0;
	double totalUTime = 0, totalSTime = 0;
	// forced verbose mode: prints out statistics even if some aren't meaningful when
	// verboseLevel==0 (like compression ratios in zfsctool).
	int verbose = verboseLevel;
	if (getenv("VERBOSE")) {
		verbose = atoi(getenv("VERBOSE"));
	}
	while( !threadPool.empty() ){
	 FileProcessor *thread = threadPool.front();
		if( thread->GetExitCode() == (THREAD_RETURN)STILL_ACTIVE ){
			fprintf( stderr, "Stopping worker thread #%d that is still %s!\n", i, (thread->scope)? "processing" : "active" );
			std::string currentFileName = thread->currentFileName();
			if( currentFileName.c_str()[0] ){
				fprintf( stderr, "\tcurrent file: %s\n", currentFileName.c_str() );
			}
			thread->Stop(true);
		}
		if( thread->nProcessed ){
			if( verbose ){
				fprintf( stderr, "Worker thread #%d processed %ld files",
					i, thread->nProcessed );
				fprintf( stderr, ", %0.2lf Kb [%0.2lf Kb] -> %0.2lf Kb [%0.2lf Kb] (%0.2lf%%)",
					thread->runningTotalRaw/1024.0, thread->runningTotalRaw/1024.0/thread->nProcessed,
					thread->runningTotalCompressed/1024.0, thread->runningTotalCompressed/1024.0/thread->nProcessed,
					100.0 * double(thread->runningTotalRaw - thread->runningTotalCompressed) / double(thread->runningTotalRaw) );
				if( thread->isBackwards ){
					fprintf( stderr, " [reverse]");
				}
				if( verbose > 1 ){
					if( thread->hasInfo ){
						fprintf( stderr, "\n\t%gs user + %gs system",
							thread->userTime, thread->systemTime );
						totalUTime += thread->userTime, totalSTime += thread->systemTime;
#ifdef __MACH__
						fprintf( stderr, "; %ds slept", thread->threadInfo.sleep_time );
#elif defined(CLOCK_THREAD_CPUTIME_ID)
						fprintf(stderr, " ; %gs CPU", thread->cpuTime);
#endif
						const auto acu = thread->avCPUUsage / thread->nProcessed;
						if (thread->avCPUUsage >= 0) {
							fprintf(stderr, "; %0.2lf%%", acu);
						}
						if (thread->m_ThreadCtx.m_runTime > 0) {
							const auto rcu = (thread->userTime + thread->systemTime) * 100.0 / thread->m_ThreadCtx.m_runTime;
							if (std::fabs(rcu - acu) > 5) {
								fprintf(stderr, "; %0.2lf%% real", rcu);
							}
						}
					}
				}
				fputc( '\n', stderr );
			}
		}
		delete thread;
		threadPool.pop_front();
		i++;
	}
	const double endTime = HRTime_Time();
	if( verbose > 1 && (totalUTime || totalSTime)){
		const double totalCPUUsage = (totalUTime + totalSTime) * 100.0 / (endTime - startTime);
		fprintf(stderr, "Total %gs user + %gs system; %gs total; %0.2lf%% CPU\n",
				totalUTime, totalSTime, endTime - startTime, totalCPUUsage);
	}
	return nProcessed;
}
예제 #7
0
int main( int argc, char *argv[] )
{ int i;
  HANDLE bgThread;
  DWORD exitCode;
  SECURITY_ATTRIBUTES semSec;

	MSEmul_UseSharedMemory(true);

#if 1
{ char test[256], *head;
	test[0] = '\0';
	head = test;
	fprintf( stderr, "appending to test[%lu] with snprintf:\n", sizeof(test) );
	do{
	  int len = strlen(test), n;
	  size_t ni = strlen("0123456789");
		fprintf( stderr, "len(test[%lu])=%d, rem. %lu added", sizeof(test), len, (size_t)(sizeof(test) - len) ); fflush(stderr);
		n = snprintf( &test[len], (size_t)(sizeof(test) - len), "0123456789" );
		head += n;
		fprintf( stderr, " %d (head[%lu]=", n, head - test ); fflush(stderr);
		if( len + n < sizeof(test) ){
			fprintf( stderr, "%c) -> %lu\n", head[0], strlen(test) );
		}
		else{
			fprintf( stderr, "!$@#) -> %lu\n", strlen(test) );
		}
	} while( strlen(test) < sizeof(test)-1 );
	fprintf( stderr, "test = %s\n", test );
}
#endif
	init_HRTime();
	tStart = HRTime_Time();
	HRTime_tic();
	{ double t0;
	  DWORD ret;
	  HANDLE hh;
		if( (hh = CreateSemaphore( NULL, 1, 0x7FFFFFFF, NULL )) ){
			t0 = HRTime_Time();
			ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000));
			t0 = HRTime_Time() - t0;
			fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n",
				   (DWORD)(SLEEPTIMEFG*1000), ret, t0
			);
			t0 = HRTime_Time();
			ret = WaitForSingleObject(hh, (DWORD)(SLEEPTIMEFG*1000));
			t0 = HRTime_Time() - t0;
			fprintf( stderr, "WaitForSingleObject(hh,%lu)==%lu took %g seconds\n",
				   (DWORD)(SLEEPTIMEFG*1000), ret, t0
			);
			t0 = HRTime_Time();
			ret = WaitForSingleObject(hh, 500);
			t0 = HRTime_Time() - t0;
			fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds\n",
				   ret, t0
			);
			ReleaseSemaphore(hh, 1, NULL);
			t0 = HRTime_Time();
			ret = WaitForSingleObject(hh, 500);
			t0 = HRTime_Time() - t0;
			fprintf( stderr, "WaitForSingleObject(hh,500)==%lu took %g seconds after ReleaseSemaphore()\n",
				   ret, t0
			);
			CloseHandle(hh);
		}
		else{
			fprintf( stderr, "Error creating semaphore: %s\n", winError(GetLastError()) );
		}

		ret = 0;
		YieldProcessor();
		fprintf( stderr, "sizeof(long)=%lu\n", sizeof(long) );
		_WriteBarrier();
		{ long oval, lbool;
		  void *ptr = NULL, *optr;
			oval = _InterlockedCompareExchange( (long*) &ret, 10L, 0L );
			fprintf( stderr, "_InterlockedCompareExchange(&ret==0, 10, 0) == %lu, ret==%lu\n", oval, ret );
			optr = InterlockedCompareExchangePointer( &ptr, (void*) fprintf, NULL );
			fprintf( stderr, "InterlockedCompareExchangePointer(&ptr==NULL, fprintf==%p, NULL) == %p, ret==%p\n",
				   fprintf, optr, ptr );
			_InterlockedIncrement( (long*) &ret );
			fprintf( stderr, "_InterlockedIncrement(&ret) ret=%lu\n", ret );
			_InterlockedDecrement( (long*) &ret );
			fprintf( stderr, "_InterlockedDecrement(&ret) ret=%lu\n", ret );
			_ReadWriteBarrier();
			lbool = false;
			_InterlockedSetTrue(&lbool);
			fprintf( stderr, "lbool = %ld\n", lbool );
			_InterlockedSetTrue(&lbool);
			fprintf( stderr, "lbool = %ld\n", lbool );
			_InterlockedSetFalse(&lbool);
			fprintf( stderr, "lbool = %ld\n", lbool );
		}
	}
#ifdef DEBUG
	{ CSEScopedLock *scope = ObtainCSEScopedLock(NULL);
		fprintf( stderr, "NULL testscope %p:locked==%u\n", scope, IsCSEScopeLocked(scope) );
		scope = ReleaseCSEScopedLock(scope);
	}
#endif

	csex = CreateCSEHandle(4000);
	if( !csex ){
		fprintf( stderr, "Failure creating CSEHandle\n" );
		exit(1);
	}
	else{
		fprintf( stderr, "Created a '%s' CSEHandle with spinMax==%lu\n", CSEHandleInfo(csex), csex->spinMax );
	}

	fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);
	fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);
	fprintf( stderr, "GetCurrentThread() = 0x%p\n", GetCurrentThread() ); Sleep(5);

	fputs( "\n", stderr );
	if( (bgThread = CreateThread( NULL, 0, bgThreadSleeper, NULL, CREATE_SUSPENDED, NULL )) ){
	  unsigned long ret;
	  double tEnd;
		fprintf( stderr, ">%lx t=%g will start %lx and WaitForSingleObject on it (should take 5s)\n",
			   GetCurrentThreadId(), HRTime_Time() - tStart, GetThreadId(bgThread) );
		ResumeThread(bgThread);
//		Sleep(1);
		ret = WaitForSingleObject( bgThread, 1500 ); tEnd = HRTime_Time();
		GetExitCodeThread( bgThread, &exitCode );
		fprintf( stderr, ">%lx WaitForSingleObject(bgThread,1500)=%lu exitCode=%ld at t=%g\n",
			   GetCurrentThreadId(), ret, exitCode, tEnd - tStart );
		ret = WaitForSingleObject( bgThread, 10000 ); tEnd = HRTime_Time();
		GetExitCodeThread( bgThread, &exitCode );
		fprintf( stderr, ">%lx WaitForSingleObject(bgThread,10000)=%lu exitCode=%ld at t=%g\n",
			   GetCurrentThreadId(), ret, exitCode, tEnd - tStart );
		CloseHandle(bgThread);
	}
	fputs( "\n", stderr );
	if( (nudgeEvent = CreateEvent( NULL, false, false, NULL )) ){
		if( (bgThread = CreateThread( NULL, 0, bgThread2Nudge, NULL, 0, NULL )) ){
		  unsigned long ret;
		  double tEnd;
			Sleep(1000);
			fprintf( stderr, ">%lx t=%g SetEvent(nudgeEvent) = %d; sleep(1ms) and then wait for return nudge\n", GetCurrentThreadId(), HRTime_Time() - tStart, SetEvent(nudgeEvent) );
			Sleep(1);
			ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time();
			fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n",
				   GetCurrentThreadId(), ret, tEnd - tStart );
			ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time();
			GetExitCodeThread( bgThread, &exitCode );
			fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n",
				   GetCurrentThreadId(), ret, exitCode, tEnd - tStart );
			CloseHandle(bgThread);
		}
		CloseHandle(nudgeEvent);
	}
	fputs( "\n", stderr );
	semSec.nLength = sizeof(SECURITY_ATTRIBUTES);
	semSec.lpSecurityDescriptor = NULL;
	semSec.bInheritHandle = true;
	// semSec does not actually need to be used:
	if( (nudgeEvent = CreateSemaphore( &semSec, 0, 0x7FFFFFFF, (char*) "cseSem" )) ){
		if( (bgThread = CreateThread( NULL, 0, bgThread4SemTest, NULL, 0, NULL )) ){
		  unsigned long ret;
		  double tEnd;
			Sleep(1000);
			fprintf( stderr, ">%lx t=%g ReleaseSemaphore(nudgeEvent,1,NULL) = %d; sleep(1ms) and then wait for return nudge\n",
				   GetCurrentThreadId(), HRTime_Time() - tStart, ReleaseSemaphore(nudgeEvent, 1, NULL) );
			Sleep(1);
			ret = WaitForSingleObject( nudgeEvent, INFINITE ); tEnd = HRTime_Time();
			fprintf( stderr, ">%lx WaitForSingleObject( nudgeEvent, INFINITE ) = %lu at t=%g\n",
				   GetCurrentThreadId(), ret, tEnd - tStart );
			ret = WaitForSingleObject( bgThread, 5000 ); tEnd = HRTime_Time();
			GetExitCodeThread( bgThread, &exitCode );
			fprintf( stderr, ">%lx WaitForSingleObject(bgThread,5000)=%lu exitCode=%ld at t=%g\n",
				   GetCurrentThreadId(), ret, exitCode, tEnd - tStart );
			CloseHandle(bgThread);
		}
		CloseHandle(nudgeEvent);
	}
	fputs( "\n", stderr );
	if( (bgThread = CreateThread( NULL, 0, bgCSEXaccess, NULL, CREATE_SUSPENDED, NULL )) ){
		fprintf( stderr, "csex is %slocked\n", (IsCSEHandleLocked(csex))? "" : "not " );
		SetThreadPriority( bgThread, GetThreadPriority(GetCurrentThread()) );
		fprintf( stderr, "GetThreadPriority(GetCurrentThread()) = %d\n", GetThreadPriority(GetCurrentThread()) );
		ResumeThread(bgThread);
		i = 0;
		fprintf( stderr, "entering main csex locking loop at t=%gs\n", HRTime_toc() );
		while( i < 5 ){
		  double t0, t1;

			if( IsCSEHandleLocked(csex) ){
				fprintf( stderr, "\tmain loop waiting for csex lock\n" );
			}
			t0 = HRTime_toc();
			{
#ifdef LOCKSCOPEFG
			  CSEScopedLock *scope = ObtainCSEScopedLock(csex);
#else
			  unsigned char unlock = LockCSEHandle(csex);
#endif
				t1 = HRTime_toc();
				i += 1;
				fprintf( stderr, "> got csex lock #%d=%d at t=%g after %gs; starting %g s wait\n",
						i, IsCSEHandleLocked(csex), t1, t1-t0, SLEEPTIMEFG ); fflush(stderr);
#ifdef BUSYSLEEPING
				MMSleep(SLEEPTIMEFG);
#else
				do{
					t1 = HRTime_toc();
				} while (t1-t0 < SLEEPTIMEFG);
#endif
				fprintf( stderr, "\tmain loop wait #%d ended at t=%gs; csex lock=%d\n",
					i, HRTime_toc(), IsCSEHandleLocked(csex) ); fflush(stderr);
#ifndef LOCKSCOPEFG
				UnlockCSEHandle( csex, unlock );
#else
				scope = ReleaseCSEScopedLock(scope);
#endif
			}
			// just to give the other thread a chance to get a lock:
			Sleep(1);
		}
		fprintf( stderr, "exiting main csex locking loop at t=%gs\n", HRTime_toc() );
		_InterlockedSetFalse(&bgRun);
		WaitForSingleObject( bgThread, 5000 );
		CloseHandle(bgThread);
		fprintf( stderr, "Background loop finished at t=%gs\n", HRTime_toc() );
	}
	else{
		fprintf( stderr, "Failure creating bgCSEXaccess thread\n" );
	}
	DeleteCSEHandle(csex);
	ASSERT(1);
	ASSERT(0);
	exit(0);
}