void *pe_func(void *arg) { thread_context *ptr = (thread_context*)arg; PEContext *pe_env = GET_THREAD_DATA(arg); CUContext *master = pe_env->master_cu_env; pthread_mutex_lock(&pe_env->mutx); // setting global var cvtFidToDIM3(&pe_env->workitem_id, pe_env->workitem_Fid, &master->exec_task->workgroup_size); pre_thread_ptr = ptr; pre_pe_env = pe_env; if (pe_env->kernel) { gotoCodeCache(master->sim_barrier); } else { pthread_mutex_unlock(&pe_env->mutx); return NULL; } //pthread_barrier_wait(pe_env->barrier_ptr); //fprintf(stderr, "pe %p finish, workitem id %4d\n", // (void*)pe_env->id, // pe_env->workitem_Fid); pthread_mutex_lock(&master->wakeup_pe_mutx); master->wavefront_count++; master->workgroup_count++; if (master->wavefront_count == pe_env->max_wavefront_count) { // reset counter, and signal cu master->wavefront_count = 0; pthread_cond_signal(&master->wakeup_pe_cond); //fprintf(stderr, "pe %p signal, workitem id %4d\n", // (void*)pe_env->id, // pe_env->workitem_Fid); } pthread_mutex_unlock(&master->wakeup_pe_mutx); pthread_mutex_unlock(&pe_env->mutx); return NULL; }
BOOL SockInitialize ( IN PVOID DllHandle, IN ULONG Reason, IN PVOID Context OPTIONAL ) { NTSTATUS status; SYSTEM_INFO systemInfo; // // On a thread detach, set up the context param so that all // necessary deallocations will occur. // if ( Reason == DLL_THREAD_DETACH ) { Context = NULL; } switch ( Reason ) { case DLL_PROCESS_ATTACH: SockModuleHandle = (HMODULE)DllHandle; #if DBG // // If there is a file in the current directory called "wsdebug" // open it and read the first line to set the debugging flags. // { HANDLE handle; handle = CreateFile( "WsDebug", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if( handle == INVALID_HANDLE_VALUE ) { // // Set default value. // WsDebug = WINSOCK_DEBUG_DEBUGGER; } else { CHAR buffer[11]; DWORD bytesRead; RtlZeroMemory( buffer, sizeof(buffer) ); if ( ReadFile( handle, buffer, 10, &bytesRead, NULL ) ) { buffer[bytesRead] = '\0'; WsDebug = strtoul( buffer, NULL, 16 ); } else { WS_PRINT(( "read file failed: %ld\n", GetLastError( ) )); } CloseHandle( handle ); } } #endif IF_DEBUG(INIT) { WS_PRINT(( "SockInitialize: process attach, PEB = %lx\n", NtCurrentPeb( ) )); } // // Initialize the lists of sockets and helper DLLs. // InitializeListHead( &SockHelperDllListHead ); InitializeListHead( &SocketListHead ); // // Initialize the global post routine pointer. We have to do it // here rather than statically because it otherwise won't be // thunked correctly. // SockPostRoutine = PostMessage; // // *** lock acquisition order: it is legal to acquire SocketLock // while holding an individual socket lock, but not the other way // around! // InitializeCriticalSection( &SocketLock ); InitializeCriticalSection( &csRnRLock); #if !defined(USE_TEB_FIELD) // // Allocate space in TLS so that we can convert global variables // to thread variables. // SockTlsSlot = TlsAlloc( ); if ( SockTlsSlot == 0xFFFFFFFF ) { WS_PRINT(( "SockInitialize: TlsAlloc failed: %ld\n", GetLastError( ) )); DeleteCriticalSection( &SocketLock ); DeleteCriticalSection( &csRnRLock ); return FALSE; } #endif // !USE_TEB_FIELD // // Create private WinSock heap on MP machines. UP machines // just use the process heap. // GetSystemInfo( &systemInfo ); if( systemInfo.dwNumberOfProcessors > 1 ) { SockPrivateHeap = RtlCreateHeap( HEAP_GROWABLE | // Flags HEAP_CLASS_1, NULL, // HeapBase 0, // ReserveSize 0, // CommitSize NULL, // Lock NULL ); // Parameters } else { WS_ASSERT( SockPrivateHeap == NULL ); } if ( SockPrivateHeap == NULL ) { // // This is either a UP box, or RtlCreateHeap() failed. In // either case, just use the process heap. // SockPrivateHeap = RtlProcessHeap(); } break; case DLL_PROCESS_DETACH: IF_DEBUG(INIT) { WS_PRINT(( "SockInitialize: process detach, PEB = %lx\n", NtCurrentPeb( ) )); } // // Only clean up resources if we're being called because of a // FreeLibrary(). If this is because of process termination, // do not clean up, as the system will do it for us. Also, // if we get called at process termination, it is likely that // a thread was terminated while it held a winsock lock, which // would cause a deadlock if we then tried to grab the lock. // if ( Context == NULL ) { WSACleanup( ); GetHostCleanup(); DeleteCriticalSection( &SocketLock ); DeleteCriticalSection( &csRnRLock ); } SockProcessTerminating = TRUE; // *** lack of break is intentional! case DLL_THREAD_DETACH: IF_DEBUG(INIT) { WS_PRINT(( "SockInitialize: thread detach, TEB = %lx\n", NtCurrentTeb( ) )); } // // If the TLS information for this thread has been initialized, // free the thread data buffer. // if ( Context == NULL && GET_THREAD_DATA() != NULL ) { FREE_HEAP( GET_THREAD_DATA() ); SET_THREAD_DATA( NULL ); } // // If this is a process detach, free the TLS slot we're using. // if ( Reason == DLL_PROCESS_DETACH && Context == NULL ) { #if !defined(USE_TEB_FIELD) if ( SockTlsSlot != 0xFFFFFFFF ) { BOOLEAN ret; ret = TlsFree( SockTlsSlot ); WS_ASSERT( ret ); SockTlsSlot = 0xFFFFFFFF; } #endif // !USE_TEB_FIELD // // Also destroy any private WinSock heap. // if ( SockPrivateHeap != RtlProcessHeap() ) { WS_ASSERT( SockPrivateHeap != NULL ); RtlDestroyHeap( SockPrivateHeap ); SockPrivateHeap = NULL; } } break; case DLL_THREAD_ATTACH: break; default: WS_ASSERT( FALSE ); break; } return TRUE; } // SockInitialize
char * PASCAL inet_ntoa( IN struct in_addr in ) /*++ Routine Description: This function takes an Internet address structure specified by the in parameter. It returns an ASCII string representing the address in ".'' notation as "a.b.c.d". Note that the string returned by inet_ntoa() resides in memory which is allocated by the Windows Sockets implementation. The application should not make any assumptions about the way in which the memory is allocated. The data is guaranteed to be valid until the next Windows Sockets API call within the same thread, but no longer. Arguments: in - A structure which represents an Internet host address. Return Value: If no error occurs, inet_ntoa() returns a char pointer to a static buffer containing the text address in standard "." notation. Otherwise, it returns NULL. The data should be copied before another Windows Sockets call is made. --*/ { PUCHAR p; PUCHAR buffer; PUCHAR b; WS_ENTER( "inet_ntoa", (PVOID)in.s_addr, NULL, NULL, NULL ); // // A number of applications apparently depend on calling inet_ntoa() // without first calling WSAStartup(). Because of this, we must perform // our own explicit thread initialization check here. // if( GET_THREAD_DATA() == NULL ) { if( !SockThreadInitialize() ) { SetLastError( WSAENOBUFS ); WS_EXIT( "inet_ntoa", (INT)NULL, TRUE ); return NULL; } } WS_ASSERT( GET_THREAD_DATA() != NULL ); buffer = INTOA_Buffer; b = buffer; // // In an unrolled loop, calculate the string value for each of the four // bytes in an IP address. Note that for values less than 100 we will // do one or two extra assignments, but we save a test/jump with this // algorithm. // p = (PUCHAR)∈ *b = NToACharStrings[*p][0]; *(b+1) = NToACharStrings[*p][1]; *(b+2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b+1) = NToACharStrings[*p][1]; *(b+2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b+1) = NToACharStrings[*p][1]; *(b+2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b++ = '.'; p++; *b = NToACharStrings[*p][0]; *(b+1) = NToACharStrings[*p][1]; *(b+2) = NToACharStrings[*p][2]; b += NToACharStrings[*p][3]; *b = '\0'; WS_EXIT( "inet_ntoa", (INT)INTOA_Buffer, FALSE ); return(buffer); }