mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   Software (https://www.mersenneforum.org/forumdisplay.php?f=10)
-   -   Prime95 version 27.7 / 27.9 (https://www.mersenneforum.org/showthread.php?t=16779)

chris2be8 2012-05-28 16:42

The code would also have "interesting" behavior on a system using EBCDIC. But that's not very likely to occur in the real world. But I could believe some unicode variant doing strange things.

Chris

KingKurly 2012-05-31 18:39

Modern Linux seems to use /sys/class/power_supply/ instead of /proc/acpi/battery/ -- is there any chance we can have support for Linux battery detection updated?

Looks like you could either examine /sys/class/power_supply/BAT0/status or just /sys/class/power_supply/AC/online ... instead of parsing the old /proc/acpi/battery/BAT0/state, it looks like /sys/class/power_supply/AC/online returns a 0 (battery) or 1 (AC). So this should actually simplify the code a bit, and it will stop us from using a deprecated interface. Anyone using a later 2.6 or any 3.x kernel without the deprecated CONFIG_ACPI_PROCFS_POWER option enabled will not have a /proc/acpi/battery/BAT0/state at all!

I had always wondered why battery detection wasn't working right, and now I know. :) Hopefully it's an easy fix. Let me know if I can be of any assistance in testing. I would be happy to unset that kernel option and check a new build.

Dubslow 2012-05-31 18:44

[QUOTE=KingKurly;300861]Modern Linux seems to use /sys/class/power_supply/ instead of /proc/acpi/battery/ -- is there any chance we can have support for Linux battery detection updated?

Looks like you could either examine /sys/class/power_supply/BAT0/status or just /sys/class/power_supply/AC/online ... instead of parsing the old /proc/acpi/battery/BAT0/state, it looks like /sys/class/power_supply/AC/online returns a 0 (battery) or 1 (AC). So this should actually simplify the code a bit, and it will stop us from using a deprecated interface. Anyone using a later 2.6 or any 3.x kernel without the deprecated CONFIG_ACPI_PROCFS_POWER option enabled will not have a /proc/acpi/battery/BAT0/state at all!

I had always wondered why battery detection wasn't working right, and now I know. :) Hopefully it's an easy fix. Let me know if I can be of any assistance in testing. I would be happy to unset that kernel option and check a new build.[/QUOTE]Huh, Ubuntu 12.04 (Linux 3.2.x) worked out of the box with the battery detection. I have on idea whether or not Ubuntu sets that option or not though.

KingKurly 2012-05-31 21:20

[QUOTE=Dubslow;300862]Huh, Ubuntu 12.04 (Linux 3.2.x) worked out of the box with the battery detection. I have on idea whether or not Ubuntu sets that option or not though.[/QUOTE]
Any kernel compiled with the CONFIG_ACPI_PROCFS_POWER option that enables deprecated interfaces will work. I'm proposing that we go ahead and use the proper non-deprecated interface, when available. Ubuntu seems to provide both interfaces (/proc and /sys). To confirm, check: grep ACPI_PROCFS_POWER /boot/config-`uname -r` (Note: those are backticks.)

I don't know why Ubuntu chose to keep that interface around, but I just checked a 10.10 VM that I have and yes, it is enabled there too. On my personal machine, it is not enabled. I am a little surprised that Ubuntu would keep that deprecated code active in a 2012 release, but I guess they would have to support people who don't understand why things that used the old interface suddenly stopped working. :wink: I am reluctant to enable such an option when it is clear that the way forward is through /sys rather than /proc.

[URL]http://cateee.net/lkddb/web-lkddb/ACPI_PROCFS_POWER.html[/URL]

Perhaps we should read from /sys, if that fails then we read from /proc, and if that fails then we assume AC. (Today, we already do exactly that except we don't check /sys first...) The changes to the software should be limited to just a few lines of the OnBattery function in linux/os_routines.c and linux64/os_routines.c (which seem to be identical).

Dubslow 2012-05-31 22:07

[QUOTE=KingKurly;300880]Ubuntu seems to provide both interfaces (/proc and /sys). To confirm, check: grep ACPI_PROCFS_POWER /boot/config-`uname -r` (Note: those are backticks.)[/quote]
[code]CONFIG_ACPI_PROCFS_POWER=y[/code]
That's Ubuntu 11.04, kernel 2.6; note that 11.04 and 10.10 are old releases, and don't represent 12.04. The laptop I mentioned is now borked, so I can't test 12.04 myself right now.
[/QUOTE]

Prime95 2012-05-31 22:43

[QUOTE=KingKurly;300861]Modern Linux seems to use /sys/class/power_supply/ instead of /proc/acpi/battery/ -- is there any chance we can have support for Linux battery detection updated?[/QUOTE]

If anyone can provide updated code for me to include that would be great. The new code should handle both the old and new standards.

Xyzzy 2012-05-31 23:38

12.04 LTS

[CODE]$ grep ACPI_PROCFS_POWER /boot/config-`uname -r`
CONFIG_ACPI_PROCFS_POWER=y
$ uname -a
Linux m 3.2.0-24-generic #39-Ubuntu SMP Mon May 21 16:52:17 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux[/CODE]

KingKurly 2012-05-31 23:54

[QUOTE=Prime95;300890]If anyone can provide updated code for me to include that would be great. The new code should handle both the old and new standards.[/QUOTE]
I apologize for any formatting/tabbing/spacing issues in this post. Please ask if any clarification is required. I have tested this solution only on my own machine, so please do not unleash it on an unsuspecting public until you are comfortable with it! :smile:

As part of this section of code in linux/os_routines.c and linux64/os_routines.c:
[CODE]
#elif defined (__linux__)
FILE *fd;
char buf[180];
int ac_state;

ac_state = -1;
fd = fopen ("/proc/acpi/battery/BAT0/state", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
char *p;
p = strstr (buf, "charging state:");
if (p == NULL) continue;
if (strstr (p+14, "discharging") != NULL) ac_state = 0;
else if (strstr (p+14, "charging") != NULL) ac_state = 1;
else if (strstr (p+14, "charged") != NULL) ac_state = 1;
}
fclose (fd);
} ####### NEW CODE GOES HERE ########
return (ac_state == 0);
#else
[/CODE]Insert this:
[CODE] else {
fd = fopen ("/sys/class/power_supply/AC/online", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
ac_state = atoi(buf);
}
}
}
[/CODE]So the final product should look like:

[CODE]
#elif defined (__linux__)
FILE *fd;
char buf[180];
int ac_state;

ac_state = -1;
fd = fopen ("/proc/acpi/battery/BAT0/state", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
char *p;
p = strstr (buf, "charging state:");
if (p == NULL) continue;
if (strstr (p+14, "discharging") != NULL) ac_state = 0;
else if (strstr (p+14, "charging") != NULL) ac_state = 1;
else if (strstr (p+14, "charged") != NULL) ac_state = 1;
}
fclose (fd);
} else {
fd = fopen ("/sys/class/power_supply/AC/online", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
ac_state = atoi(buf);
}
}
}
return (ac_state == 0);
#else
[/CODE]...If you want a quick standalone app to test my changes (and please, do test them on an Ubuntu machine at least!)

