X-Git-Url: https://git.wpitchoune.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fnvidia.c;h=99df9967556d9f00afc6728b2ede8ffcfaab6c12;hb=c3632937977f27dbe33c26409026e396672f12e1;hp=e2e06027c922ecbabe8fbf4a3fc04c514988b138;hpb=45c8086f97097df36ba8cd0552f152be80f79b12;p=psensor.git diff --git a/src/lib/nvidia.c b/src/lib/nvidia.c index e2e0602..99df996 100644 --- a/src/lib/nvidia.c +++ b/src/lib/nvidia.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2011 jeanfi@gmail.com + * Copyright (C) 2010-2014 jeanfi@gmail.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -33,9 +33,7 @@ Display *display; -/* - Returns the temperature (Celcius) of a NVidia GPU. -*/ +/* Returns the temperature (Celsius) of a NVIDIA GPU. */ static int get_temp(struct psensor *sensor) { int temp; @@ -51,23 +49,125 @@ static int get_temp(struct psensor *sensor) if (res == True) return temp; - fprintf(stderr, _("ERROR: failed to retrieve nvidia temperature\n")); + log_debug(_("NVIDIA proprietary driver not used or cannot " + "retrieve NVIDIA GPU temperature.")); + return 0; +} + +static double get_usage_att(char *atts, char *att) +{ + char *c, *key, *strv, *s; + size_t n; + double v; + + c = atts; + + v = UNKNOWN_DBL_VALUE; + while (*c) { + s = c; + n = 0; + while (*c) { + if (*c == '=') + break; + c++; + n++; + } + + key = strndup(s, n); + + if (*c) + c++; + + n = 0; + s = c; + while (*c) { + if (*c == ',') + break; + c++; + n++; + } + + strv = strndup(s, n); + if (!strcmp(key, att)) + v = atoi(strv); + + free(key); + free(strv); + + if (v != UNKNOWN_DBL_VALUE) + break; + + while (*c && (*c == ' ' || *c == ',')) + c++; + } + + return v; +} + +static int get_usage(struct psensor *sensor) +{ + char *temp; + Bool res; + + res = XNVCTRLQueryTargetStringAttribute(display, + NV_CTRL_TARGET_TYPE_GPU, + sensor->nvidia_id, + 0, + NV_CTRL_STRING_GPU_UTILIZATION, + &temp); + + if (res == True) + return get_usage_att(temp, "graphics"); + + log_debug(_("NVIDIA proprietary driver not used or cannot " + "retrieve NVIDIA GPU usage.")); return 0; } -static struct psensor *create_sensor(int id, int values_len) +static struct psensor *create_temp_sensor(int id, int values_len) { char name[200]; char *sid; struct psensor *s; + int t; sprintf(name, "GPU%d", id); - sid = malloc(strlen("nvidia") + 1 + strlen(name) + 1); - sprintf(sid, "nvidia %s", name); + sid = malloc(strlen("NVIDIA") + 1 + strlen(name) + 1); + sprintf(sid, "NVIDIA %s", name); - s = psensor_create(sid, strdup(name), - SENSOR_TYPE_NVIDIA_TEMP, values_len); + t = SENSOR_TYPE_NVCTRL | SENSOR_TYPE_GPU | SENSOR_TYPE_TEMP; + + s = psensor_create(sid, + strdup(name), + strdup(_("NVIDIA GPU")), + t, + values_len); + + s->nvidia_id = id; + + return s; +} + +static struct psensor *create_usage_sensor(int id, int values_len) +{ + char name[200]; + char *sid; + struct psensor *s; + int t; + + sprintf(name, "GPU%d graphics", id); + + sid = malloc(strlen("NVIDIA") + 1 + strlen(name) + 1); + sprintf(sid, "NVIDIA %s", name); + + t = SENSOR_TYPE_NVCTRL | SENSOR_TYPE_GPU | SENSOR_TYPE_USAGE; + + s = psensor_create(sid, + strdup(name), + strdup(_("NVIDIA GPU")), + t, + values_len); s->nvidia_id = id; @@ -76,9 +176,9 @@ static struct psensor *create_sensor(int id, int values_len) /* Opens connection to X server and returns the number - of NVidia GPUs. + of NVIDIA GPUs. - Return 0 if no NVidia gpus or cannot get information. + Return 0 if no NVIDIA gpus or cannot get information. */ static int init() { @@ -87,8 +187,7 @@ static int init() display = XOpenDisplay(NULL); if (!display) { - fprintf(stderr, - _("ERROR: Cannot open connection to X Server\n")); + log_err(_("Cannot open connection to X11 server.")); return 0; } @@ -96,7 +195,7 @@ static int init() XNVCTRLQueryTargetCount(display, NV_CTRL_TARGET_TYPE_GPU, &n)) return n; - fprintf(stderr, _("ERROR: Cannot retrieve NVidia information\n")); + log_err(_("Failed to retrieve NVIDIA information.")); return 0; } @@ -109,8 +208,12 @@ void nvidia_psensor_list_update(struct psensor **sensors) while (*ss) { s = *ss; - if (s->type == SENSOR_TYPE_NVIDIA_TEMP) - psensor_set_current_value(s, get_temp(s)); + if (s->type & SENSOR_TYPE_NVCTRL) { + if (s->type & SENSOR_TYPE_TEMP) + psensor_set_current_value(s, get_temp(s)); + else if (s->type & SENSOR_TYPE_USAGE) + psensor_set_current_value(s, get_usage(s)); + } ss++; } @@ -126,7 +229,16 @@ struct psensor **nvidia_psensor_list_add(struct psensor **sensors, ss = sensors; for (i = 0; i < n; i++) { - s = create_sensor(i, values_len); + s = create_temp_sensor(i, values_len); + + tmp = psensor_list_add(ss, s); + + if (ss != tmp) + free(ss); + + ss = tmp; + + s = create_usage_sensor(i, values_len); tmp = psensor_list_add(ss, s);