<commit_before>/*++
Copyright (c) 2011 Microsoft Corporation

Module Name:

    scoped_timer.cpp

Abstract:

    <abstract>

Author:

    <NAME> (leonardo) 2011-04-26.

Revision History:

--*/
#ifdef _CYGWIN
// Hack to make CreateTimerQueueTimer available on cygwin
#define _WIN32_WINNT 0x0600
#endif

#include"z3_exception.h"
#include"z3_omp.h"
#if defined(_WINDOWS) || defined(_CYGWIN)
// Windows
#include<windows.h>
#elif defined(__APPLE__) && defined(__MACH__)
// Mac OS X
#include<mach/mach.h>
#include<mach/clock.h>
#include<sys/time.h>
#include<sys/errno.h>
#include<pthread.h>
#elif defined(_LINUX_) || defined(_FREEBSD_)
// Linux
#include<errno.h>
#include<pthread.h>
#include<sched.h>
#include<time.h>
// ---------
#else
// Other platforms
#endif 

#include"scoped_timer.h"
#ifdef _CYGWIN
#undef min
#undef max
#endif
#include"util.h"
#include<limits.h>
#include"z3_omp.h"

struct scoped_timer::imp {
    event_handler *  m_eh;
#if defined(_WINDOWS) || defined(_CYGWIN)
    HANDLE           m_timer;
    bool             m_first;
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS X
    pthread_t        m_thread_id;
    pthread_attr_t   m_attributes;
    unsigned         m_interval;    
    pthread_mutex_t  m_mutex;
    pthread_cond_t   m_condition_var;
    struct timespec  m_end_time;
#elif defined(_LINUX_) || defined(_FREEBSD_)
    // Linux & FreeBSD
    pthread_t       m_thread_id;
    pthread_mutex_t m_mutex;
    pthread_cond_t  m_cond;
    unsigned        m_ms;
    bool            m_initialized;
#else
    // Other
#endif

#if defined(_WINDOWS) || defined(_CYGWIN)
    static void CALLBACK abort_proc(PVOID param, BOOLEAN timer_or_wait_fired) {
        imp * obj = static_cast<imp*>(param);
        if (obj->m_first) {
            obj->m_first = false;
        }
        else {
            obj->m_eh->operator()();
        }
    }
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS X
    static void * thread_func(void * arg) {
        scoped_timer::imp * st = static_cast<scoped_timer::imp*>(arg);  

        pthread_mutex_lock(&st->m_mutex);

        int e = pthread_cond_timedwait(&st->m_condition_var, &st->m_mutex, &st->m_end_time);
        if (e != 0 && e != ETIMEDOUT)
            throw default_exception("failed to start timed wait");
        st->m_eh->operator()();

        pthread_mutex_unlock(&st->m_mutex);

        return st;
    }
#elif defined(_LINUX_) || defined(_FREEBSD_)
    static void* thread_func(void *arg) {
        scoped_timer::imp *st = static_cast<scoped_timer::imp*>(arg);

        struct timespec end_time;
        clock_gettime(CLOCK_REALTIME, &end_time);
        end_time.tv_sec  += st->m_ms / 1000u;
        end_time.tv_nsec += (st->m_ms % 1000u) * 1000000ull;
        // check for overflow
        if (end_time.tv_nsec >= 1000000000ull) {
            ++end_time.tv_sec;
            end_time.tv_nsec -= 1000000000ull;
        }

        pthread_mutex_lock(&st->m_mutex);
        st->m_initialized = true;
        int e = pthread_cond_timedwait(&st->m_cond, &st->m_mutex, &end_time);
        ENSURE(e == 0 || e == ETIMEDOUT);

        pthread_mutex_unlock(&st->m_mutex);
        if (e == ETIMEDOUT)
            st->m_eh->operator()();<commit_msg>fix compiler warning in scoped_timer.cpp on linux 2 secs in nanosec representation still fit in 31 bits, so no need for ULL<commit_after>/*++
Copyright (c) 2011 Microsoft Corporation

Module Name:

    scoped_timer.cpp

Abstract:

    <abstract>

Author:

    <NAME> (leonardo) 2011-04-26.

Revision History:

--*/
#ifdef _CYGWIN
// Hack to make CreateTimerQueueTimer available on cygwin
#define _WIN32_WINNT 0x0600
#endif

#include"z3_exception.h"
#include"z3_omp.h"
#if defined(_WINDOWS) || defined(_CYGWIN)
// Windows
#include<windows.h>
#elif defined(__APPLE__) && defined(__MACH__)
// Mac OS X
#include<mach/mach.h>
#include<mach/clock.h>
#include<sys/time.h>
#include<sys/errno.h>
#include<pthread.h>
#elif defined(_LINUX_) || defined(_FREEBSD_)
// Linux
#include<errno.h>
#include<pthread.h>
#include<sched.h>
#include<time.h>
// ---------
#else
// Other platforms
#endif 

#include"scoped_timer.h"
#ifdef _CYGWIN
#undef min
#undef max
#endif
#include"util.h"
#include<limits.h>
#include"z3_omp.h"

struct scoped_timer::imp {
    event_handler *  m_eh;
#if defined(_WINDOWS) || defined(_CYGWIN)
    HANDLE           m_timer;
    bool             m_first;
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS X
    pthread_t        m_thread_id;
    pthread_attr_t   m_attributes;
    unsigned         m_interval;    
    pthread_mutex_t  m_mutex;
    pthread_cond_t   m_condition_var;
    struct timespec  m_end_time;
#elif defined(_LINUX_) || defined(_FREEBSD_)
    // Linux & FreeBSD
    pthread_t       m_thread_id;
    pthread_mutex_t m_mutex;
    pthread_cond_t  m_cond;
    unsigned        m_ms;
    bool            m_initialized;
#else
    // Other
#endif

#if defined(_WINDOWS) || defined(_CYGWIN)
    static void CALLBACK abort_proc(PVOID param, BOOLEAN timer_or_wait_fired) {
        imp * obj = static_cast<imp*>(param);
        if (obj->m_first) {
            obj->m_first = false;
        }
        else {
            obj->m_eh->operator()();
        }
    }
#elif defined(__APPLE__) && defined(__MACH__)
    // Mac OS X
    static void * thread_func(void * arg) {
        scoped_timer::imp * st = static_cast<scoped_timer::imp*>(arg);  

        pthread_mutex_lock(&st->m_mutex);

        int e = pthread_cond_timedwait(&st->m_condition_var, &st->m_mutex, &st->m_end_time);
        if (e != 0 && e != ETIMEDOUT)
            throw default_exception("failed to start timed wait");
        st->m_eh->operator()();

        pthread_mutex_unlock(&st->m_mutex);

        return st;
    }
#elif defined(_LINUX_) || defined(_FREEBSD_)
    static void* thread_func(void *arg) {
        scoped_timer::imp *st = static_cast<scoped_timer::imp*>(arg);

        struct timespec end_time;
        clock_gettime(CLOCK_REALTIME, &end_time);
        end_time.tv_sec  += st->m_ms / 1000u;
        end_time.tv_nsec += (st->m_ms % 1000u) * 1000000ull;
        // check for overflow
        if (end_time.tv_nsec >= 1000000000) {
            ++end_time.tv_sec;
            end_time.tv_nsec -= 1000000000;
        }

        pthread_mutex_lock(&st->m_mutex);
        st->m_initialized = true;
        int e = pthread_cond_timedwait(&st->m_cond, &st->m_mutex, &end_time);
        ENSURE(e == 0 || e == ETIMEDOUT);

        pthread_mutex_unlock(&st->m_mutex);
        if (e == ETIMEDOUT)
            st->m_eh->operator()();
{'fraction_non_alphanumeric': 0.13080684596577016, 'fraction_numerical': 0.018490220048899754, 'mean_word_length': 2.816326530612245, 'pattern_counts': {'":': 0, '<': 35, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2234961', 'n_tokens_mistral': 2464, 'n_tokens_neox': 2317, 'n_words': 460}