Skip to content

Commit

Permalink
basic cpu_temp
Browse files Browse the repository at this point in the history
  • Loading branch information
uliss committed May 7, 2024
1 parent 9896bfe commit 46c1e84
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 37 deletions.
30 changes: 23 additions & 7 deletions ceammc/ext/src/hw/hw_cpu_temp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,23 +12,39 @@
* this file belongs to.
*****************************************************************************/
#include "hw_cpu_temp.h"
#include "ceammc_containers.h"
#include "ceammc_factory.h"

HwCpuTemp::HwCpuTemp(const PdArgs& args)
: BaseObject(args)
: DispatchedObject<BaseObject>(args)
, cpu_temp_(0, ceammc_hw_cputemp_free)
{
createOutlet();

#ifndef WITH_SMC
OBJ_ERR << "supports only MacOSX at this moment";
#endif
cpu_temp_.reset(ceammc_hw_cputemp_create(
this,
[](void* user, const char* label, float value) {
auto this_ = static_cast<HwCpuTemp*>(user);
if (this_) {
AtomArray<2> data { gensym(label), value };
this_->listTo(0, data.view());
}
},
{ subscriberId(), [](size_t id) { Dispatcher::instance().send({ id, 0 }); } }));
}

void HwCpuTemp::onBang()
{
#ifdef WITH_SMC
return floatTo(0, smc_.cpuTemperature());
#endif
if (cpu_temp_)
ceammc_hw_cputemp_get(cpu_temp_.get());
}

bool HwCpuTemp::notify(int)
{
if (cpu_temp_)
return ceammc_hw_cputemp_process(cpu_temp_.get());
else
return false;
}

void setup_hw_cpu_temp()
Expand Down
14 changes: 6 additions & 8 deletions ceammc/ext/src/hw/hw_cpu_temp.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,18 @@
#define HW_CPU_TEMP_H

#include "ceammc_object.h"

#ifdef WITH_SMC
#include "apple/smc.h"
#endif
#include "ceammc_poll_dispatcher.h"
#include "hw_rust.hpp"

using namespace ceammc;

