Пример #1
0
void Server(UT_ARGUMENT arg) {
	serverStarted = true;
	if ( clientStarted )
		UtActivate(utClient);

	for (;;) {
		if (!hasWork) UtDeactivate(); 
		if (end)
			break;
		res = factorial(n);
		hasAnswer = true;
		hasWork = false; 
		UtActivate(utClient);
	}
}
VOID EventSignal (PEVENT Event) {
	if (IsListEmpty(&Event->Waiters)) {
		Event->Signaled = TRUE;
	} else {
		PWAIT_BLOCK WaitBlockPtr =
			CONTAINING_RECORD(RemoveHeadList(&Event->Waiters), WAIT_BLOCK, Link);
		UtActivate(WaitBlockPtr->Thread);
	}
}
Пример #3
0
void Client(UT_ARGUMENT arg) {
	int i;
	long * numbers = (long *)arg;

	clientStarted = true;
	if ( ! serverStarted ) UtDeactivate();
	
	for (i = 0; i < MAX_WORK; i++) {
		n = numbers[i];
		hasWork = true;
		hasAnswer = false; 
		UtActivate(utServer);
		if (!hasAnswer) UtDeactivate(); 
		numbers[i] = res;
	}

	end = true;
	hasWork = true;
	UtActivate(utServer);

}
VOID SignalLatch (PCountDownLatch CountDownLatch) {
	// decrementa o contador interno, desbloqueando todas as threads em espera se este chegar a zero

	if (CountDownLatch->counter == 0) {
	}

	CountDownLatch->counter--;
	if (CountDownLatch->counter == 0) {
		while (!IsListEmpty(&CountDownLatch->Waiters)) {
			PWAIT_BLOCK WaitBlockPtr = CONTAINING_RECORD(RemoveHeadList(&CountDownLatch->Waiters), WAIT_BLOCK, Link);
			UtActivate(WaitBlockPtr->Thread);
		}
	}
}
Пример #5
0
//
// Creates a user thread to run the specified function. The thread is placed
// at the end of the ready queue.
//
HANDLE UtCreate64(UT_FUNCTION Function, UT_ARGUMENT Argument, PUCHAR name, DWORD stacksize) {
	PUTHREAD Thread;

	//
	// Dynamically allocate an instance of UTHREAD and the associated stack.
	//
	Thread = (PUTHREAD)malloc(sizeof(UTHREAD));
	Thread->Name = name;
	Thread->Stack = (PUCHAR)malloc(stacksize);
	//Thread->Stack = (PUCHAR) malloc(STACK_SIZE);
	_ASSERTE(Thread != NULL && Thread->Stack != NULL);

	//
	// Zero the stack for emotional confort.
	//
	//memset(Thread->Stack, 0, STACK_SIZE);
	memset(Thread->Stack, 0, stacksize);
	//
	// Memorize Function and Argument for use in InternalStart.
	//
	Thread->Function = Function;
	Thread->Argument = Argument;
	Thread->State = READY;
	//
	// Map an UTHREAD_CONTEXT instance on the thread's stack.
	// We'll use it to save the initial context of the thread.
	//
	// +------------+  <- Highest word of a thread's stack space
	// | 0x00000000 |    (needs to be set to 0 for Visual Studio to
	// +------------+      correctly present a thread's call stack).   
	// | 0x00000000 |  \
	// +------------+   |
	// | 0x00000000 |   | <-- Shadow Area for Internal Start 
	// +------------+   |
	// | 0x00000000 |   |
	// +------------+   |
	// | 0x00000000 |  /
	// +============+       
	// |  RetAddr   | \    
	// +------------+  |
	// |    RBP     |  |
	// +------------+  |
	// |    RBX     |   >   Thread->ThreadContext mapped on the stack.
	// +------------+  |
	// |    RDI     |  |
	// +------------+  |
	// |    RSI     |  |
	// +------------+  |
	// |    R12     |  |
	// +------------+  |
	// |    R13     |  |
	// +------------+  |
	// |    R14     |  |
	// +------------+  |
	// |    R15     | /  <- The stack pointer will be set to this address
	// +============+       at the next context switch to this thread.
	// |            | \
	// +------------+  |
	// |     :      |  |
	//       :          >   Remaining stack space.
	// |     :      |  |
	// +------------+  |
	// |            | /  <- Lowest word of a thread's stack space
	// +------------+       (Thread->Stack always points to this location).
	//

	Thread->ThreadContext = (PUTHREAD_CONTEXT)(Thread->Stack +
		STACK_SIZE - sizeof(UTHREAD_CONTEXT) - sizeof(ULONGLONG) * 5);

	//
	// Set the thread's initial context by initializing the values of 
	// registers that must be saved by the called (R15,R14,R13,R12, RSI, RDI, RBCX, RBP)

	// 
	// Upon the first context switch to this thread, after popping the dummy
	// values of the "saved" registers, a ret instruction will place the
	// address of InternalStart on EIP.
	//
	Thread->ThreadContext->R15 = 0x77777777;
	Thread->ThreadContext->R14 = 0x66666666;
	Thread->ThreadContext->R13 = 0x55555555;
	Thread->ThreadContext->R12 = 0x44444444;
	Thread->ThreadContext->RSI = 0x33333333;
	Thread->ThreadContext->RDI = 0x11111111;
	Thread->ThreadContext->RBX = 0x22222222;
	Thread->ThreadContext->RBP = 0x11111111;
	Thread->ThreadContext->RetAddr = InternalStart;
	InitializeListHead(&Thread->Joiners);
	InsertTailList(&AliveThreads, &Thread->alive);
	//
	// Ready the thread.
	//
	NumberOfThreads += 1;
	UtActivate((HANDLE)Thread);

	return (HANDLE)Thread;
}
Пример #6
0
//
// Creates a user thread to run the specified function. The thread is placed
// at the end of the ready queue.
//
HANDLE UtCreate32(UT_FUNCTION Function, UT_ARGUMENT Argument, PUCHAR name, DWORD stacksize) {
	PUTHREAD Thread;

	//
	// Dynamically allocate an instance of UTHREAD and the associated stack.
	//
	Thread = (PUTHREAD)malloc(sizeof(UTHREAD));
	Thread->Name = name;
	//Thread->Stack = (PUCHAR) malloc(STACK_SIZE);
	Thread->Stack = (PUCHAR)malloc(stacksize);
	_ASSERTE(Thread != NULL && Thread->Stack != NULL);

	//
	// Zero the stack for emotional confort.
	//
	//memset(Thread->Stack, 0, STACK_SIZE);
	memset(Thread->Stack, 0, stacksize);
	//
	// Memorize Function and Argument for use in InternalStart.
	//
	Thread->Function = Function;
	Thread->Argument = Argument;

	//
	// Map an UTHREAD_CONTEXT instance on the thread's stack.
	// We'll use it to save the initial context of the thread.
	//
	// +------------+
	// | 0x00000000 |    <- Highest word of a thread's stack space
	// +============+       (needs to be set to 0 for Visual Studio to
	// |  RetAddr   | \     correctly present a thread's call stack).
	// +------------+  |
	// |    EBP     |  |
	// +------------+  |
	// |    EBX     |   >   Thread->ThreadContext mapped on the stack.
	// +------------+  |
	// |    ESI     |  |
	// +------------+  |
	// |    EDI     | /  <- The stack pointer will be set to this address
	// +============+       at the next context switch to this thread.
	// |            | \
	// +------------+  |
	// |     :      |  |
	//       :          >   Remaining stack space.
	// |     :      |  |
	// +------------+  |
	// |            | /  <- Lowest word of a thread's stack space
	// +------------+       (Thread->Stack always points to this location).
	//

	/*Thread->ThreadContext = (PUTHREAD_CONTEXT) (Thread->Stack +
		STACK_SIZE - sizeof (ULONG) - sizeof (UTHREAD_CONTEXT));*/
	Thread->ThreadContext = (PUTHREAD_CONTEXT)(Thread->Stack +
		stacksize - sizeof(ULONG) - sizeof(UTHREAD_CONTEXT));
	//
	// Set the thread's initial context by initializing the values of EDI,
	// EBX, ESI and EBP (must be zero for Visual Studio to correctly present
	// a thread's call stack) and by hooking the return address.
	// 
	// Upon the first context switch to this thread, after popping the dummy
	// values of the "saved" registers, a ret instruction will place the
	// address of InternalStart on EIP.
	//
	Thread->ThreadContext->EDI = 0x33333333;
	Thread->ThreadContext->EBX = 0x11111111;
	Thread->ThreadContext->ESI = 0x22222222;
	Thread->ThreadContext->EBP = 0x00000000;
	Thread->ThreadContext->RetAddr = InternalStart;
	//initialize joiners
	InitializeListHead(&Thread->Joiners);
	InsertTailList(&AliveThreads, &Thread->alive);
	//
	// Ready the thread.
	//
	NumberOfThreads += 1;
	Thread->State = READY;
	UtActivate((HANDLE)Thread);


	return (HANDLE)Thread;
}