<commit_before>use core::cmp::Ordering;
use core::ops::{Add, Sub};

use scheduler;

pub const NANOS_PER_MICRO: i32 = 1000;
pub const NANOS_PER_MILLI: i32 = 1000000;
pub const NANOS_PER_SEC: i32 = 1000000000;

/// A duration
#[derive(Copy, Clone)]
pub struct Duration {
    /// The seconds
    pub secs: i64,
    /// The nano seconds
    pub nanos: i32,
}

impl Duration {
    /// Create a new duration
    pub fn new(mut secs: i64, mut nanos: i32) -> Self {
        while nanos >= NANOS_PER_SEC || (nanos > 0 && secs < 0) {
            secs += 1;
            nanos -= NANOS_PER_SEC;
        }

        while nanos < 0 && secs > 0 {
            secs -= 1;
            nanos += NANOS_PER_SEC;
        }

        Duration {
            secs: secs,
            nanos: nanos,
        }
    }

    /// Get the current duration
    pub fn monotonic() -> Self {
        let ret;
        unsafe {
            let reenable = scheduler::start_no_ints();
            ret = ::clock_monotonic;
            scheduler::end_no_ints(reenable);
        }
        ret
    }

    /// Get the realtime
    pub fn realtime() -> Self {
        let ret;
        unsafe {
            let reenable = scheduler::start_no_ints();
            ret = ::clock_realtime;
            scheduler::end_no_ints(reenable);
        }
        ret
    }

    /// Sleep the duration
    pub fn sleep(&self) {
        let start_time = Duration::monotonic();
        loop {
            let elapsed = Duration::monotonic() - start_time;
            if elapsed > *self {
                break;
            } else {
                unsafe {
                    let disable = scheduler::start_ints();
                    scheduler::end_ints(disable);
                }
            }
        }
    }
}

impl Add for Duration {
    type Output = Duration;

    fn add(self, other: Self) -> Self {
        Duration::new(self.secs + other.secs, self.nanos + other.nanos)
    }
}

impl Sub for Duration {
    type Output = Duration;

    fn sub(self, other: Self) -> Self {
        Duration::new(self.secs - other.secs, self.nanos - other.nanos)
    }
}

impl PartialEq for Duration {
    fn eq(&self, other: &Self) -> bool {
        let dif = *self - *other;
        dif.secs == 0 && dif.nanos == 0
    }
}

impl PartialOrd for Duration {<commit_msg>Context switch in sleep loop<commit_after>use core::cmp::Ordering;
use core::ops::{Add, Sub};

use scheduler;
use scheduler::context;

pub const NANOS_PER_MICRO: i32 = 1000;
pub const NANOS_PER_MILLI: i32 = 1000000;
pub const NANOS_PER_SEC: i32 = 1000000000;

/// A duration
#[derive(Copy, Clone)]
pub struct Duration {
    /// The seconds
    pub secs: i64,
    /// The nano seconds
    pub nanos: i32,
}

impl Duration {
    /// Create a new duration
    pub fn new(mut secs: i64, mut nanos: i32) -> Self {
        while nanos >= NANOS_PER_SEC || (nanos > 0 && secs < 0) {
            secs += 1;
            nanos -= NANOS_PER_SEC;
        }

        while nanos < 0 && secs > 0 {
            secs -= 1;
            nanos += NANOS_PER_SEC;
        }

        Duration {
            secs: secs,
            nanos: nanos,
        }
    }

    /// Get the current duration
    pub fn monotonic() -> Self {
        let ret;
        unsafe {
            let reenable = scheduler::start_no_ints();
            ret = ::clock_monotonic;
            scheduler::end_no_ints(reenable);
        }
        ret
    }

    /// Get the realtime
    pub fn realtime() -> Self {
        let ret;
        unsafe {
            let reenable = scheduler::start_no_ints();
            ret = ::clock_realtime;
            scheduler::end_no_ints(reenable);
        }
        ret
    }

    /// Sleep the duration
    pub fn sleep(&self) {
        let start_time = Duration::monotonic();
        loop {
            let elapsed = Duration::monotonic() - start_time;
            if elapsed > *self {
                break;
            } else {
                unsafe { context::context_switch(false) };
            }
        }
    }
}

impl Add for Duration {
    type Output = Duration;

    fn add(self, other: Self) -> Self {
        Duration::new(self.secs + other.secs, self.nanos + other.nanos)
    }
}

impl Sub for Duration {
    type Output = Duration;

    fn sub(self, other: Self) -> Self {
        Duration::new(self.secs - other.secs, self.nanos - other.nanos)
    }
}

impl PartialEq for Duration {
    fn eq(&self, other: &Self) -> bool {
        let dif = *self - *other;
        dif.secs == 0 && dif.nanos == 0
    }
}

impl PartialOrd for Duration {
{'fraction_non_alphanumeric': 0.11657117672983694, 'fraction_numerical': 0.01895107977082415, 'mean_word_length': 1.6466472303206998, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, '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': '7110713', 'n_tokens_mistral': 1564, 'n_tokens_neox': 1432, 'n_words': 387}