Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 187197
b: refs/heads/master
c: d49129a
h: refs/heads/master
i:
  187195: 11d79b5
v: v3
  • Loading branch information
Randy Dunlap authored and Linus Torvalds committed Mar 12, 2010
1 parent 2b30c7a commit ef78ae9
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 171 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: e61863099f58e458f08c101da87da752a1e009f5
refs/heads/master: d49129accc21ddb2e779d375dacafb612b1bd28d
2 changes: 1 addition & 1 deletion trunk/Documentation/Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
obj-m := DocBook/ accounting/ auxdisplay/ connector/ \
filesystems/configfs/ ia64/ networking/ \
filesystems/configfs/ ia64/ laptops/ networking/ \
pcmcia/ spi/ timers/ video4linux/ vm/ watchdog/src/
2 changes: 2 additions & 0 deletions trunk/Documentation/laptops/00-INDEX
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
- This file
acer-wmi.txt
- information on the Acer Laptop WMI Extras driver.
dslm.c
- Simple Disk Sleep Monitor program
laptop-mode.txt
- how to conserve battery power using laptop-mode.
sony-laptop.txt
Expand Down
8 changes: 8 additions & 0 deletions trunk/Documentation/laptops/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# kbuild trick to avoid linker error. Can be omitted if a module is built.
obj- := dummy.o

# List of programs to build
hostprogs-y := dslm

# Tell kbuild to always build the programs
always := $(hostprogs-y)
166 changes: 166 additions & 0 deletions trunk/Documentation/laptops/dslm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
/*
* dslm.c
* Simple Disk Sleep Monitor
* by Bartek Kania
* Licenced under the GPL
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>

#ifdef DEBUG
#define D(x) x
#else
#define D(x)
#endif

int endit = 0;

/* Check if the disk is in powersave-mode
* Most of the code is stolen from hdparm.
* 1 = active, 0 = standby/sleep, -1 = unknown */
static int check_powermode(int fd)
{
unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
int state;

if (ioctl(fd, HDIO_DRIVE_CMD, &args)
&& (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
&& ioctl(fd, HDIO_DRIVE_CMD, &args)) {
if (errno != EIO || args[0] != 0 || args[1] != 0) {
state = -1; /* "unknown"; */
} else
state = 0; /* "sleeping"; */
} else {
state = (args[2] == 255) ? 1 : 0;
}
D(printf(" drive state is: %d\n", state));

return state;
}

static char *state_name(int i)
{
if (i == -1) return "unknown";
if (i == 0) return "sleeping";
if (i == 1) return "active";

return "internal error";
}

static char *myctime(time_t time)
{
char *ts = ctime(&time);
ts[strlen(ts) - 1] = 0;

return ts;
}

static void measure(int fd)
{
time_t start_time;
int last_state;
time_t last_time;
int curr_state;
time_t curr_time = 0;
time_t time_diff;
time_t active_time = 0;
time_t sleep_time = 0;
time_t unknown_time = 0;
time_t total_time = 0;
int changes = 0;
float tmp;

printf("Starting measurements\n");

last_state = check_powermode(fd);
start_time = last_time = time(0);
printf(" System is in state %s\n\n", state_name(last_state));

while(!endit) {
sleep(1);
curr_state = check_powermode(fd);

if (curr_state != last_state || endit) {
changes++;
curr_time = time(0);
time_diff = curr_time - last_time;

if (last_state == 1) active_time += time_diff;
else if (last_state == 0) sleep_time += time_diff;
else unknown_time += time_diff;

last_state = curr_state;
last_time = curr_time;

printf("%s: State-change to %s\n", myctime(curr_time),
state_name(curr_state));
}
}
changes--; /* Compensate for SIGINT */

total_time = time(0) - start_time;
printf("\nTotal running time: %lus\n", curr_time - start_time);
printf(" State changed %d times\n", changes);

tmp = (float)sleep_time / (float)total_time * 100;
printf(" Time in sleep state: %lus (%.2f%%)\n", sleep_time, tmp);
tmp = (float)active_time / (float)total_time * 100;
printf(" Time in active state: %lus (%.2f%%)\n", active_time, tmp);
tmp = (float)unknown_time / (float)total_time * 100;
printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
}

static void ender(int s)
{
endit = 1;
}

static void usage(void)
{
puts("usage: dslm [-w <time>] <disk>");
exit(0);
}

int main(int argc, char **argv)
{
int fd;
char *disk = 0;
int settle_time = 60;

/* Parse the simple command-line */
if (argc == 2)
disk = argv[1];
else if (argc == 4) {
settle_time = atoi(argv[2]);
disk = argv[3];
} else
usage();

if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
printf("Can't open %s, because: %s\n", disk, strerror(errno));
exit(-1);
}

if (settle_time) {
printf("Waiting %d seconds for the system to settle down to "
"'normal'\n", settle_time);
sleep(settle_time);
} else
puts("Not waiting for system to settle down");

signal(SIGINT, ender);

measure(fd);

close(fd);

return 0;
}
170 changes: 1 addition & 169 deletions trunk/Documentation/laptops/laptop-mode.txt
Original file line number Diff line number Diff line change
Expand Up @@ -779,172 +779,4 @@ Monitoring tool
---------------

