コード例 #1
0
ファイル: CmdLineParser.cpp プロジェクト: blinds52/diskspd
bool CmdLineParser::_ReadParametersFromCmdLine(const int argc, const char *argv[], Profile *pProfile, struct Synchronization *synch)
{
    /* Process any command-line options */
    int nParamCnt = argc - 1;
    const char** args = argv + 1;

    // create targets
    vector<Target> vTargets;
    int iFirstFile = -1;
    for (int i = 1; i < argc; i++)
    {
        if (argv[i][0] != '-' && argv[i][0] != '/')
        {
            iFirstFile = i;
            Target target;
            target.SetPath(argv[i]);
            vTargets.push_back(target);
        }
    }

    // find block size (other parameters may be stated in terms of blocks)
    for (int x = 1; x < argc; ++x)
    {
        if ((nullptr != argv[x]) && (('-' == argv[x][0]) || ('/' == argv[x][0])) && ('b' == argv[x][1]) && ('\0' != argv[x][2]))
        {
            _dwBlockSize = 0;
            UINT64 ullBlockSize;
            if (_GetSizeInBytes(&argv[x][2], ullBlockSize))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    // TODO: UINT64->DWORD
                    i->SetBlockSizeInBytes((DWORD)ullBlockSize);
                }
            }
            else
            {
                fprintf(stderr, "Invalid block size passed to -b\n");
                exit(1);
            }
            _dwBlockSize = (DWORD)ullBlockSize;
            break;
        }
    }

    TimeSpan timeSpan;
    bool bExit = false;
    while (nParamCnt)
    {
        const char* arg = *args;
        bool fError = false;

        // check if it is a parameter or already path
        if ('-' != *arg && '/' != *arg)
        {
            break;
        }

        // skip '-' or '/'
        ++arg;

        if ('\0' == *arg)
        {
            fprintf(stderr, "Invalid option\n");
            exit(1);
        }

        switch (*arg)
        {
        case '?':
            _DisplayUsageInfo(argv[0]);
            exit(0);

        case 'a':    //affinity
            //-a1,2,3,4 (assign threads to cpus 1,2,3,4 (round robin))
            if (!_ParseAffinity(arg, &timeSpan))
            {
                fError = true;
            }
            break;

        case 'b':    //block size
            // nop - block size has been taken care of before the loop
            break;

        case 'B':    //base file offset (offset from the beggining of the file), cannot be used with 'random'
            if (*(arg + 1) != '\0')
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetBaseFileOffsetInBytes(cb);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid base file offset passed to -B\n");
                    fError = true;
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 'c':    //create file of the given size
            if (*(arg + 1) != '\0')
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetFileSize(cb);
                        i->SetCreateFile(true);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid file size passed to -c\n");
                    fError = true;
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 'C':    //cool down time
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetCooldown(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'd':    //duration
            {
                int x = atoi(arg + 1);
                if (x > 0)
                {
                    timeSpan.SetDuration(x);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'D':    //standard deviation
            {
                timeSpan.SetCalculateIopsStdDev(true);

                int x = atoi(arg + 1);
                if (x > 0)
                {
                    timeSpan.SetIoBucketDurationInMilliseconds(x);
                }
            }
            break;

        case 'e':    //etw
            if (!_ParseETWParameter(arg, pProfile))
            {
                fError = true;
            }
            break;

        case 'f':
            if ('r' == *(arg + 1))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetRandomAccessHint(true);
                }
            }
            else if ('s' == *(arg + 1))
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetSequentialScanHint(true);
                }
            }
            else
            {
                if (*(arg + 1) != '\0')
                {
                    UINT64 cb;
                    if (_GetSizeInBytes(arg + 1, cb))
                    {
                        for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                        {
                            i->SetMaxFileSize(cb);
                        }
                    }
                    else
                    {
                        fprintf(stderr, "Invalid max file size passed to -f\n");
                        fError = true;
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'F':    //total number of threads
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    timeSpan.SetThreadCount(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'g':    //throughput in bytes per millisecond
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThroughput(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'h':    //disable both software and hardware caching
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetDisableAllCache(true);
            }
            break;

        case 'i':    //number of IOs to issue before think time
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetBurstSize(c);
                        i->SetUseBurstSize(true);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'j':    //time to wait between bursts of IOs
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThinkTime(c);
                        i->SetEnableThinkTime(true);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'I':   //io priority
            {
                int x = atoi(arg + 1);
                if (x > 0 && x < 4)
                {
                    PRIORITY_HINT hint[] = { IoPriorityHintVeryLow, IoPriorityHintLow, IoPriorityHintNormal };
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetIOPriorityHint(hint[x - 1]);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'l':    //large pages
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetUseLargePages(true);
            }
            break;
        
        case 'L':    //measure latency
            timeSpan.SetMeasureLatency(true);
            break;

        case 'n':    //disable affinity (by default simple affinity is turned on)
            timeSpan.SetDisableAffinity(true);
            break;

        case 'o':    //request count (1==synchronous)
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetRequestCount(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'p':    //start async IO operations with the same offset
            //makes sense only for -o2 and greater
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetUseParallelAsyncIO(true);
            }
            break;

        case 'P':    //show progress every x IO operations
            {
                int c = atoi(arg + 1);
                if (c < 1)
                {
                    c = 65536;
                }
                pProfile->SetProgress(c);
            }
            break;

        case 'r':    //random access
            {
                UINT64 cb = _dwBlockSize;
                if (*(arg + 1) != '\0')
                {
                    if (!_GetSizeInBytes(arg + 1, cb) || (cb == 0))
                    {
                        fprintf(stderr, "Invalid alignment passed to -r\n");
                        fError = true;
                    }
                }
                if (!fError)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetUseRandomAccessPattern(true);
                        i->SetBlockAlignmentInBytes(cb);
                    }
                }
            }
            break;

        case 'R':    //custom result parser
            if (0 != *(arg + 1))
            {
                const char* pszArg = arg + 1;
                if (strcmp(pszArg, "xml") == 0)
                {
                    pProfile->SetResultsFormat(ResultsFormat::Xml);
                }
                else if (strcmp(pszArg, "text") != 0)
                {
                    fError = true;
                    fprintf(stderr, "Invalid results format: '%s'.\n", pszArg);
                }
            }
            else
            {
                fError = true;
            }
            break;

        case 's':    //stride size
            {
                int idx = 1;

                if ('i' == *(arg + idx))
                {
                    // do interlocked sequential mode
                    // ISSUE-REVIEW: this does nothing if -r is specified
                    // ISSUE-REVIEW: this does nothing if -p is specified
                    // ISSUE-REVIEW: this does nothing if we are single-threaded 
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetUseInterlockedSequential(true);
                    }

                    idx++;
                }
                
                if (*(arg + idx) != '\0')
                {
                    UINT64 cb;
                    if (_GetSizeInBytes(arg + idx, cb))
                    {
                        for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                        {
                            i->SetBlockAlignmentInBytes(cb);
                        }
                    }
                    else
                    {
                        fprintf(stderr, "Invalid stride size passed to -s\n");
                        fError = true;
                    }
                }
            }
            break;

        case 'S':   //disable OS caching (software buffering)
            //IMPORTANT: File access must begin at byte offsets within the file that are integer multiples of the volume's sector size. 
            // File access must be for numbers of bytes that are integer multiples of the volume's sector size. For example, if the sector
            // size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes. 
            // Buffer addresses for read and write operations should be sector aligned (aligned on addresses in memory that are integer
            // multiples of the volume's sector size). Depending on the disk, this requirement may not be enforced. 
            for (auto i = vTargets.begin(); i != vTargets.end(); i++)
            {
                i->SetDisableOSCache(true);
            }
            break;

        case 't':    //number of threads per file
            {
                int c = atoi(arg + 1);
                if (c > 0)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThreadsPerFile(c);
                    }
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'T':    //offsets between threads reading the same file
            {
                UINT64 cb;
                if (_GetSizeInBytes(arg + 1, cb) && (cb > 0))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetThreadStrideInBytes(cb);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid offset passed to -T\n");
                    fError = true;
                }
            }
            break;

        case 'v':    //verbose mode
            pProfile->SetVerbose(true);
            break;

        case 'w':    //write test [default=read]
            {
                int c = -1;
                if (*(arg + 1) == '\0')
                {
                    c = _ulWriteRatio;
                }
                else
                {
                    c = atoi(arg + 1);
                    if (c < 0 || c > 100)
                    {
                        c = -1;
                        fError = true;
                    }
                }
                if (c != -1)
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetWriteRatio(c);
                    }
                }
            }
            break;

        case 'W':    //warm up time
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetWarmup(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'x':    //completion routines
            timeSpan.SetCompletionRoutines(true);
            break;

        case 'y':    //external synchronization
            switch (*(arg + 1))
            {

            case 's':
                _hEventStarted = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == _hEventStarted)
                {
                    fprintf(stderr, "Error creating/opening start notification event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'f':
                _hEventFinished = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == _hEventFinished)
                {
                    fprintf(stderr, "Error creating/opening finish notification event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'r':
                synch->hStartEvent = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == synch->hStartEvent)
                {
                    fprintf(stderr, "Error creating/opening wait-for-start event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'p':
                synch->hStopEvent = CreateEvent(NULL, TRUE, FALSE, arg + 2);
                if (NULL == synch->hStopEvent)
                {
                    fprintf(stderr, "Error creating/opening force-stop event: '%s'\n", arg + 2);
                    exit(1);    // TODO: this class shouldn't terminate the process
                }
                break;

            case 'e':
                {
                    HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, arg + 2);
                    if (NULL == hEvent)
                    {
                        fprintf(stderr, "Error opening event '%s'\n", arg + 2);
                        exit(1);    // TODO: this class shouldn't terminate the process
                    }
                    if (!SetEvent(hEvent))
                    {
                        fprintf(stderr, "Error setting event '%s'\n", arg + 2);
                        exit(1);    // TODO: this class shouldn't terminate the process
                    }
                    CloseHandle(hEvent);
                    printf("Succesfully set event: '%s'\n", arg + 2);
                    bExit = true;
                    break;
                }

            default:
                fError = true;
            }

        case 'z':    //random seed
            if (*(arg + 1) == '\0')
            {
                timeSpan.SetRandSeed((ULONG)GetTickCount64());
            }
            else
            {
                int c = atoi(arg + 1);
                if (c >= 0)
                {
                    timeSpan.SetRandSeed(c);
                }
                else
                {
                    fError = true;
                }
            }
            break;

        case 'Z':    //zero write buffers
            if (*(arg + 1) == '\0')
            {
                for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                {
                    i->SetZeroWriteBuffers(true);
                }
            }
            else
            {
                UINT64 cb = 0;
                string sPath;
                if (_GetRandomDataWriteBufferData(string(arg + 1), cb, sPath) && (cb > 0))
                {
                    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
                    {
                        i->SetRandomDataWriteBufferSize(cb);
                        i->SetRandomDataWriteBufferSourcePath(sPath);
                    }
                }
                else
                {
                    fprintf(stderr, "Invalid size passed to -Z\n");
                    fError = true;
                }
            }
            break;

        default:
            fprintf(stderr, "Invalid option: '%s'\n", arg);
            exit(1);                    // TODO: this class shouldn't terminate the process
        }

        if (fError)
        {
            fprintf(stderr, "Incorrectly provided option: '%s'\n", arg);
            exit(1);                    // TODO: this class shouldn't terminate the process
        }

        --nParamCnt;
        ++args;
    }

    //
    // exit if a user specified an action which was already satisfied and doesn't require running test
    //
    if (bExit)
    {
        printf("Now exiting...\n");
        exit(1);                        // TODO: this class shouldn't terminate the process
    }

    if (vTargets.size() < 1)
    {
        fprintf(stderr, "You need to provide at least one filename\n");
        return false;
    }

    for (auto i = vTargets.begin(); i != vTargets.end(); i++)
    {
        timeSpan.AddTarget(*i);
    }
    pProfile->AddTimeSpan(timeSpan);

    return true;
}
コード例 #2
0
ファイル: testset.c プロジェクト: Jpfonseca/Algoritmos
int main (void)
{
	PtSet set1 = NULL, set2 = NULL, set3 = NULL;
	char filename[21], car; int st; 

	system ("clear");

	printf ("\nLer conjunto do ficheiro - Read set from a text file\n");
	do
	{
  		printf ("Nome do ficheiro (Filename) -> ");
		st = scanf ("%20[^\n]", filename);
		scanf ("%*[^\n]"); scanf ("%*c");
	} while (st == 0);

	set1 = SetCreateFile (filename);
	printf ("\nConjunto lido do ficheiro - Set acquired from text file %s\n", filename);
	WriteSet (set1);

	printf ("\nLer conjunto do teclado [# para terminar] - Read set from keyboard [# to stop]\n");
	set2 = SetCreate ();
	do
	{
		do
		{
			printf ("Elemento do conjunto (Set's element) ? "); st = scanf ("%c", &car);
			scanf ("%*[^\n]"); scanf ("%*c");
		} while (st == 0);
		car = toupper (car);
		if (isupper(car)) SetInsertElement (set2, car);
	} while (car != '#');

	printf ("\nConjunto lido do teclado - Set acquired from keyboard\n");
	WriteSet (set2);

	printf ("\nEscrever conjunto no ficheiro - Storing the set in a text file\n");
	do
	{
  		printf ("Nome do ficheiro (Filename) -> ");
		st = scanf ("%20[^\n]", filename);
		scanf ("%*[^\n]"); scanf ("%*c");
	} while (st == 0);
	SetStoreFile (set2, filename);

	set3 = SetReunion (set1, set2);
	printf ("\nConjunto Reuniao - Union set\n");
	WriteSet (set3);

	SetDestroy (&set3);
	set3 = SetIntersection (set1, set2);
	printf ("\nConjunto Interseccao - Intersection set\n");
	WriteSet (set3);

	SetDestroy (&set3);
	set3 = SetSymmetricDifference (set1, set2);
	printf ("\nConjunto Diferença - Symmetric Difference set\n");
	WriteSet (set3);

	printf ("\nDestruir os conjuntos - Releasing the sets\n");
	SetDestroy (&set1);
	SetDestroy (&set2);
	SetDestroy (&set3);

	WriteSet (set3);

	return 0;
}