class HwCpuTemp : public BaseObject {
#ifdef WITH_SMC
apple_smc::SMC smc_;
#endif
class HwCpuTemp : public DispatchedObject<BaseObject> {
std::unique_ptr<ceammc_hw_cputemp, void (*)(ceammc_hw_cputemp*)> cpu_temp_;

public:
HwCpuTemp(const PdArgs& args);
void onBang() override;
bool notify(int) final;
};

void setup_hw_cpu_temp();
Expand Down
1 change: 1 addition & 0 deletions ceammc/extra/rust/hw/.vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"cSpell.words": [
"ceammc",
"cputemp",
"dests",
"devinfo",
"etype",
Expand Down
1 change: 1 addition & 0 deletions ceammc/extra/rust/hw/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ c_str_macro = "1.0.3"
env_logger = "0.11.3"
gilrs = "0.10.5"
log = "0.4.21"
sysinfo = "0.30.12"
tokio = { version = "1.36", features = ["rt", "rt-multi-thread", "signal", "sync", "macros", "time"] }

[target.'cfg(windows)'.dependencies]
Expand Down
26 changes: 19 additions & 7 deletions ceammc/extra/rust/hw/hw_rust.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,18 @@ enum class ceammc_hw_printer_state {
UNKNOWN,
};

struct ceammc_hw_cputemp;

/// gamepad opaque type
struct ceammc_hw_gamepad;

struct ceammc_hw_notify_cb {
/// dispatcher ID
size_t id;
/// dispatcher callback (not NULL!)
void (*f)(size_t id);
};

struct ceammc_gamepad_err_cb {
/// pointer to user data
void *user;
Expand Down Expand Up @@ -123,13 +132,6 @@ struct ceammc_gamepad_listdev_cb {
void (*cb)(void *user, const ceammc_gamepad_dev_info *info);
};

struct ceammc_hw_notify_cb {
/// dispatcher ID
size_t id;
/// dispatcher callback (not NULL!)
void (*f)(size_t id);
};

struct ceammc_hw_printer_info {
const char *name;
const char *system_name;
Expand Down Expand Up @@ -161,6 +163,16 @@ struct ceammc_hw_error_cb {

extern "C" {

ceammc_hw_cputemp *ceammc_hw_cputemp_create(void *user,
void (*cb_temp)(void *user, const char *label, float cpu_temp),
ceammc_hw_notify_cb cb_notify);

void ceammc_hw_cputemp_free(ceammc_hw_cputemp *cpu_temp);

bool ceammc_hw_cputemp_get(ceammc_hw_cputemp *cpu_temp);

bool ceammc_hw_cputemp_process(ceammc_hw_cputemp *cpu_temp);

/// free gamepad
/// @param gp - pointer to gp
void ceammc_hw_gamepad_free(ceammc_hw_gamepad *gp);
Expand Down
16 changes: 2 additions & 14 deletions ceammc/extra/rust/hw/src/gamepad.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,15 @@ use std::{
use gilrs::{Axis, Button, EventType, Gilrs, PowerInfo};
use tokio::time::sleep;

use crate::hw_notify_cb;

#[allow(non_camel_case_types)]
#[repr(C)]
pub enum hw_gamepad_rc {
Ok = 0,
InvalidHandle,
}

#[allow(non_camel_case_types)]
#[repr(C)]
pub struct hw_notify_cb {
/// dispatcher ID
id: usize,
/// dispatcher callback (not NULL!)
f: extern "C" fn(id: usize),
}

impl hw_notify_cb {
fn notify(&self) {
(self.f)(self.id);
}
}

#[derive(Default, Debug)]
#[allow(non_camel_case_types)]
Expand Down
17 changes: 16 additions & 1 deletion ceammc/extra/rust/hw/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,23 @@ use std::{
os::raw::{c_char, c_void},
};

#[allow(non_camel_case_types)]
#[repr(C)]
pub struct hw_notify_cb {
/// dispatcher ID
id: usize,
/// dispatcher callback (not NULL!)
f: extern "C" fn(id: usize),
}

impl hw_notify_cb {
fn notify(&self) {
(self.f)(self.id);
}
}

pub mod gamepad;
// pub mod sysinfo;
pub mod sysinfo;
pub mod printers;

#[repr(C)]
Expand Down
146 changes: 146 additions & 0 deletions ceammc/extra/rust/hw/src/sysinfo.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
use std::{
ffi::CString,
os::raw::{c_char, c_void},
time::Duration,
};

use sysinfo::Components;

use crate::hw_notify_cb;

enum CpuTempReply {
Temp(CString, f32),
}

enum CpuTempRequest {
GetTemp,
Quit,
}

#[allow(non_camel_case_types)]
pub struct hw_cputemp {
rx: std::sync::mpsc::Receiver<CpuTempReply>,
tx: std::sync::mpsc::Sender<CpuTempRequest>,
user: *mut c_void,
cb_temp: Option<extern "C" fn(user: *mut c_void, label: *const c_char, cpu_temp: f32)>,
}

impl Drop for hw_cputemp {
fn drop(&mut self) {
if let Err(err) = self.tx.send(CpuTempRequest::Quit) {
log::error!("send error: {err}");
}
}
}

#[no_mangle]
pub extern "C" fn ceammc_hw_cputemp_create(
user: *mut c_void,
cb_temp: Option<extern "C" fn(user: *mut c_void, label: *const c_char, cpu_temp: f32)>,
cb_notify: hw_notify_cb,
) -> *mut hw_cputemp {
let (reply_tx, reply_rx) = std::sync::mpsc::channel::<CpuTempReply>();
let (req_tx, req_rx) = std::sync::mpsc::channel::<CpuTempRequest>();

std::thread::spawn(move || {
let mut components = Components::new_with_refreshed_list();
loop {
match req_rx.recv_timeout(Duration::from_millis(100)) {
Ok(data) => match data {
CpuTempRequest::Quit => {
log::debug!("[worker] quit");
break;
}
CpuTempRequest::GetTemp => {
for component in &mut components.iter_mut() {
component.refresh();

let str = component.label();

#[cfg(target_os = "macos")]
{
if !str.starts_with("GPU") && !str.starts_with("pACC") && !str.starts_with("eACC") {
continue;
}
}

let lbl = CString::new(str).unwrap_or_default();

let temp = component.temperature();
if temp.is_nan() { // skip
continue;
}
if let Err(err) = reply_tx.send(CpuTempReply::Temp(lbl, temp)) {
log::error!("[worker] send error: {err}");
break;
}

cb_notify.notify();
}
}
},
Err(err) => match err {
std::sync::mpsc::RecvTimeoutError::Timeout => continue,
std::sync::mpsc::RecvTimeoutError::Disconnected => break,
},
}
}
});

Box::into_raw(Box::new(hw_cputemp {
rx: reply_rx,
tx: req_tx,
user,
cb_temp,
}))
}

#[no_mangle]
pub extern "C" fn ceammc_hw_cputemp_get(cpu_temp: *mut hw_cputemp) -> bool {
if cpu_temp.is_null() {
log::error!("NULL cpu temp pointer");
return false;
}

let cpu_temp = unsafe { &mut *cpu_temp };
match cpu_temp.tx.send(CpuTempRequest::GetTemp) {
Ok(_) => true,
Err(err) => {
log::error!("[owner] send error: {err}");
false
}
}
}

#[no_mangle]
pub extern "C" fn ceammc_hw_cputemp_process(cpu_temp: *mut hw_cputemp) -> bool {
if cpu_temp.is_null() {
log::error!("NULL cpu temp pointer");
return false;
}

let cpu_temp = unsafe { &mut *cpu_temp };
loop {
match cpu_temp.rx.try_recv() {
Ok(reply) => match reply {
CpuTempReply::Temp(label, value) => cpu_temp
.cb_temp
.map(|f| f(cpu_temp.user, label.as_ptr(), value)),
},
Err(err) => match err {
std::sync::mpsc::TryRecvError::Empty => return true,
std::sync::mpsc::TryRecvError::Disconnected => {
log::error!("[owner] process results: {err}");
return false;
}
},
};
}
}

#[no_mangle]
pub extern "C" fn ceammc_hw_cputemp_free(cpu_temp: *mut hw_cputemp) {
if !cpu_temp.is_null() {
drop(unsafe { Box::from_raw(cpu_temp) });
}
}

0 comments on commit 46c1e84

Please sign in to comment.