13f085823Sopenharmony_ci/*
23f085823Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd.
33f085823Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
43f085823Sopenharmony_ci * you may not use this file except in compliance with the License.
53f085823Sopenharmony_ci * You may obtain a copy of the License at
63f085823Sopenharmony_ci *
73f085823Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
83f085823Sopenharmony_ci *
93f085823Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
103f085823Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
113f085823Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
123f085823Sopenharmony_ci * See the License for the specific language governing permissions and
133f085823Sopenharmony_ci * limitations under the License.
143f085823Sopenharmony_ci */
153f085823Sopenharmony_ci
163f085823Sopenharmony_ci#include <sleep_ex.h>
173f085823Sopenharmony_ci
183f085823Sopenharmony_ci#include <cstdlib>
193f085823Sopenharmony_ci#include <ctime>
203f085823Sopenharmony_ci#include <unistd.h>
213f085823Sopenharmony_ci
223f085823Sopenharmony_ci#define UNUSED(x) (void)(x)
233f085823Sopenharmony_ci
243f085823Sopenharmony_cinamespace SleepTest {
253f085823Sopenharmony_ci    const long ID_MS_TO_NS_LEVEL = 1000000; // from milliseconds to nanoseconds
263f085823Sopenharmony_ci    const int ID_SE_TO_MS_LEVEL = 1000; // from seconds to milliseconds
273f085823Sopenharmony_ci}
283f085823Sopenharmony_ci
293f085823Sopenharmony_cistatic double TimeDiff(struct timeval *x , struct timeval *y)
303f085823Sopenharmony_ci{
313f085823Sopenharmony_ci    if (x == nullptr || y == nullptr) {
323f085823Sopenharmony_ci        return 0;
333f085823Sopenharmony_ci    }
343f085823Sopenharmony_ci
353f085823Sopenharmony_ci    double xUs = reinterpret_cast<double>(x->tv_sec * SleepTest::ID_MS_TO_NS_LEVEL) +
363f085823Sopenharmony_ci     reinterpret_cast<double>(x->tv_usec);
373f085823Sopenharmony_ci    double yUs = reinterpret_cast<double>(y->tv_sec * SleepTest::ID_MS_TO_NS_LEVEL) +
383f085823Sopenharmony_ci     reinterpret_cast<double>(y->tv_usec);
393f085823Sopenharmony_ci
403f085823Sopenharmony_ci    return (yUs - xUs);
413f085823Sopenharmony_ci}
423f085823Sopenharmony_ci
433f085823Sopenharmony_cistatic int Nsleep(const struct timespec *req, struct timespec *rem)
443f085823Sopenharmony_ci{
453f085823Sopenharmony_ci    struct timespec tempRem;
463f085823Sopenharmony_ci    if (nanosleep(req, rem) == -1) {
473f085823Sopenharmony_ci        Nsleep(rem, &tempRem);
483f085823Sopenharmony_ci        return 0;
493f085823Sopenharmony_ci    }
503f085823Sopenharmony_ci    return 1;
513f085823Sopenharmony_ci}
523f085823Sopenharmony_ci
533f085823Sopenharmony_ciint Msleep(unsigned long miliSec)
543f085823Sopenharmony_ci{
553f085823Sopenharmony_ci    struct timespec req = {0, 0};
563f085823Sopenharmony_ci    struct timespec rem = {0, 0};
573f085823Sopenharmony_ci    time_t sec = reinterpret_cast<int>(miliSec / SleepTest::ID_SE_TO_MS_LEVEL);
583f085823Sopenharmony_ci    miliSec = miliSec - (sec * SleepTest::ID_SE_TO_MS_LEVEL);
593f085823Sopenharmony_ci    req.tv_sec = sec;
603f085823Sopenharmony_ci    req.tv_nsec = miliSec * SleepTest::ID_MS_TO_NS_LEVEL;
613f085823Sopenharmony_ci    Nsleep(&req, &rem);
623f085823Sopenharmony_ci    return 1;
633f085823Sopenharmony_ci}
643f085823Sopenharmony_ci
653f085823Sopenharmony_cistatic void TmpFunc(const void* arg)
663f085823Sopenharmony_ci{
673f085823Sopenharmony_ci    UNUSED(arg);
683f085823Sopenharmony_ci}
693f085823Sopenharmony_ci
703f085823Sopenharmony_cidouble ElapsedTime(time_callback func, void* arg)
713f085823Sopenharmony_ci{
723f085823Sopenharmony_ci    struct timeval start;
733f085823Sopenharmony_ci    struct timeval stop;
743f085823Sopenharmony_ci    double diff;
753f085823Sopenharmony_ci    double selfSpent;
763f085823Sopenharmony_ci
773f085823Sopenharmony_ci    if (func == nullptr) {
783f085823Sopenharmony_ci        // error process here.
793f085823Sopenharmony_ci        return 0.0;
803f085823Sopenharmony_ci    }
813f085823Sopenharmony_ci
823f085823Sopenharmony_ci    // calc self spent.
833f085823Sopenharmony_ci    gettimeofday(&start, 0);
843f085823Sopenharmony_ci    TmpFunc(nullptr);
853f085823Sopenharmony_ci    gettimeofday(&stop, 0);
863f085823Sopenharmony_ci    selfSpent = TimeDiff(&start, &stop);
873f085823Sopenharmony_ci
883f085823Sopenharmony_ci    gettimeofday(&start, 0);
893f085823Sopenharmony_ci    func(arg);
903f085823Sopenharmony_ci    gettimeofday(&stop, 0);
913f085823Sopenharmony_ci    diff = TimeDiff(&start, &stop);
923f085823Sopenharmony_ci
933f085823Sopenharmony_ci    diff = diff - selfSpent;
943f085823Sopenharmony_ci    return (diff >= 0) ? diff : 0;
953f085823Sopenharmony_ci}
96