Bartek Kania submitted this, it can be used to measure how much time your disk
spends spun up/down.

---------------------------dslm.c BEGIN-----------------------------------------
/*
* Simple Disk Sleep Monitor
* by Bartek Kania
* Licenced under the GPL
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <string.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <linux/hdreg.h>

#ifdef DEBUG
#define D(x) x
#else
#define D(x)
#endif

int endit = 0;

/* Check if the disk is in powersave-mode
* Most of the code is stolen from hdparm.
* 1 = active, 0 = standby/sleep, -1 = unknown */
int check_powermode(int fd)
{
unsigned char args[4] = {WIN_CHECKPOWERMODE1,0,0,0};
int state;

if (ioctl(fd, HDIO_DRIVE_CMD, &args)
&& (args[0] = WIN_CHECKPOWERMODE2) /* try again with 0x98 */
&& ioctl(fd, HDIO_DRIVE_CMD, &args)) {
if (errno != EIO || args[0] != 0 || args[1] != 0) {
state = -1; /* "unknown"; */
} else
state = 0; /* "sleeping"; */
} else {
state = (args[2] == 255) ? 1 : 0;
}
D(printf(" drive state is: %d\n", state));

return state;
}

char *state_name(int i)
{
if (i == -1) return "unknown";
if (i == 0) return "sleeping";
if (i == 1) return "active";

return "internal error";
}

char *myctime(time_t time)
{
char *ts = ctime(&time);
ts[strlen(ts) - 1] = 0;

return ts;
}

void measure(int fd)
{
time_t start_time;
int last_state;
time_t last_time;
int curr_state;
time_t curr_time = 0;
time_t time_diff;
time_t active_time = 0;
time_t sleep_time = 0;
time_t unknown_time = 0;
time_t total_time = 0;
int changes = 0;
float tmp;

printf("Starting measurements\n");

last_state = check_powermode(fd);
start_time = last_time = time(0);
printf(" System is in state %s\n\n", state_name(last_state));

while(!endit) {
sleep(1);
curr_state = check_powermode(fd);

if (curr_state != last_state || endit) {
changes++;
curr_time = time(0);
time_diff = curr_time - last_time;

if (last_state == 1) active_time += time_diff;
else if (last_state == 0) sleep_time += time_diff;
else unknown_time += time_diff;

last_state = curr_state;
last_time = curr_time;

printf("%s: State-change to %s\n", myctime(curr_time),
state_name(curr_state));
}
}
changes--; /* Compensate for SIGINT */

total_time = time(0) - start_time;
printf("\nTotal running time: %lus\n", curr_time - start_time);
printf(" State changed %d times\n", changes);

tmp = (float)sleep_time / (float)total_time * 100;
printf(" Time in sleep state: %lus (%.2f%%)\n", sleep_time, tmp);
tmp = (float)active_time / (float)total_time * 100;
printf(" Time in active state: %lus (%.2f%%)\n", active_time, tmp);
tmp = (float)unknown_time / (float)total_time * 100;
printf(" Time in unknown state: %lus (%.2f%%)\n", unknown_time, tmp);
}

void ender(int s)
{
endit = 1;
}

void usage()
{
puts("usage: dslm [-w <time>] <disk>");
exit(0);
}

int main(int argc, char **argv)
{
int fd;
char *disk = 0;
int settle_time = 60;

/* Parse the simple command-line */
if (argc == 2)
disk = argv[1];
else if (argc == 4) {
settle_time = atoi(argv[2]);
disk = argv[3];
} else
usage();

if (!(fd = open(disk, O_RDONLY|O_NONBLOCK))) {
printf("Can't open %s, because: %s\n", disk, strerror(errno));
exit(-1);
}

if (settle_time) {
printf("Waiting %d seconds for the system to settle down to "
"'normal'\n", settle_time);
sleep(settle_time);
} else
puts("Not waiting for system to settle down");

signal(SIGINT, ender);

measure(fd);

close(fd);

return 0;
}
---------------------------dslm.c END-------------------------------------------
spends spun up/down. See Documentation/laptops/dslm.c

0 comments on commit ef78ae9

Please sign in to comment.