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')
|
project('tuxclocker')
|
||||||
|
|
||||||
|
cc = meson.get_compiler('c')
|
||||||
|
|
||||||
|
incdir = include_directories('src/include')
|
||||||
|
|
||||||
subdir('src')
|
subdir('src')
|
||||||
|
@ -9,7 +9,10 @@
|
|||||||
enum tc_assignable_value_category {TC_ASSIGNABLE_RANGE, TC_ASSIGNABLE_ENUM};
|
enum tc_assignable_value_category {TC_ASSIGNABLE_RANGE, TC_ASSIGNABLE_ENUM};
|
||||||
|
|
||||||
// Is the range double or integer
|
// 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;
|
double min, max;
|
||||||
@ -32,8 +35,6 @@ typedef struct {
|
|||||||
char **properties;
|
char **properties;
|
||||||
} tc_assignable_enum_t;
|
} tc_assignable_enum_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct tc_assignable_node_t {
|
typedef struct tc_assignable_node_t {
|
||||||
// Assignable name eg. fan speed
|
// Assignable name eg. fan speed
|
||||||
char *name;
|
char *name;
|
||||||
@ -54,3 +55,12 @@ typedef struct tc_assignable_node_t {
|
|||||||
uint16_t children_count;
|
uint16_t children_count;
|
||||||
struct tc_assignable_node_t **children_nodes;
|
struct tc_assignable_node_t **children_nodes;
|
||||||
} tc_assignable_node_t;
|
} 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>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
// Categories for modules.
|
||||||
|
enum tc_module_category {
|
||||||
|
TC_CATEGORY_ASSIGNABLE,
|
||||||
|
TC_CATEGORY_PROPERTY
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct tc_module_t {
|
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;
|
} 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('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