164339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// Copyright (C) 2016 and later: Unicode, Inc. and others.
264339d36f8bd4db5025fe2988eda22b491a9219cFredrik Roubert// License & terms of use: http://www.unicode.org/copyright.html
3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/********************************************************************
4ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * COPYRIGHT:
554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius * Copyright (c) 2002-2012, International Business Machines Corporation and
6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * others. All Rights Reserved.
7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru ********************************************************************/
8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
9103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Defines _XOPEN_SOURCE for access to POSIX functions.
10103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Must be before any other #includes.
11103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uposixdefs.h"
12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/uperf.h"
14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "uoptions.h"
15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h"
16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdio.h>
17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include <stdlib.h>
18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#if !UCONFIG_NO_CONVERSION
20103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
21103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUPerfFunction::~UPerfFunction() {}
22103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius
23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const char delim = '/';
24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic int32_t execCount = 0;
25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUPerfTest* UPerfTest::gTest = NULL;
26ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic const int MAXLINES = 40000;
27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst char UPerfTest::gUsageString[] =
28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "Usage: %s [OPTIONS] [FILES]\n"
29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\tReads the input file and prints out time taken in seconds\n"
30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "Options:\n"
31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-h or -? or --help   this usage text\n"
32ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-v or --verbose      print extra information when processing files\n"
33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-s or --sourcedir    source directory for files followed by path\n"
34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t                     followed by path\n"
35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-e or --encoding     encoding of source files\n"
36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-u or --uselen       perform timing analysis on non-null terminated buffer using length\n"
37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-f or --file-name    file to be used as input data\n"
38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-p or --passes       Number of passes to be performed. Requires Numeric argument.\n"
39ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t                     Cannot be used with --time\n"
40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-i or --iterations   Number of iterations to be performed. Requires Numeric argument\n"
41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-t or --time         Threshold time for looping until in seconds. Requires Numeric argument.\n"
42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t                     Cannot be used with --iterations\n"
43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-l or --line-mode    The data file should be processed in line mode\n"
44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-b or --bulk-mode    The data file should be processed in file based.\n"
45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t                     Cannot be used with --line-mode\n"
46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    "\t-L or --locale       Locale for the test\n";
47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruenum
49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    HELP1,
51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    HELP2,
52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    VERBOSE,
53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    SOURCEDIR,
54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ENCODING,
55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    USELEN,
56ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    FILE_NAME,
57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    PASSES,
58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ITERATIONS,
59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    TIME,
60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LINE_MODE,
61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    BULK_MODE,
62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    LOCALE,
63ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    OPTIONS_COUNT
64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Querustatic UOption options[OPTIONS_COUNT+20]={
68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_HELP_H,
69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_HELP_QUESTION_MARK,
70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_VERBOSE,
71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_SOURCEDIR,
72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_ENCODING,
73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "uselen",        'u', UOPT_NO_ARG),
74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "file-name",     'f', UOPT_REQUIRES_ARG),
75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "passes",        'p', UOPT_REQUIRES_ARG),
76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "iterations",    'i', UOPT_REQUIRES_ARG),
77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "time",          't', UOPT_REQUIRES_ARG),
78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "line-mode",     'l', UOPT_NO_ARG),
79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "bulk-mode",     'b', UOPT_NO_ARG),
80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UOPTION_DEF( "locale",        'L', UOPT_REQUIRES_ARG)
81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru};
82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUPerfTest::UPerfTest(int32_t argc, const char* argv[], UErrorCode& status)
84ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        : _argc(argc), _argv(argv), _addUsage(NULL),
85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          ucharBuf(NULL), encoding(""),
86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uselen(FALSE),
87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          fileName(NULL), sourceDir("."),
88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          lines(NULL), numLines(0), line_mode(TRUE),
89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          buffer(NULL), bufferLen(0),
90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          verbose(FALSE), bulk_mode(FALSE),
91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          passes(1), iterations(0), time(0),
92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          locale(NULL) {
93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    init(NULL, 0, status);
94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUPerfTest::UPerfTest(int32_t argc, const char* argv[],
97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     UOption addOptions[], int32_t addOptionsCount,
98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     const char *addUsage,
99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     UErrorCode& status)
100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        : _argc(argc), _argv(argv), _addUsage(addUsage),
101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          ucharBuf(NULL), encoding(""),
102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          uselen(FALSE),
103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          fileName(NULL), sourceDir("."),
104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          lines(NULL), numLines(0), line_mode(TRUE),
105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          buffer(NULL), bufferLen(0),
106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          verbose(FALSE), bulk_mode(FALSE),
107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          passes(1), iterations(0), time(0),
108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru          locale(NULL) {
109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    init(addOptions, addOptionsCount, status);
110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UPerfTest::init(UOption addOptions[], int32_t addOptionsCount,
113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                     UErrorCode& status) {
114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //initialize the argument list
115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    U_MAIN_INIT_ARGS(_argc, _argv);
116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
11785bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho    resolvedFileName = NULL;
11885bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho
119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // add specific options
120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t optionsCount = OPTIONS_COUNT;
121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (addOptionsCount > 0) {
122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        memcpy(options+optionsCount, addOptions, addOptionsCount*sizeof(UOption));
123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        optionsCount += addOptionsCount;
124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    //parse the arguments
127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    _remainingArgc = u_parseArgs(_argc, (char**)_argv, optionsCount, options);
128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // copy back values for additional options
130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (addOptionsCount > 0) {
131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        memcpy(addOptions, options+OPTIONS_COUNT, addOptionsCount*sizeof(UOption));
132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Now setup the arguments
135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(_argc==1 || options[HELP1].doesOccur || options[HELP2].doesOccur) {
136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        status = U_ILLEGAL_ARGUMENT_ERROR;
137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return;
138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[VERBOSE].doesOccur) {
141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        verbose = TRUE;
142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[SOURCEDIR].doesOccur) {
145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        sourceDir = options[SOURCEDIR].value;
146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[ENCODING].doesOccur) {
149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        encoding = options[ENCODING].value;
150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[USELEN].doesOccur) {
153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uselen = TRUE;
154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[FILE_NAME].doesOccur){
157ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        fileName = options[FILE_NAME].value;
158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
160ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[PASSES].doesOccur) {
161ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        passes = atoi(options[PASSES].value);
162ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
163ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[ITERATIONS].doesOccur) {
164ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iterations = atoi(options[ITERATIONS].value);
165ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(options[TIME].doesOccur) {
166ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_ILLEGAL_ARGUMENT_ERROR;
167ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
168ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
169ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else if(options[TIME].doesOccur) {
170ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        time = atoi(options[TIME].value);
171ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    } else {
172ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        iterations = 1000; // some default
173ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
174ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
175ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[LINE_MODE].doesOccur) {
176ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        line_mode = TRUE;
177ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bulk_mode = FALSE;
178ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
179ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
180ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[BULK_MODE].doesOccur) {
181ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        bulk_mode = TRUE;
182ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        line_mode = FALSE;
183ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
184ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
185ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(options[LOCALE].doesOccur) {
18685bf2e2fbc60a9f938064abc8127d61da7d19882Claire Ho        locale = options[LOCALE].value;
187ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
188ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
189ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t len = 0;
190ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(fileName!=NULL){
191ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        //pre-flight
192ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucbuf_resolveFileName(sourceDir, fileName, NULL, &len, &status);
193ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        resolvedFileName = (char*) uprv_malloc(len);
194ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(resolvedFileName==NULL){
195ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status= U_MEMORY_ALLOCATION_ERROR;
196ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
197ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
198ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(status == U_BUFFER_OVERFLOW_ERROR){
199ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            status = U_ZERO_ERROR;
200ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
201ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucbuf_resolveFileName(sourceDir, fileName, resolvedFileName, &len, &status);
202ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        ucharBuf = ucbuf_open(resolvedFileName,&encoding,TRUE,FALSE,&status);
203ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
204ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(U_FAILURE(status)){
205ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            printf("Could not open the input file %s. Error: %s\n", fileName, u_errorName(status));
206ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            return;
207ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
208ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
209ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
210ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
211ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruULine* UPerfTest::getLines(UErrorCode& status){
212b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (U_FAILURE(status)) {
213b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return NULL;
214b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
215b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    if (lines != NULL) {
216b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        return lines;  // don't do it again
217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho    }
218ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    lines     = new ULine[MAXLINES];
219ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int maxLines = MAXLINES;
220ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    numLines=0;
221ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const UChar* line=NULL;
222ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t len =0;
223ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (;;) {
224ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        line = ucbuf_readline(ucharBuf,&len,&status);
225ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if(line == NULL || U_FAILURE(status)){
226ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
227ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
228ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        lines[numLines].name  = new UChar[len];
229ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        lines[numLines].len   = len;
230ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        memcpy(lines[numLines].name, line, len * U_SIZEOF_UCHAR);
231ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
232ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        numLines++;
233ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        len = 0;
234ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (numLines >= maxLines) {
235ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            maxLines += MAXLINES;
236ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ULine *newLines = new ULine[maxLines];
237ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(newLines == NULL) {
238ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stderr, "Out of memory reading line %d.\n", (int)numLines);
239ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                status= U_MEMORY_ALLOCATION_ERROR;
240ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                delete []lines;
241ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return NULL;
242ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
243ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
244ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            memcpy(newLines, lines, numLines*sizeof(ULine));
245ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete []lines;
246ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            lines = newLines;
247ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
248ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
249ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return lines;
250ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
251ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruconst UChar* UPerfTest::getBuffer(int32_t& len, UErrorCode& status){
252ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (U_FAILURE(status)) {
253ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return NULL;
254ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
255ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = ucbuf_size(ucharBuf);
256ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    buffer =  (UChar*) uprv_malloc(U_SIZEOF_UCHAR * (len+1));
257ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    u_strncpy(buffer,ucbuf_getBuffer(ucharBuf,&bufferLen,&status),len);
258ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    buffer[len]=0;
259ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    len = bufferLen;
260ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return buffer;
261ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
262ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool UPerfTest::run(){
263ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(_remainingArgc==1){
264ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        // Testing all methods
265ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        return runTest();
266ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
267ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool res=FALSE;
268ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // Test only the specified fucntion
269ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    for (int i = 1; i < _remainingArgc; ++i) {
270ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (_argv[i][0] != '-') {
271ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char* name = (char*) _argv[i];
272ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(verbose==TRUE){
273ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //fprintf(stdout, "\n=== Handling test: %s: ===\n", name);
274ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //fprintf(stdout, "\n%s:\n", name);
275ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
276ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            char* parameter = strchr( name, '@' );
277ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (parameter) {
278ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                *parameter = 0;
279ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                parameter += 1;
280ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
281ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            execCount = 0;
282ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            res = runTest( name, parameter );
283ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (!res || (execCount <= 0)) {
284ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout, "\n---ERROR: Test doesn't exist: %s!\n", name);
285ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return FALSE;
286ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
287ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
288ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
289ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return res;
290ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
291ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool UPerfTest::runTest(char* name, char* par ){
292ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool rval;
293ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    char* pos = NULL;
294ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
295ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (name)
296ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        pos = strchr( name, delim ); // check if name contains path (by looking for '/')
297ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (pos) {
298ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        path = pos+1;   // store subpath for calling subtest
299ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *pos = 0;       // split into two strings
300ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }else{
301ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        path = NULL;
302ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
303ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
304ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (!name || (name[0] == 0) || (strcmp(name, "*") == 0)) {
305ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rval = runTestLoop( NULL, NULL );
306ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
307ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }else if (strcmp( name, "LIST" ) == 0) {
308ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        this->usage();
309ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rval = TRUE;
310ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
311ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }else{
312ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        rval = runTestLoop( name, par );
313ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
314ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
315ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (pos)
316ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        *pos = delim;  // restore original value at pos
317ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return rval;
318ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
319ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
320ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
321ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UPerfTest::setPath( char* pathVal )
322ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
323ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    this->path = pathVal;
324ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
325ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
326ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru// call individual tests, to be overriden to call implementations
32754dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusUPerfFunction* UPerfTest::runIndexedTest( int32_t /*index*/, UBool /*exec*/, const char* & /*name*/, char* /*par*/ )
328ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
329ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    // to be overriden by a method like:
330ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    /*
331ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    switch (index) {
332ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 0: name = "First Test"; if (exec) FirstTest( par ); break;
333ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        case 1: name = "Second Test"; if (exec) SecondTest( par ); break;
334ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        default: name = ""; break;
335ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
336ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    */
337ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stderr,"*** runIndexedTest needs to be overriden! ***");
338ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return NULL;
339ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
340ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
341ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
342ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool UPerfTest::runTestLoop( char* testname, char* par )
343ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
344ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t    index = 0;
345ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char*   name;
346ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool  run_this_test;
347ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool  rval = FALSE;
348ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UErrorCode status = U_ZERO_ERROR;
349ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UPerfTest* saveTest = gTest;
350ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    gTest = this;
351ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t loops = 0;
352ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    double t=0;
353ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t n = 1;
354ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    long ops;
355ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    do {
356ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        this->runIndexedTest( index, FALSE, name );
357ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!name || (name[0] == 0))
358ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
359ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!testname) {
360ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            run_this_test = TRUE;
361ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }else{
362ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            run_this_test = (UBool) (strcmp( name, testname ) == 0);
363ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
364ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (run_this_test) {
365ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            UPerfFunction* testFunction = this->runIndexedTest( index, TRUE, name, par );
366ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            execCount++;
367ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            rval=TRUE;
368ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(testFunction==NULL){
369ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stderr,"%s function returned NULL", name);
370ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return FALSE;
371ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
372ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            ops = testFunction->getOperationsPerIteration();
373ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if (ops < 1) {
374ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stderr, "%s returned an illegal operations/iteration()\n", name);
375ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                return FALSE;
376ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
377ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(iterations == 0) {
378ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                n = time;
379ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                // Run for specified duration in seconds
380ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(verbose==TRUE){
381ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout,"= %s calibrating %i seconds \n", name, (int)n);
382ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
383ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
384ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //n *=  1000; // s => ms
385ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //System.out.println("# " + meth.getName() + " " + n + " sec");
386ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                int32_t failsafe = 1; // last resort for very fast methods
387ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                t = 0;
388ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                while (t < (int)(n * 0.9)) { // 90% is close enough
389ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if (loops == 0 || t == 0) {
390ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        loops = failsafe;
391ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        failsafe *= 10;
392ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    } else {
393ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        //System.out.println("# " + meth.getName() + " x " + loops + " = " + t);
394ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        loops = (int)((double)n / t * loops + 0.5);
395ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        if (loops == 0) {
396ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            fprintf(stderr,"Unable to converge on desired duration");
397ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            return FALSE;
398ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        }
399ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
400ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    //System.out.println("# " + meth.getName() + " x " + loops);
401ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    t = testFunction->time(loops,&status);
402ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if(U_FAILURE(status)){
403ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        printf("Performance test failed with error: %s \n", u_errorName(status));
404ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        break;
405ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
406ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
407ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            } else {
408ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                loops = iterations;
409ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
410ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
411ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            double min_t=1000000.0, sum_t=0.0;
412ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            long events = -1;
413ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
414ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            for(int32_t ps =0; ps < passes; ps++){
415ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                fprintf(stdout,"= %s begin " ,name);
416ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(verbose==TRUE){
417ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if(iterations > 0) {
418ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout, "%i\n", (int)loops);
419ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    } else {
420ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout, "%i\n", (int)n);
421ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
422ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                } else {
423ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "\n");
424ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
425ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                t = testFunction->time(loops, &status);
426ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(U_FAILURE(status)){
427ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    printf("Performance test failed with error: %s \n", u_errorName(status));
428ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    break;
429ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
430ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                sum_t+=t;
431ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(t<min_t) {
432ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    min_t=t;
433ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
434ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                events = testFunction->getEventsPerIteration();
435ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                //print info only in verbose mode
436ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if(verbose==TRUE){
437ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if(events == -1){
438ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout, "= %s end: %f loops: %i operations: %li \n", name, t, (int)loops, ops);
439ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }else{
440ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout, "= %s end: %f loops: %i operations: %li events: %li\n", name, t, (int)loops, ops, events);
441ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
442ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }else{
443ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    if(events == -1){
444ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout,"= %s end %f %i %li\n", name, t, (int)loops, ops);
445ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }else{
446ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                        fprintf(stdout,"= %s end %f %i %li %li\n", name, t, (int)loops, ops, events);
447ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    }
448ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
449ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
450ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            if(verbose && U_SUCCESS(status)) {
451ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                double avg_t = sum_t/passes;
452ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                if (loops == 0 || ops == 0) {
453ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stderr, "%s did not run\n", name);
454ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
455ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else if(events == -1) {
456ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns\n",
457ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops));
458ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns\n",
459ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            name, min_t, (int)loops, (min_t*1E9)/(loops*ops));
460ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
461ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                else {
462ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "%%= %s avg: %.4g loops: %i avg/op: %.4g ns avg/event: %.4g ns\n",
463ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            name, avg_t, (int)loops, (avg_t*1E9)/(loops*ops), (avg_t*1E9)/(loops*events));
464ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                    fprintf(stdout, "_= %s min: %.4g loops: %i min/op: %.4g ns min/event: %.4g ns\n",
465ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                            name, min_t, (int)loops, (min_t*1E9)/(loops*ops), (min_t*1E9)/(loops*events));
466ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru                }
467ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            }
468ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            delete testFunction;
469ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        }
470ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        index++;
471ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }while(name);
472ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
473ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    gTest = saveTest;
474ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return rval;
475ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
476ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
477ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/**
478ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Print a usage message for this test class.
479ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru*/
480ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UPerfTest::usage( void )
481ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
482ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    puts(gUsageString);
483ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (_addUsage != NULL) {
484ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        puts(_addUsage);
485ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
486ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
487ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    UBool save_verbose = verbose;
488ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    verbose = TRUE;
489ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stdout,"Test names:\n");
490ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    fprintf(stdout,"-----------\n");
491ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
492ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    int32_t index = 0;
493ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    const char* name = NULL;
494ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    do{
495ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        this->runIndexedTest( index, FALSE, name );
496ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        if (!name)
497ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru            break;
498b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho        fprintf(stdout, "%s\n", name);
499ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        index++;
500ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }while (name && (name[0] != 0));
501ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    verbose = save_verbose;
502ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
503ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
504ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
505ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
506ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
507ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruvoid UPerfTest::setCaller( UPerfTest* callingTest )
508ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
509ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    caller = callingTest;
510ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if (caller) {
511ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        verbose = caller->verbose;
512ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
513ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
514ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
515ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUBool UPerfTest::callTest( UPerfTest& testToBeCalled, char* par )
516ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru{
517ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    execCount--; // correct a previously assumed test-exec, as this only calls a subtest
518ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    testToBeCalled.setCaller( this );
519ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    return testToBeCalled.runTest( path, par );
520ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
521ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
522ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUPerfTest::~UPerfTest(){
523ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(lines!=NULL){
524ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        delete[] lines;
525ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
526ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(buffer!=NULL){
527ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_free(buffer);
528ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
529ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    if(resolvedFileName!=NULL){
530ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru        uprv_free(resolvedFileName);
531ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    }
532ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru    ucbuf_close(ucharBuf);
533ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru}
534ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru
535ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif
536