mirror of
https://github.com/Lurkki14/tuxclocker.git
synced 2025-02-25 18:55:24 -06:00
Start nvidia module
This commit is contained in:
parent
d8a013dcba
commit
b15bd8c105
@ -1,3 +1,7 @@
|
||||
project('tuxclocker')
|
||||
|
||||
cc = meson.get_compiler('c')
|
||||
|
||||
incdir = include_directories('src/include')
|
||||
|
||||
subdir('src')
|
||||
|
@ -9,13 +9,16 @@
|
||||
enum tc_assignable_value_category {TC_ASSIGNABLE_RANGE, TC_ASSIGNABLE_ENUM};
|
||||
|
||||
// Is the range double or integer
|
||||
enum tc_assignable_range_data_type {TC_ASSIGNABLE_RANGE_INT, TC_ASSIGNABLE_RANGE_DOUBLE};
|
||||
enum tc_assignable_range_data_type {
|
||||
TC_ASSIGNABLE_RANGE_INT,
|
||||
TC_ASSIGNABLE_RANGE_DOUBLE
|
||||
};
|
||||
|
||||
typedef struct tc_assignable_range_double_t{
|
||||
typedef struct tc_assignable_range_double_t {
|
||||
double min, max;
|
||||
} tc_assignable_range_double_t;
|
||||
|
||||
typedef struct tc_assignable_range_int_t{
|
||||
typedef struct tc_assignable_range_int_t {
|
||||
int64_t min, max;
|
||||
} tc_assignable_range_int_t;
|
||||
|
||||
@ -32,8 +35,6 @@ typedef struct {
|
||||
char **properties;
|
||||
} tc_assignable_enum_t;
|
||||
|
||||
|
||||
|
||||
typedef struct tc_assignable_node_t {
|
||||
// Assignable name eg. fan speed
|
||||
char *name;
|
||||
@ -54,3 +55,12 @@ typedef struct tc_assignable_node_t {
|
||||
uint16_t children_count;
|
||||
struct tc_assignable_node_t **children_nodes;
|
||||
} tc_assignable_node_t;
|
||||
|
||||
/* Utility functions for assignables */
|
||||
// Allocates memory for a tunable node
|
||||
tc_assignable_node_t *tc_assignable_node_new();
|
||||
// Deallocates memory of the node
|
||||
void tc_assignable_node_destroy(tc_assignable_node_t *node);
|
||||
|
||||
// Add a child to a node
|
||||
int8_t tc_assignable_node_add_child(tc_assignable_node_t *node, tc_assignable_node_t *child);
|
||||
|
8
src/include/tc_common.h
Normal file
8
src/include/tc_common.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
// Common definitions for tuxclocker
|
||||
|
||||
// Error values
|
||||
#define TC_SUCCESS 0
|
||||
#define TC_EGENERIC (-1)
|
||||
#define TC_ENOMEM (-2)
|
@ -2,6 +2,21 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// Categories for modules.
|
||||
enum tc_module_category {
|
||||
TC_CATEGORY_ASSIGNABLE,
|
||||
TC_CATEGORY_PROPERTY
|
||||
};
|
||||
|
||||
|
||||
|
||||
typedef struct tc_module_t {
|
||||
enum tc_module_category category;
|
||||
const char *name;
|
||||
|
||||
// Initializes the module's internal state
|
||||
int8_t (*init_callback)();
|
||||
// Frees the internal memory of the module
|
||||
int8_t (*close_callback)();
|
||||
|
||||
} tc_module_t;
|
||||
|
0
src/lib/meson.build
Normal file
0
src/lib/meson.build
Normal file
27
src/lib/tc_assignable.c
Normal file
27
src/lib/tc_assignable.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <tc_common.h>
|
||||
#include <tc_assignable.h>
|
||||
|
||||
tc_assignable_node_t *tc_assignable_node_new() {
|
||||
tc_assignable_node_t *node = calloc(1, sizeof(tc_assignable_node_t));
|
||||
return node;
|
||||
}
|
||||
|
||||
void tc_assignable_node_destroy(tc_assignable_node_t *node) {
|
||||
// The name is allocated on the heap
|
||||
if (node->name != NULL) {
|
||||
free(node->name);
|
||||
}
|
||||
|
||||
free(node);
|
||||
}
|
||||
|
||||
int8_t tc_assignable_node_add_child(tc_assignable_node_t *parent, tc_assignable_node_t *child) {
|
||||
parent->children_count++;
|
||||
if ((parent->children_nodes = realloc(parent->children_nodes, parent->children_count)) == NULL) {
|
||||
return TC_ENOMEM;
|
||||
}
|
||||
parent->children_nodes[parent->children_count] = child;
|
||||
return TC_SUCCESS;
|
||||
}
|
@ -1 +1,7 @@
|
||||
# Define libtuxclocker target here since others depend on it
|
||||
libtuxclocker = shared_library('libtuxclocker',
|
||||
['lib/tc_assignable.c'],
|
||||
include_directories : incdir)
|
||||
|
||||
subdir('modules')
|
||||
subdir('lib')
|
||||
|
@ -1 +1,12 @@
|
||||
shared_library('libnvidia', 'nvidia.c')
|
||||
|
||||
libnvml = cc.find_library('nvidia-ml')
|
||||
libx = cc.find_library('X11')
|
||||
libxnvctrl = cc.find_library('XNVCtrl')
|
||||
|
||||
nvml_h = cc.has_header('nvml.h')
|
||||
|
||||
shared_library('libnvidia', 'nvidia_linux.c',
|
||||
include_directories : incdir,
|
||||
dependencies : [libnvml, libx, libxnvctrl],
|
||||
link_with : libtuxclocker)
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
#include "/opt/cuda/include/nvml.h"
|
||||
|
||||
#define MAX_GPUS 32
|
||||
|
||||
static nvmlDevice_t nvml_handles[MAX_GPUS];
|
82
src/modules/assignable/nvidia_linux.c
Normal file
82
src/modules/assignable/nvidia_linux.c
Normal file
@ -0,0 +1,82 @@
|
||||
#include "/opt/cuda/include/nvml.h"
|
||||
#include <X11/Xlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <tc_assignable.h>
|
||||
#include <tc_common.h>
|
||||
|
||||
#define MAX_GPUS 32
|
||||
|
||||
// Local function declarations
|
||||
static int8_t init();
|
||||
static int8_t close();
|
||||
static int8_t generate_assignable_tree();
|
||||
|
||||
static uint32_t gpu_count;
|
||||
static nvmlDevice_t nvml_handles[MAX_GPUS];
|
||||
static Display *dpy;
|
||||
static tc_assignable_node_t *root_node;
|
||||
|
||||
static int8_t init() {
|
||||
// Initialize library
|
||||
if (nvmlInit_v2() != NVML_SUCCESS) {
|
||||
return TC_EGENERIC;
|
||||
}
|
||||
|
||||
// Query GPU count
|
||||
if (nvmlDeviceGetCount(&gpu_count) != NVML_SUCCESS) {
|
||||
return TC_EGENERIC;
|
||||
}
|
||||
|
||||
if (gpu_count > MAX_GPUS) {
|
||||
return TC_ENOMEM;
|
||||
}
|
||||
|
||||
// Get nvml handles
|
||||
uint32_t valid_count = 0;
|
||||
for (uint8_t i = 0; i < gpu_count; i++) {
|
||||
nvmlDevice_t dev;
|
||||
|
||||
if (nvmlDeviceGetHandleByIndex_v2(i, &dev) == NVML_SUCCESS) {
|
||||
nvml_handles[valid_count] = dev;
|
||||
valid_count++;
|
||||
}
|
||||
}
|
||||
gpu_count = valid_count;
|
||||
|
||||
// Get X11 display
|
||||
if ((dpy = XOpenDisplay(NULL)) == NULL) {
|
||||
return TC_EGENERIC;
|
||||
}
|
||||
|
||||
// Generate the tree structure of assignables for every GPU. Free in close().
|
||||
generate_assignable_tree();
|
||||
|
||||
return TC_SUCCESS;
|
||||
}
|
||||
|
||||
static int8_t close() {
|
||||
|
||||
}
|
||||
|
||||
static int8_t generate_assignable_tree() {
|
||||
// Allocate memory for root node
|
||||
root_node = tc_assignable_node_new();
|
||||
|
||||
for (uint32_t i = 0; i < gpu_count; i++) {
|
||||
// Get GPU name and use it as the root item for GPU
|
||||
char gpu_name[NVML_DEVICE_NAME_BUFFER_SIZE];
|
||||
|
||||
if (nvmlDeviceGetName(nvml_handles[i], gpu_name, NVML_DEVICE_NAME_BUFFER_SIZE) != NVML_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
// Got the name, append the item to the root item
|
||||
tc_assignable_node_t *gpu_name_node = tc_assignable_node_new();
|
||||
gpu_name_node->name = strdup(gpu_name);
|
||||
|
||||
// Append to the root node
|
||||
if (tc_assignable_node_add_child(root_node, gpu_name_node) != TC_SUCCESS) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user