[CODE]
/* actest.c, no warranty, etc */

#include <stdio.h>
#define TRUE 1
#define FALSE 0

int onBattery(void);

int main()
{
int battery;
battery = onBattery();
if (battery == TRUE)
printf("BATTERY\n");
else if (battery == FALSE)
printf("AC\n");
else
printf("Uh oh\n");

return 0;
}

int onBattery(void)
{
FILE *fd;
char buf[180];
int ac_state;

ac_state = -1;
fd = fopen ("/proc/acpi/battery/BAT0/state", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
char *p;
p = strstr (buf, "charging state:");
if (p == NULL) continue;
if (strstr (p+14, "discharging") != NULL) ac_state = 0;
else if (strstr (p+14, "charging") != NULL) ac_state = 1;
else if (strstr (p+14, "charged") != NULL) ac_state = 1;
}
fclose (fd);
} else {
fd = fopen ("/sys/class/power_supply/AC/online", "r");
if (fd != NULL) {
while (fgets (buf, sizeof (buf), fd) != NULL) {
ac_state = atoi(buf);
}
}
}
return (ac_state == 0);
}

[/CODE]... I'd have provided a diff of the code instead of putting it out how I did, but I don't know what formats you prefer, and the code should be pretty easy to plug in. I hope. :geek: And if the call to atoi is too slow, there are other ways to do it. The file is simply a 1 or a 0.

I am too used to coding in Ruby; I forgot how picky C is in certain situations...!

chalsall 2012-05-31 23:59

[QUOTE=Prime95;300890]If anyone can provide updated code for me to include that would be great. The new code should handle both the old and new standards.[/QUOTE]

Add the red below to os_routines.c, in OnBattery():

[code] FILE *fd;
char buf[180];
int ac_state;

ac_state = -1;
[COLOR="Red"] fd = fopen ("/sys/class/power_supply/AC/online", "r");
if (fd != NULL) {
fscanf(fd, "%d", &ac_state);
fclose (fd);
return (ac_state == 0);
}
[/COLOR] fd = fopen ("/proc/acpi/battery/BAT0/state", "r");
[/CODE]

Note: not tested. But it should be correct.

KingKurly 2012-06-01 00:00

Prime95: In case it's not obvious from the code, this will attempt the old way first, and then if that didn't work, it will try the new way. You might decide to flip it around. I didn't check how often this gets called, so I don't know how tight it needs to be. Maybe it is worth caching which one exists and using it every time? Or maybe that is overkill.

Everyone: If anyone wants to help out, copy/paste the contents of the last code block (the one labeled actest.c) into a file called actest.c. Change into the directory containing that file and type 'make actest'. Then type './actest' both while on battery and on AC. Results from Ubuntu would be especially appreciated, or perhaps I can convince my stepfather to let me borrow his Ubuntu laptop for a few minutes...

KingKurly 2012-06-01 00:02

[QUOTE=chalsall;300896]Note: not tested. But it should be correct.[/QUOTE]
Works on my box. I think I like your solution better because it's less code and avoids the call to atoi. You win this round...! :bow:


All times are UTC. The time now is 06:29.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.