1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
use libc::c_int;
use raw;
use std::marker::PhantomData;

use {Core, L3, Phantom, Raw};

/// An instance of a system on a chip.
pub struct Processor<'l> {
    raw: Raw<raw::Processor>,
    phantom: Phantom<'l, raw::Processor>,
}

struct Items<'l, T> {
    length: usize,
    position: usize,
    raw: Raw<raw::Processor>,
    phantom: PhantomData<(&'l raw::Processor, &'l raw::root_system, T)>,
}

trait Reader {
    fn read(raw: Raw<raw::Processor>, i: usize) -> Self;
}

/// An iterator over cores.
pub type Cores<'l> = Items<'l, Core<'l>>;

/// An iterator over L3 caches.
pub type L3s<'l> = Items<'l, L3<'l>>;

impl<'l> Processor<'l> {
    /// Return an iterator over cores.
    #[inline]
    pub fn cores(&self) -> Cores<'l> {
        Cores {
            length: unsafe { raw::Processor_numCore(self.raw.0) } as usize,
            position: 0,
            raw: self.raw,
            phantom: PhantomData,
        }
    }

    /// Return an iterator over L3 caches.
    #[inline]
    pub fn l3s(&self) -> L3s<'l> {
        L3s {
            length: unsafe { raw::Processor_numL3(self.raw.0) } as usize,
            position: 0,
            raw: self.raw,
            phantom: PhantomData,
        }
    }
}

impl<'l> Drop for Processor<'l> {
    #[inline]
    fn drop(&mut self) {
        unsafe { raw::delete_Processor(debug_not_null!(self.raw.0)) };
    }
}

impl<'l, T> Items<'l, T> {
    /// Return the total number of items regardless of how many have been
    /// traversed.
    #[inline]
    pub fn len(&self) -> usize { self.length }
}

impl<'l, T> Iterator for Items<'l, T> where T: Reader {
    type Item = T;

    fn next(&mut self) -> Option<T> {
        if self.position == self.length {
            None
        } else {
            self.position += 1;
            Some(<T as Reader>::read(self.raw, self.position - 1))
        }
    }
}

impl<'l> Reader for Core<'l> {
    #[inline]
    fn read(raw: Raw<raw::Processor>, i: usize) -> Core<'l> {
        unsafe {
            ::core::from_raw((debug_not_null!(raw::Processor_cores(raw.0, i as c_int)), raw.1))
        }
    }
}

impl<'l> Reader for L3<'l> {
    #[inline]
    fn read(raw: Raw<raw::Processor>, i: usize) -> L3<'l> {
        use std::mem::transmute;
        unsafe {
            let raw = (debug_not_null!(raw::Processor_l3array(raw.0, i as c_int)), raw.1);
            transmute(::cache::from_raw(raw))
        }
    }
}

#[inline]
pub fn from_raw<'l>(raw: (*mut raw::Processor, *mut raw::root_system)) -> Processor<'l> {
    Processor { raw: raw, phantom: PhantomData }
}