Imported Upstream version 9.20
[platform/upstream/7zip.git] / CPP / 7zip / UI / GUI / BenchmarkDialog.cpp
1 // BenchmarkDialog.cpp\r
2 \r
3 #include "StdAfx.h"\r
4 \r
5 #include "Common/IntToString.h"\r
6 #include "Common/MyException.h"\r
7 \r
8 #include "Windows/Error.h"\r
9 #include "Windows/System.h"\r
10 #include "Windows/Thread.h"\r
11 \r
12 #include "../FileManager/HelpUtils.h"\r
13 \r
14 #include "BenchmarkDialog.h"\r
15 \r
16 using namespace NWindows;\r
17 \r
18 static LPCWSTR kHelpTopic = L"fm/benchmark.htm";\r
19 \r
20 static const UINT_PTR kTimerID = 4;\r
21 static const UINT kTimerElapse = 1000;\r
22 \r
23 #ifdef LANG\r
24 #include "../FileManager/LangUtils.h"\r
25 #endif\r
26 \r
27 using namespace NWindows;\r
28 \r
29 UString HResultToMessage(HRESULT errorCode);\r
30 \r
31 #ifdef LANG\r
32 static CIDLangPair kIDLangPairs[] =\r
33 {\r
34   { IDC_BENCHMARK_DICTIONARY, 0x02000D0C },\r
35   { IDC_BENCHMARK_MEMORY, 0x03080001 },\r
36   { IDC_BENCHMARK_NUM_THREADS, 0x02000D12 },\r
37   { IDC_BENCHMARK_SPEED_LABEL, 0x03080004 },\r
38   { IDC_BENCHMARK_RATING_LABEL, 0x03080005 },\r
39   { IDC_BENCHMARK_COMPRESSING, 0x03080002 },\r
40   { IDC_BENCHMARK_DECOMPRESSING, 0x03080003 },\r
41   { IDC_BENCHMARK_CURRENT, 0x03080007 },\r
42   { IDC_BENCHMARK_RESULTING, 0x03080008 },\r
43   { IDC_BENCHMARK_CURRENT2, 0x03080007 },\r
44   { IDC_BENCHMARK_RESULTING2, 0x03080008 },\r
45   { IDC_BENCHMARK_TOTAL_RATING, 0x03080006 },\r
46   { IDC_BENCHMARK_ELAPSED, 0x02000C01 },\r
47   { IDC_BENCHMARK_SIZE, 0x02000C03 },\r
48   { IDC_BENCHMARK_PASSES, 0x03080009 },\r
49   // { IDC_BENCHMARK_ERRORS, 0x0308000A },\r
50   { IDC_BENCHMARK_USAGE_LABEL, 0x0308000B },\r
51   { IDC_BENCHMARK_RPU_LABEL, 0x0308000C },\r
52   { IDC_BENCHMARK_COMBO_NUM_THREADS, 0x02000D12},\r
53  \r
54   { IDC_BUTTON_STOP, 0x02000714 },\r
55   { IDC_BUTTON_RESTART, 0x02000715 },\r
56   { IDHELP, 0x02000720 },\r
57   { IDCANCEL, 0x02000710 }\r
58 };\r
59 #endif\r
60 \r
61 const LPCTSTR kProcessingString = TEXT("...");\r
62 const LPCTSTR kMB = TEXT(" MB");\r
63 const LPCTSTR kMIPS =  TEXT(" MIPS");\r
64 const LPCTSTR kKBs = TEXT(" KB/s");\r
65 \r
66 #ifdef UNDER_CE\r
67 static const int kMinDicLogSize = 20;\r
68 #else\r
69 static const int kMinDicLogSize = 21;\r
70 #endif\r
71 static const UInt32 kMinDicSize = (1 << kMinDicLogSize);\r
72 static const UInt32 kMaxDicSize =\r
73     #ifdef _WIN64\r
74     (1 << 30);\r
75     #else\r
76     (1 << 27);\r
77     #endif\r
78 \r
79 bool CBenchmarkDialog::OnInit()\r
80 {\r
81   #ifdef LANG\r
82   LangSetWindowText(HWND(*this), 0x03080000);\r
83   LangSetDlgItemsText(HWND(*this), kIDLangPairs, sizeof(kIDLangPairs) / sizeof(kIDLangPairs[0]));\r
84   #endif\r
85 \r
86   Sync.Init();\r
87 \r
88 \r
89   UInt32 numCPUs = NSystem::GetNumberOfProcessors();\r
90   if (numCPUs < 1)\r
91     numCPUs = 1;\r
92   numCPUs = MyMin(numCPUs, (UInt32)(1 << 8));\r
93 \r
94   if (Sync.NumThreads == (UInt32)-1)\r
95   {\r
96     Sync.NumThreads = numCPUs;\r
97     if (Sync.NumThreads > 1)\r
98       Sync.NumThreads &= ~1;\r
99   }\r
100   m_NumThreads.Attach(GetItem(IDC_BENCHMARK_COMBO_NUM_THREADS));\r
101   int cur = 0;\r
102   for (UInt32 num = 1; num <= numCPUs * 2;)\r
103   {\r
104     TCHAR s[40];\r
105     ConvertUInt64ToString(num, s);\r
106     int index = (int)m_NumThreads.AddString(s);\r
107     m_NumThreads.SetItemData(index, num);\r
108     if (num <= Sync.NumThreads)\r
109       cur = index;\r
110     if (num > 1)\r
111       num++;\r
112     num++;\r
113   }\r
114   m_NumThreads.SetCurSel(cur);\r
115   Sync.NumThreads = GetNumberOfThreads();\r
116 \r
117   m_Dictionary.Attach(GetItem(IDC_BENCHMARK_COMBO_DICTIONARY));\r
118   cur = 0;\r
119   UInt64 ramSize = NSystem::GetRamSize();\r
120   \r
121   #ifdef UNDER_CE\r
122   const UInt32 kNormalizedCeSize = (16 << 20);\r
123   if (ramSize > kNormalizedCeSize && ramSize < (33 << 20))\r
124     ramSize = kNormalizedCeSize;\r
125   #endif\r
126 \r
127   if (Sync.DictionarySize == (UInt32)-1)\r
128   {\r
129     int dicSizeLog;\r
130     for (dicSizeLog = 25; dicSizeLog > kBenchMinDicLogSize; dicSizeLog--)\r
131       if (GetBenchMemoryUsage(Sync.NumThreads, ((UInt32)1 << dicSizeLog)) + (8 << 20) <= ramSize)\r
132         break;\r
133     Sync.DictionarySize = (1 << dicSizeLog);\r
134   }\r
135   if (Sync.DictionarySize < kMinDicSize)\r
136     Sync.DictionarySize = kMinDicSize;\r
137   if (Sync.DictionarySize > kMaxDicSize)\r
138     Sync.DictionarySize = kMaxDicSize;\r
139 \r
140   for (int i = kMinDicLogSize; i <= 30; i++)\r
141     for (int j = 0; j < 2; j++)\r
142     {\r
143       UInt32 dictionary = (1 << i) + (j << (i - 1));\r
144       if (dictionary > kMaxDicSize)\r
145         continue;\r
146       TCHAR s[40];\r
147       ConvertUInt64ToString((dictionary >> 20), s);\r
148       lstrcat(s, kMB);\r
149       int index = (int)m_Dictionary.AddString(s);\r
150       m_Dictionary.SetItemData(index, dictionary);\r
151       if (dictionary <= Sync.DictionarySize)\r
152         cur = index;\r
153     }\r
154   m_Dictionary.SetCurSel(cur);\r
155 \r
156   OnChangeSettings();\r
157 \r
158   Sync._startEvent.Set();\r
159   _timer = SetTimer(kTimerID, kTimerElapse);\r
160 \r
161   NormalizePosition();\r
162   return CModalDialog::OnInit();\r
163 }\r
164 \r
165 UInt32 CBenchmarkDialog::GetNumberOfThreads()\r
166 {\r
167   return (UInt32)m_NumThreads.GetItemData(m_NumThreads.GetCurSel());\r
168 }\r
169 \r
170 UInt32 CBenchmarkDialog::OnChangeDictionary()\r
171 {\r
172   UInt32 dictionary = (UInt32)m_Dictionary.GetItemData(m_Dictionary.GetCurSel());\r
173   UInt64 memUsage = GetBenchMemoryUsage(GetNumberOfThreads(), dictionary);\r
174   memUsage = (memUsage + (1 << 20) - 1) >> 20;\r
175   TCHAR s[40];\r
176   ConvertUInt64ToString(memUsage, s);\r
177   lstrcat(s, kMB);\r
178   SetItemText(IDC_BENCHMARK_MEMORY_VALUE, s);\r
179   return dictionary;\r
180 }\r
181 \r
182 static const UInt32 g_IDs[] =\r
183 {\r
184   IDC_BENCHMARK_COMPRESSING_USAGE,\r
185   IDC_BENCHMARK_COMPRESSING_USAGE2,\r
186   IDC_BENCHMARK_COMPRESSING_SPEED,\r
187   IDC_BENCHMARK_COMPRESSING_SPEED2,\r
188   IDC_BENCHMARK_COMPRESSING_RATING,\r
189   IDC_BENCHMARK_COMPRESSING_RATING2,\r
190   IDC_BENCHMARK_COMPRESSING_RPU,\r
191   IDC_BENCHMARK_COMPRESSING_RPU2,\r
192   \r
193   IDC_BENCHMARK_DECOMPRESSING_SPEED,\r
194   IDC_BENCHMARK_DECOMPRESSING_SPEED2,\r
195   IDC_BENCHMARK_DECOMPRESSING_RATING,\r
196   IDC_BENCHMARK_DECOMPRESSING_RATING2,\r
197   IDC_BENCHMARK_DECOMPRESSING_USAGE,\r
198   IDC_BENCHMARK_DECOMPRESSING_USAGE2,\r
199   IDC_BENCHMARK_DECOMPRESSING_RPU,\r
200   IDC_BENCHMARK_DECOMPRESSING_RPU2,\r
201   \r
202   IDC_BENCHMARK_TOTAL_USAGE_VALUE,\r
203   IDC_BENCHMARK_TOTAL_RATING_VALUE,\r
204   IDC_BENCHMARK_TOTAL_RPU_VALUE\r
205 };\r
206   \r
207 void CBenchmarkDialog::OnChangeSettings()\r
208 {\r
209   EnableItem(IDC_BUTTON_STOP, true);\r
210   UInt32 dictionary = OnChangeDictionary();\r
211   TCHAR s[40] = { TEXT('/'), TEXT(' '), 0 };\r
212   ConvertUInt64ToString(NSystem::GetNumberOfProcessors(), s + 2);\r
213   SetItemText(IDC_BENCHMARK_HARDWARE_THREADS, s);\r
214   for (int i = 0; i < sizeof(g_IDs) / sizeof(g_IDs[0]); i++)\r
215     SetItemText(g_IDs[i], kProcessingString);\r
216   _startTime = GetTickCount();\r
217   PrintTime();\r
218   NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS);\r
219   Sync.Init();\r
220   Sync.DictionarySize = dictionary;\r
221   Sync.Changed = true;\r
222   Sync.NumThreads = GetNumberOfThreads();\r
223 }\r
224 \r
225 void CBenchmarkDialog::OnRestartButton()\r
226 {\r
227   OnChangeSettings();\r
228 }\r
229 \r
230 void CBenchmarkDialog::OnStopButton()\r
231 {\r
232   EnableItem(IDC_BUTTON_STOP, false);\r
233   Sync.Pause();\r
234 }\r
235 \r
236 void CBenchmarkDialog::OnHelp()\r
237 {\r
238   ShowHelpWindow(NULL, kHelpTopic);\r
239 }\r
240 \r
241 void CBenchmarkDialog::OnCancel()\r
242 {\r
243   Sync.Stop();\r
244   KillTimer(_timer);\r
245   CModalDialog::OnCancel();\r
246 }\r
247 \r
248 static void GetTimeString(UInt64 timeValue, TCHAR *s)\r
249 {\r
250   wsprintf(s, TEXT("%02d:%02d:%02d"),\r
251       UInt32(timeValue / 3600),\r
252       UInt32((timeValue / 60) % 60),\r
253       UInt32(timeValue % 60));\r
254 }\r
255 \r
256 void CBenchmarkDialog::PrintTime()\r
257 {\r
258   UInt32 curTime = ::GetTickCount();\r
259   UInt32 elapsedTime = (curTime - _startTime);\r
260   UInt32 elapsedSec = elapsedTime / 1000;\r
261   if (elapsedSec != 0 && Sync.WasPaused())\r
262     return;\r
263   TCHAR s[40];\r
264   GetTimeString(elapsedSec, s);\r
265   SetItemText(IDC_BENCHMARK_ELAPSED_VALUE, s);\r
266 }\r
267 \r
268 void CBenchmarkDialog::PrintRating(UInt64 rating, UINT controlID)\r
269 {\r
270   TCHAR s[40];\r
271   ConvertUInt64ToString(rating / 1000000, s);\r
272   lstrcat(s, kMIPS);\r
273   SetItemText(controlID, s);\r
274 }\r
275 \r
276 void CBenchmarkDialog::PrintUsage(UInt64 usage, UINT controlID)\r
277 {\r
278   TCHAR s[40];\r
279   ConvertUInt64ToString((usage + 5000) / 10000, s);\r
280   lstrcat(s, TEXT("%"));\r
281   SetItemText(controlID, s);\r
282 }\r
283 \r
284 void CBenchmarkDialog::PrintResults(\r
285     UInt32 dictionarySize,\r
286     const CBenchInfo2 &info,\r
287     UINT usageID, UINT speedID, UINT rpuID, UINT ratingID,\r
288     bool decompressMode)\r
289 {\r
290   if (info.GlobalTime == 0)\r
291     return;\r
292 \r
293   UInt64 size = info.UnpackSize;\r
294   TCHAR s[40];\r
295   {\r
296     UInt64 speed = size * info.GlobalFreq / info.GlobalTime;\r
297     ConvertUInt64ToString(speed / 1024, s);\r
298     lstrcat(s, kKBs);\r
299     SetItemText(speedID, s);\r
300   }\r
301   UInt64 rating;\r
302   if (decompressMode)\r
303     rating = GetDecompressRating(info.GlobalTime, info.GlobalFreq, size, info.PackSize, 1);\r
304   else\r
305     rating = GetCompressRating(dictionarySize, info.GlobalTime, info.GlobalFreq, size * info.NumIterations);\r
306 \r
307   PrintRating(rating, ratingID);\r
308   PrintRating(GetRatingPerUsage(info, rating), rpuID);\r
309   PrintUsage(GetUsage(info), usageID);\r
310 }\r
311 \r
312 bool CBenchmarkDialog::OnTimer(WPARAM /* timerID */, LPARAM /* callback */)\r
313 {\r
314   PrintTime();\r
315   NWindows::NSynchronization::CCriticalSectionLock lock(Sync.CS);\r
316 \r
317   TCHAR s[40];\r
318   ConvertUInt64ToString((Sync.ProcessedSize >> 20), s);\r
319   lstrcat(s, kMB);\r
320   SetItemText(IDC_BENCHMARK_SIZE_VALUE, s);\r
321 \r
322   ConvertUInt64ToString(Sync.NumPasses, s);\r
323   SetItemText(IDC_BENCHMARK_PASSES_VALUE, s);\r
324 \r
325   /*\r
326   ConvertUInt64ToString(Sync.NumErrors, s);\r
327   SetItemText(IDC_BENCHMARK_ERRORS_VALUE, s);\r
328   */\r
329 \r
330   {\r
331     UInt32 dicSizeTemp = (UInt32)MyMax(Sync.ProcessedSize, UInt64(1) << 20);\r
332     dicSizeTemp = MyMin(dicSizeTemp, Sync.DictionarySize),\r
333     PrintResults(dicSizeTemp,\r
334       Sync.CompressingInfoTemp,\r
335       IDC_BENCHMARK_COMPRESSING_USAGE,\r
336       IDC_BENCHMARK_COMPRESSING_SPEED,\r
337       IDC_BENCHMARK_COMPRESSING_RPU,\r
338       IDC_BENCHMARK_COMPRESSING_RATING);\r
339   }\r
340 \r
341   {\r
342     PrintResults(\r
343       Sync.DictionarySize,\r
344       Sync.CompressingInfo,\r
345       IDC_BENCHMARK_COMPRESSING_USAGE2,\r
346       IDC_BENCHMARK_COMPRESSING_SPEED2,\r
347       IDC_BENCHMARK_COMPRESSING_RPU2,\r
348       IDC_BENCHMARK_COMPRESSING_RATING2);\r
349   }\r
350 \r
351   {\r
352     PrintResults(\r
353       Sync.DictionarySize,\r
354       Sync.DecompressingInfoTemp,\r
355       IDC_BENCHMARK_DECOMPRESSING_USAGE,\r
356       IDC_BENCHMARK_DECOMPRESSING_SPEED,\r
357       IDC_BENCHMARK_DECOMPRESSING_RPU,\r
358       IDC_BENCHMARK_DECOMPRESSING_RATING,\r
359       true);\r
360   }\r
361   {\r
362     PrintResults(\r
363       Sync.DictionarySize,\r
364       Sync.DecompressingInfo,\r
365       IDC_BENCHMARK_DECOMPRESSING_USAGE2,\r
366       IDC_BENCHMARK_DECOMPRESSING_SPEED2,\r
367       IDC_BENCHMARK_DECOMPRESSING_RPU2,\r
368       IDC_BENCHMARK_DECOMPRESSING_RATING2,\r
369       true);\r
370     if (Sync.DecompressingInfo.GlobalTime > 0 &&\r
371         Sync.CompressingInfo.GlobalTime > 0)\r
372     {\r
373       UInt64 comprRating = GetCompressRating(Sync.DictionarySize,\r
374           Sync.CompressingInfo.GlobalTime, Sync.CompressingInfo.GlobalFreq, Sync.CompressingInfo.UnpackSize);\r
375       UInt64 decomprRating = GetDecompressRating(Sync.DecompressingInfo.GlobalTime,\r
376           Sync.DecompressingInfo.GlobalFreq, Sync.DecompressingInfo.UnpackSize,\r
377           Sync.DecompressingInfo.PackSize, 1);\r
378       PrintRating((comprRating + decomprRating) / 2, IDC_BENCHMARK_TOTAL_RATING_VALUE);\r
379       PrintRating((\r
380           GetRatingPerUsage(Sync.CompressingInfo, comprRating) +\r
381           GetRatingPerUsage(Sync.DecompressingInfo, decomprRating)) / 2, IDC_BENCHMARK_TOTAL_RPU_VALUE);\r
382       PrintUsage((GetUsage(Sync.CompressingInfo) + GetUsage(Sync.DecompressingInfo)) / 2, IDC_BENCHMARK_TOTAL_USAGE_VALUE);\r
383     }\r
384   }\r
385   return true;\r
386 }\r
387 \r
388 bool CBenchmarkDialog::OnCommand(int code, int itemID, LPARAM lParam)\r
389 {\r
390   if (code == CBN_SELCHANGE &&\r
391       (itemID == IDC_BENCHMARK_COMBO_DICTIONARY ||\r
392        itemID == IDC_BENCHMARK_COMBO_NUM_THREADS))\r
393   {\r
394     OnChangeSettings();\r
395     return true;\r
396   }\r
397   return CModalDialog::OnCommand(code, itemID, lParam);\r
398 }\r
399 \r
400 bool CBenchmarkDialog::OnButtonClicked(int buttonID, HWND buttonHWND)\r
401 {\r
402   switch(buttonID)\r
403   {\r
404     case IDC_BUTTON_RESTART:\r
405       OnRestartButton();\r
406       return true;\r
407     case IDC_BUTTON_STOP:\r
408       OnStopButton();\r
409       return true;\r
410   }\r
411   return CModalDialog::OnButtonClicked(buttonID, buttonHWND);\r
412 }\r
413 \r
414 struct CThreadBenchmark\r
415 {\r
416   CBenchmarkDialog *BenchmarkDialog;\r
417   UInt64 _startTime;\r
418   DECL_EXTERNAL_CODECS_VARS\r
419   // UInt32 dictionarySize;\r
420   // UInt32 numThreads;\r
421 \r
422   HRESULT Process();\r
423   HRESULT Result;\r
424   static THREAD_FUNC_DECL MyThreadFunction(void *param)\r
425   {\r
426     ((CThreadBenchmark *)param)->Result = ((CThreadBenchmark *)param)->Process();\r
427     return 0;\r
428   }\r
429 };\r
430 \r
431 struct CBenchCallback: public IBenchCallback\r
432 {\r
433   UInt32 dictionarySize;\r
434   CProgressSyncInfo *Sync;\r
435   HRESULT SetEncodeResult(const CBenchInfo &info, bool final);\r
436   HRESULT SetDecodeResult(const CBenchInfo &info, bool final);\r
437 };\r
438 \r
439 HRESULT CBenchCallback::SetEncodeResult(const CBenchInfo &info, bool final)\r
440 {\r
441   NSynchronization::CCriticalSectionLock lock(Sync->CS);\r
442   if (Sync->Changed || Sync->Paused || Sync->Stopped)\r
443     return E_ABORT;\r
444   Sync->ProcessedSize = info.UnpackSize;\r
445   if (final && Sync->CompressingInfo.GlobalTime == 0)\r
446   {\r
447     (CBenchInfo&)Sync->CompressingInfo = info;\r
448     if (Sync->CompressingInfo.GlobalTime == 0)\r
449       Sync->CompressingInfo.GlobalTime = 1;\r
450   }\r
451   else\r
452     (CBenchInfo&)Sync->CompressingInfoTemp = info;\r
453 \r
454   return S_OK;\r
455 }\r
456 \r
457 HRESULT CBenchCallback::SetDecodeResult(const CBenchInfo &info, bool final)\r
458 {\r
459   NSynchronization::CCriticalSectionLock lock(Sync->CS);\r
460   if (Sync->Changed || Sync->Paused || Sync->Stopped)\r
461     return E_ABORT;\r
462   CBenchInfo info2 = info;\r
463   if (info2.NumIterations == 0)\r
464     info2.NumIterations = 1;\r
465 \r
466   info2.UnpackSize *= info2.NumIterations;\r
467   info2.PackSize *= info2.NumIterations;\r
468   info2.NumIterations = 1;\r
469 \r
470   if (final && Sync->DecompressingInfo.GlobalTime == 0)\r
471   {\r
472     (CBenchInfo&)Sync->DecompressingInfo = info2;\r
473     if (Sync->DecompressingInfo.GlobalTime == 0)\r
474       Sync->DecompressingInfo.GlobalTime = 1;\r
475   }\r
476   else\r
477     (CBenchInfo&)Sync->DecompressingInfoTemp = info2;\r
478   return S_OK;\r
479 }\r
480 \r
481 HRESULT CThreadBenchmark::Process()\r
482 {\r
483   CProgressSyncInfo &sync = BenchmarkDialog->Sync;\r
484   sync.WaitCreating();\r
485   try\r
486   {\r
487     for (;;)\r
488     {\r
489       if (sync.WasStopped())\r
490         return 0;\r
491       if (sync.WasPaused())\r
492       {\r
493         Sleep(200);\r
494         continue;\r
495       }\r
496       UInt32 dictionarySize;\r
497       UInt32 numThreads;\r
498       {\r
499         NSynchronization::CCriticalSectionLock lock(sync.CS);\r
500         if (sync.Stopped || sync.Paused)\r
501           continue;\r
502         if (sync.Changed)\r
503           sync.Init();\r
504         dictionarySize = sync.DictionarySize;\r
505         numThreads = sync.NumThreads;\r
506       }\r
507       \r
508       CBenchCallback callback;\r
509       callback.dictionarySize = dictionarySize;\r
510       callback.Sync = &sync;\r
511       HRESULT result;\r
512       try\r
513       {\r
514         result = LzmaBench(\r
515           EXTERNAL_CODECS_VARS\r
516           numThreads, dictionarySize, &callback);\r
517       }\r
518       catch(...)\r
519       {\r
520         result = E_FAIL;\r
521       }\r
522 \r
523       if (result != S_OK)\r
524       {\r
525         if (result != E_ABORT)\r
526         {\r
527           // sync.NumErrors++;\r
528           {\r
529             NSynchronization::CCriticalSectionLock lock(sync.CS);\r
530             sync.Pause();\r
531           }\r
532           UString message;\r
533           if (result == S_FALSE)\r
534             message = L"Decoding error";\r
535           else if (result == CLASS_E_CLASSNOTAVAILABLE)\r
536             message = L"Can't find 7z.dll";\r
537           else\r
538             message = HResultToMessage(result);\r
539           BenchmarkDialog->MessageBoxError(message);\r
540         }\r
541       }\r
542       else\r
543       {\r
544         NSynchronization::CCriticalSectionLock lock(sync.CS);\r
545         sync.NumPasses++;\r
546       }\r
547     }\r
548     // return S_OK;\r
549   }\r
550   catch(CSystemException &e)\r
551   {\r
552     BenchmarkDialog->MessageBoxError(HResultToMessage(e.ErrorCode));\r
553     return E_FAIL;\r
554   }\r
555   catch(...)\r
556   {\r
557     BenchmarkDialog->MessageBoxError(HResultToMessage(E_FAIL));\r
558     return E_FAIL;\r
559   }\r
560 }\r
561 \r
562 HRESULT Benchmark(\r
563     DECL_EXTERNAL_CODECS_LOC_VARS\r
564     UInt32 numThreads, UInt32 dictionarySize, HWND hwndParent)\r
565 {\r
566   CThreadBenchmark benchmarker;\r
567   #ifdef EXTERNAL_CODECS\r
568   benchmarker._codecsInfo = codecsInfo;\r
569   benchmarker._externalCodecs = *externalCodecs;\r
570   #endif\r
571 \r
572   CBenchmarkDialog benchmarkDialog;\r
573   benchmarkDialog.Sync.DictionarySize = dictionarySize;\r
574   benchmarkDialog.Sync.NumThreads = numThreads;\r
575 \r
576   benchmarker.BenchmarkDialog = &benchmarkDialog;\r
577   NWindows::CThread thread;\r
578   RINOK(thread.Create(CThreadBenchmark::MyThreadFunction, &benchmarker));\r
579   benchmarkDialog.Create(hwndParent);\r
580   return thread.Wait();\r
581 }\r