ruby + linux /proc/acpi deadlock?

W

William Morgan

Hi Rubyists,

I'm working on a predictive battery monitor in Ruby. One issue I've
found is that when I read /proc/acpi/battery/BAT1/state and there are
other Ruby threads running, the read seems to freeze. This doesn't
happen with other files in /proc/acpi (that I've tried, at least) and
doesn't happen if there's no threading going on.

Here's some code that hangs on the read for me:

PROC_FILE = "/proc/acpi/battery/BAT1/state" # freezes
#PROC_FILE = "/proc/acpi/power_resource/PFAN/state" # doesn't freeze
FREEZE = true # when this is true, the "read" thread freezes for me

def read
puts "=== starting to read at #{Time.now}"
IO.foreach(PROC_FILE) { |l| puts "> #{l}" }
puts "=== done reading at #{Time.now}"
end

Thread.new do
while true
puts "zzz..."
sleep 1
end
end if FREEZE

while true
read
sleep 1
end

This might be some weird kernel interaction thing that's specific to my
buggy BIOS, but I thought I'd check and see if others experienced the
same behavior.

Thanks,
 
R

Roeland Moors

Hi Rubyists,

I'm working on a predictive battery monitor in Ruby. One issue I've
found is that when I read /proc/acpi/battery/BAT1/state and there are
other Ruby threads running, the read seems to freeze. This doesn't
happen with other files in /proc/acpi (that I've tried, at least) and
doesn't happen if there's no threading going on.

Here's some code that hangs on the read for me:

PROC_FILE = "/proc/acpi/battery/BAT1/state" # freezes
#PROC_FILE = "/proc/acpi/power_resource/PFAN/state" # doesn't freeze

I have the same beavior with these files:
PROC_FILE = "/proc/acpi/battery/BAT0/state" # freezes
PROC_FILE = "/proc/acpi/power_resource/PRCF/state" # doesn't freeze

I can't explain it :)
 
W

William Morgan

Excerpts (reformatted) from Roeland Moors's mail of 20 Aug 2004 (EDT):
I have the same beavior with these files:
PROC_FILE = "/proc/acpi/battery/BAT0/state" # freezes
PROC_FILE = "/proc/acpi/power_resource/PRCF/state" # doesn't freeze

I can't explain it :)

So, guys, is this a bug in Ruby, or what?

(details: ruby 1.8.1 (2004-02-03) [i386-linux] and Linux kernel 2.6.8.1)
 
M

Martin Pirker

William Morgan said:
I'm working on a predictive battery monitor in Ruby.

back when I was starting in Ruby one of the first small tries was...
(fix code first, terminal is eating some chars)

run with no window decoration
not very pretty, but does the job till today :)

Martin

--------------------------------------------------------------------------

$stdout.sync = true

def resize (w,h) # resize terminal
printf("\033[8;#{h};#{w}t")
end

def readme
r1 = IO.readlines("/proc/acpi/battery/BAT1/state").grep(/remaining/)
r1 = /\s*(\d*)\smWh/.match(r1[0])[1].to_s if r1.size == 1
return r1
end

resize (10,1)

r = IO.readlines("/proc/acpi/battery/BAT1/state")
if /present.+no/ === r[0] then
printf("\n no batt ")
sleep 3
exit 1
end

or1 = readme
printf("\n%s 000",or1.rjust(5).tr(" ","0"))
nr1 = readme

loop do
nr1 = readme
if (nr1 != or1)
if or1.to_i <3000 then
'xgamma -gamma 0.3' # <---- fix me!
sleep 0.3
'xgamma -gamma 1.0' # <---- fix me!
end
printf("\n%s %s",nr1.rjust(5).tr(" ","0"),(or1.to_i-nr1.to_i).to_s.rjust(3).tr(" ","0"))
or1 = nr1
end
sleep 15
end
 
R

Roeland Moors

Excerpts (reformatted) from Roeland Moors's mail of 20 Aug 2004 (EDT):
I have the same behavior with these files:
PROC_FILE = "/proc/acpi/battery/BAT0/state" # freezes
PROC_FILE = "/proc/acpi/power_resource/PRCF/state" # doesn't freeze

I can't explain it :-(

So, guys, is this a bug in Ruby, or what?

(details: ruby 1.8.1 (2004-02-03) [i386-linux] and Linux kernel 2.6.8.1)

I also have the problem with these files:
PROC_FILE = "/proc/acpi/fan/CFAN/state" # freezes
PROC_FILE = "/proc/acpi/ac_adapter/ACAD/state" # doesn't freezes

My system:
- Linux laptop 2.6.6 #1 Wed Jul 7 20:20:50 CEST 2004 i686 GNU/Linux
- ruby 1.8.2 (2004-07-29) [i386-linux]
- Asus L3C
- Debian testing
 
W

William Morgan

Excerpts (reformatted) from Martin Pirker's mail of 23 Aug 2004 (EDT):
back when I was starting in Ruby one of the first small tries was...
(fix code first, terminal is eating some chars)

Check out http://tdbatmon.rubyforge.org and you can see what I've done.
It turns out my particular battery is pretty linear so all my
fancy-pants prediction is wasted, but it's still kinda cool, IMO.
 
W

William Morgan

Excerpts (reformatted) from Roeland Moors's mail of 23 Aug 2004 (EDT):
I also have the problem with these files:
PROC_FILE = "/proc/acpi/fan/CFAN/state" # freezes
PROC_FILE = "/proc/acpi/ac_adapter/ACAD/state" # doesn't freezes

My system:
- Linux laptop 2.6.6 #1 Wed Jul 7 20:20:50 CEST 2004 i686 GNU/Linux
- ruby 1.8.2 (2004-07-29) [i386-linux]
- Asus L3C
- Debian testing

The issue persists with Ruby 1.8.2 preview 2 on my i686 machine with
kernel 2.6.8.1, so I suggest this is a real-life bug.

Is there a better way of reporting it than just announcing it here?
 
N

Nobuyoshi Nakada

Hi,

At Fri, 27 Aug 2004 08:40:47 +0900,
William Morgan wrote in [ruby-talk:110600]:
The issue persists with Ruby 1.8.2 preview 2 on my i686 machine with
kernel 2.6.8.1, so I suggest this is a real-life bug.

Is there a better way of reporting it than just announcing it here?

Maybe, strace log?
 
W

William Morgan

Excerpts (reformatted) from Nobuyoshi Nakada's mail of 26 Aug 2004 (EDT):
Maybe, strace log?

Under Ruby 1.8.2 with kernel 2.6.8.1, with this code:

PROC_FILE = "/proc/acpi/battery/BAT1/state"
Thread.new { sleep 1000 }
puts "=== starting to read at #{Time.now}"
IO.foreach(PROC_FILE) { }
puts "=== done reading at #{Time.now}"

I get the following strace output:

[...]
write(1, "=== starting to read at Fri Aug "..., 53=== starting to read at Fri Aug 27 10:26:58 EDT 2004
) = 53
sigprocmask(SIG_BLOCK, NULL, []) = 0
open("/proc/acpi/battery/BAT1/state", O_RDONLY|O_LARGEFILE) = 3
sigprocmask(SIG_BLOCK, NULL, []) = 0
gettimeofday({1093616818, 153673}, NULL) = 0
select(4, [3], [], [], {999, 998330}

and it just hangs on that select. If I remove the Thread.new call, I get
this strace output:

[...]
open("/proc/acpi/battery/BAT1/state", O_RDONLY|O_LARGEFILE) = 3
sigprocmask(SIG_BLOCK, NULL, []) = 0
fstat64(3, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x402b7000
read(3, "present: yes\ncap"..., 1024) = 188
read(3, "", 1024) = 0
close(3) = 0
munmap(0x402b7000, 4096) = 0
gettimeofday({1093616966, 205006}, NULL) = 0
write(1, "=== done reading at Fri Aug "..., 53=== done reading at Fri Aug 27 10:29:26 EDT 2004
) = 53

If I change the filename to /proc/acpi/power_resource/PFAN/state in the
code with threads, select() is used, but it doesn't block.

So it seems like select() on reading particular files in /proc will
block. I guess the question is, is this a kernel bug or a kernel
feature?
 
N

nobu.nokada

Hi,

At Fri, 27 Aug 2004 23:52:08 +0900,
William Morgan wrote in [ruby-talk:110651]:
So it seems like select() on reading particular files in /proc will
block. I guess the question is, is this a kernel bug or a kernel
feature?

Though I'm not a developer of the kernel, it sounds like a bug.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,764
Messages
2,569,565
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top