/* Sample.cpp */ #include "stdafx.h" #include "resource.h" #include "DwordArray.h" extern "C" void __stdcall ClsCash(void); #include "DoReMiFaSort.h" #define WM_ENDOFTHREAD WM_USER + 20 struct ThreadParamStruct { double ExecTime; void *CallAddress; SortRecStruct *Address; size_t RecordCount; CDwordArray *DwordArray; DWORD RepeatCount; DWORD DataType; bool Abort; }; ThreadParamStruct ThreadParam; #ifdef _M_X64 static TCHAR tcAppName[] = TEXT( "ソート比較(64ビット版)" ); #else static TCHAR tcAppName[] = TEXT( "ソート比較(32ビット版)" ); #endif static HICON m_hIcon = NULL; static HWND m_Dlg; static HWND m_DataType; static HWND m_SortType; static HWND m_RecCount; static HWND m_RepeatCount; static HWND m_ExecTime; static HWND m_Exec; static HWND m_Abort; // static HANDLE hThread = NULL; static int nAppResult = 0; // CDwordArray DwordArray; // DWORD WINAPI ThreadProc(LPVOID lpParameter) { typedef DWORD ( __stdcall *SortProc)(SortRecStruct*, size_t, bool*); static const double dblTmFactor = 0.0001; //100.0 / ( 1000.0 * 1000.0 ); // ms 単位 SortProc CallAddress; HANDLE MyThread; double dblSpan; FILETIME dummyC, dummyE, dummyK; UINT64 UserTimeB, UserTimeE; DWORD dwPtr, dwStatus, dwResult = 0; ThreadParamStruct *Param = ( ThreadParamStruct* ) lpParameter; MyThread = GetCurrentThread(); CallAddress = ( SortProc ) Param->CallAddress; for( dwPtr = 0; dwPtr < Param->RepeatCount; dwPtr++ ) { DwordArray.SetData( Param->DataType, Param->RecordCount ); if( DwordArray.m_Status == 0 ) { ClsCash(); GetThreadTimes( MyThread, &dummyC, &dummyE, &dummyK, ( FILETIME* ) &UserTimeB ); dwStatus = ( *CallAddress )( DwordArray.m_Address, Param->RecordCount, &Param->Abort ); GetThreadTimes( MyThread, &dummyC, &dummyE, &dummyK, ( FILETIME* ) &UserTimeE ); dblSpan = ( UserTimeE - UserTimeB ) * dblTmFactor; if( dwPtr ) { if( Param->ExecTime > dblSpan ) Param->ExecTime = dblSpan; } else { Param->ExecTime = dblSpan; } if( dwStatus ) { dwResult = dwStatus; break; } } else dwResult = DwordArray.m_Status; } PostMessage( m_Dlg, WM_ENDOFTHREAD, 0, 0 ); return dwResult; } // static void PutSystemError(HWND hwndDlg, DWORD pErrorCode) { LPVOID lpMsgBuf; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS , NULL, pErrorCode, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) , ( LPTSTR ) &lpMsgBuf, 0, NULL ); if( pErrorCode ) MessageBox( hwndDlg, ( LPCTSTR ) lpMsgBuf, tcAppName, MB_ICONSTOP ); else MessageBox( hwndDlg, ( LPCTSTR ) lpMsgBuf, tcAppName, MB_ICONINFORMATION ); LocalFree( lpMsgBuf ); } // static void CheckData(void) { size_t sztPtr; DWORD dwOld = 0; bool bFlag; ThreadParam.Address = ThreadParam.DwordArray->m_Address; for( bFlag = false, sztPtr = 0; sztPtr < ThreadParam.RecordCount; sztPtr++ ) { if( sztPtr ) { if( dwOld > ThreadParam.Address[ sztPtr ].Key ) bFlag = true; } dwOld = ThreadParam.Address[ sztPtr ].Key; } if( bFlag ) { MessageBox( m_Dlg, TEXT( "ソート結果に誤り" ), tcAppName, MB_ICONSTOP ); } } // void OnExec(void) { TCHAR tcText[ 64 ]; UINT64 unTemp; DWORD dwTemp; size_t sztRecordCount; GetWindowText( m_RepeatCount, tcText, 64 ); unTemp = _tstoi64( tcText ); ThreadParam.RepeatCount = ( DWORD ) unTemp; if( unTemp ) { SetWindowText( m_ExecTime, TEXT( "初期化中" ) ); UpdateWindow( m_ExecTime ); GetWindowText( m_RecCount, tcText, 64 ); unTemp = _tstoi64( tcText ); ThreadParam.RecordCount = sztRecordCount = ( size_t ) unTemp; dwTemp = ( DWORD ) SendMessage( m_DataType, CB_GETCURSEL, 0, 0 ); ThreadParam.DataType = dwTemp; ThreadParam.ExecTime = 0; ThreadParam.Abort = false; GetWindowText( m_RepeatCount, tcText, 64 ); unTemp = _tstoi64( tcText ); dwTemp = ( DWORD ) SendMessage( m_SortType, CB_GETCURSEL, 0, 0 ); ThreadParam.DwordArray = &DwordArray; // SetWindowText( m_ExecTime, TEXT( "ソート中" ) ); switch( dwTemp ) { case 0: // qsort(VC) ThreadParam.CallAddress = qsortVc; hThread = CreateThread( NULL, 0, ThreadProc, &ThreadParam, 0, NULL ); break; case 1: // QuickSort(VC) ThreadParam.CallAddress = QuickSort; hThread = CreateThread( NULL, 0, ThreadProc, &ThreadParam, 0, NULL ); break; case 2: // QuickSort2(VC) ThreadParam.CallAddress = QuickSort2; hThread = CreateThread( NULL, 0, ThreadProc, &ThreadParam, 0, NULL ); break; case 3: // QuickSortP(VC) ThreadParam.CallAddress = QuickSortP; hThread = CreateThread( NULL, 0, ThreadProc, &ThreadParam, 0, NULL ); break; case 4: // DoReMiFaSort(VC) ThreadParam.CallAddress = DoReMiFaSort; hThread = CreateThread( NULL, 0, ThreadProc, &ThreadParam, 0, NULL ); break; } } else { MessageBox( m_Dlg, TEXT( "繰り返し回数がゼロです。" ), tcAppName, MB_ICONINFORMATION ); EnableWindow( m_Exec, TRUE ); EnableWindow( m_Abort, FALSE ); } } void OnInitDialog(HWND hwndDlg) { m_Dlg = hwndDlg; SendMessage( hwndDlg, WM_SETICON, (WPARAM) ICON_BIG, ( LPARAM ) m_hIcon ); SendMessage( hwndDlg, WM_SETICON, (WPARAM) ICON_SMALL, ( LPARAM ) m_hIcon ); // m_DataType = GetDlgItem( hwndDlg, IDC_DATATYPE ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Random32" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Random32R" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Random15" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Random15R" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Forward" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Reverse" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Constant" ) ); SendMessage( m_DataType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "Med Killer" ) ); SendMessage( m_DataType, CB_SETCURSEL, 0, 0 ); // m_SortType = GetDlgItem( hwndDlg, IDC_SORTTYPE ); SendMessage( m_SortType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "qsort(VC)" ) ); SendMessage( m_SortType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "QuickSort(VC)" ) ); SendMessage( m_SortType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "QuickSort2(VC)" ) ); SendMessage( m_SortType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "QuickSortP(VC)" ) ); SendMessage( m_SortType, CB_ADDSTRING, 0, ( LPARAM ) TEXT( "DoReMiFaSort(VC)" ) ); // SendMessage( m_SortType, CB_SETCURSEL, 0, 0 ); // m_RecCount = GetDlgItem( hwndDlg, IDC_RECCOUNT ); SetWindowText( m_RecCount, TEXT( "50000000" ) ); m_RepeatCount = GetDlgItem( hwndDlg, IDC_REPEATCOUNT ); SetWindowText( m_RepeatCount, TEXT( "1" ) ); // m_ExecTime = GetDlgItem( hwndDlg, IDC_EXECTIME ); SetWindowText( m_ExecTime, TEXT( "現在未実施" ) ); // m_Exec = GetDlgItem( hwndDlg, IDC_EXEC ); EnableWindow( m_Exec, TRUE ); m_Abort = GetDlgItem( hwndDlg, IDC_ABORT ); EnableWindow( m_Abort, FALSE ); // #ifdef _M_X64 SetWindowText( hwndDlg, TEXT( "ソート比較(64ビット)" ) ); #else SetWindowText( hwndDlg, TEXT( "ソート比較(32ビット)" ) ); #endif } INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER( lParam ); TCHAR tcText[ 32 ]; DWORD dwStatus; switch( uMsg ) { case WM_COMMAND: switch( LOWORD( wParam ) ) { case IDC_EXEC: EnableWindow( m_Exec, FALSE ); EnableWindow( m_Abort, TRUE ); OnExec(); break; case IDC_ABORT: ThreadParam.Abort = true; SetWindowText( m_ExecTime, TEXT( "中止処理中" ) ); break; case IDC_EXIT: goto ExitProgram; default: return FALSE; } break; case WM_ENDOFTHREAD: do { dwStatus = WaitForSingleObject( hThread, INFINITE ); } while( dwStatus != WAIT_OBJECT_0 ); GetExitCodeThread( hThread, ( DWORD* ) &nAppResult ); CloseHandle( hThread ); hThread = NULL; if( nAppResult ) { SetWindowText( m_ExecTime, TEXT( "エラー" ) ); PutSystemError( hwndDlg, nAppResult ); } else { SetWindowText( m_ExecTime, TEXT( "確認中" ) ); UpdateWindow( m_ExecTime ); CheckData(); _stprintf_s( tcText, TEXT( "%.4f" ), ThreadParam.ExecTime ); SetWindowText( m_ExecTime, tcText ); MessageBox( hwndDlg, TEXT( "ソートが完了しました" ), tcAppName, MB_ICONINFORMATION ); } EnableWindow( m_Exec, TRUE ); EnableWindow( m_Abort, FALSE ); break; case WM_CLOSE: ExitProgram: if( hThread ) { ThreadParam.Abort = true; do { dwStatus = WaitForSingleObject( hThread, INFINITE ); } while( dwStatus != WAIT_OBJECT_0 ); CloseHandle( hThread ); hThread = NULL; } EndDialog( hwndDlg, IDOK ); break; case WM_INITDIALOG: OnInitDialog( hwndDlg ); break; default: return FALSE; } return TRUE; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { UNREFERENCED_PARAMETER( hPrevInstance ); UNREFERENCED_PARAMETER( lpCmdLine ); UNREFERENCED_PARAMETER( nCmdShow ); INT_PTR nStatus; m_hIcon = LoadIcon( hInstance, MAKEINTRESOURCE( IDI_ICON ) ); nStatus = DialogBox( hInstance, MAKEINTRESOURCE( IDD_DIALOG ), NULL, ( DLGPROC ) DialogProc ); switch( nStatus ) { case 0: case -1: nStatus = GetLastError(); break; default: nStatus = 0; } return ( int ) nStatus; }