Tuesday 24 January 2012

open() using O_WRONLY | O_RDWR

One of the lesser known Linux features is that one can open a file with the flags O_WRONLY | O_RDWR.   One requires read and write permission to perform the open(), however, the flags indicate that no reading or writing is to be done on the file descriptor.   It is useful for operations such as ioctl() where we also want to ensure we don't actually do any reading or writing to a device.  A bunch of utilities such as LILO seem to use this obscure feature. 

LILO defines these flags as O_NOACCESS as follows:

 #ifdef O_ACCMODE  
 # define O_NOACCESS O_ACCMODE  
 #else  
 /* open a file for "no access" */  
 # define O_NOACCESS 3  
 #endif  

..as in this example, you may find these flags more widely known as O_NOACCESS even though they are not defined in the standard fcntl.h headers.

Below is a very simple example of the use of O_WRONLY | O_RDWR:

 #include <stdio.h>  
 #include <stdlib.h>  
 #include <unistd.h>  
 #include <sys/ioctl.h>  
 #include <fcntl.h>  
 int main(int argc, char **argv)  
 {  
      int fd;  
      struct winsize ws;  
      if ((fd = open("/dev/tty", O_WRONLY | O_RDWR)) < 0) {  
           perror("open /dev/tty failed");  
           exit(EXIT_FAILURE);  
      }  
      if (ioctl(fd, TIOCGWINSZ, &ws) == 0)  
           printf("%d x %d\n", ws.ws_row, ws.ws_col);  
      close(fd);  
      exit(EXIT_SUCCESS);  
 }  

It is a little arcane and not portable but also an interesting feature to know about.

Friday 20 January 2012

C ternary operator hack

Here is a simple bit of C that sets either x or y to value v depending on the value of c..

if (c)   
    x = v;  
else  
    y = v;  

..but why not "improve" this by using the C ternary operator ? : as follows:

 *(c ? &x : &y) = v;  

Now, how does this shape up when compiled on an x86 with gcc -O2 ?  Well, the first example compiles down to a test and a branch where as the second example uses a conditional move instruction (cmove) and avoids the test and branch and is faster code.  Result!

OK, so this isn't rocket science, but does show that a little bit of abuse of the ternary operator can save me a few cycles if the compiler is clued up to use cmove.

Tuesday 17 January 2012

Improving Battery Life in Ubuntu Precise 12.04 LTS (part 2)

Last month I wrote about the investigations being undertaken to identify any suitable power savings for Ubuntu Precise 12.04 LTS.  Armed with a suitably accurate 6.5 digit precision Fluke digital multimeter I worked my way through the Kernel Team Power Management Blueprint measuring many numerous configurations and ways to possibly save power.

A broad range of areas were examined, from kernel tweaks, hardware settings to disk wake-ups and application wakeup events.

Quite a handful of misbehaving applications have been identified ranging from frequent unnecessary wake-ups on poll() and select() calls to rather verbose logging of debug messages that stop the disk from going into power saving states.

We also managed to identify and remove pm-utils power.d scripts that didn't actually save any power and even consumed more power on newer Solid State Drives.    By carefully analysing all the PowerTop recommendations we also identified a subset of device power management savings that are shown to be useful and save power across a wide range of machines.   After crowd-source testing these tweaks we have now added them into pm-utils for Ubuntu Precise 12.04 LTS by default.  I'm very grateful to the Ubuntu community for participating in the testing and feedback.

I've written a brief summary of all the test results, however, the full results can be found in the various subdirectories here.   I've also written a very simple set of recommendations to help application developers avoid mistakes that lead to power wasting applications.

We've also set up a Power Management Wiki page that has links to the following:

* Identifying Power Sucking Applications
* Aggressive Link Power Management call for testing
* PCIe Active State Power Management call for testing (now complete)
* Updates to pm utils scripts call for testing (now complete)

..and probably the most useful:

* Power Saving Tweaks

The Power Saving Tweaks page lists a selection of tweaks that can be employed to save power on various machines.  Unfortunately with some hardware these tweaks cause lock-ups or rendering bugs, so they cannot be rolled out by default unless we can find either a definitive list of the broken hardware or a large enough whitelist to enable these on a useful set of working hardware.  Some of the tweaks cannot be rolled out for all machines as users want specific functionality enabled by default, for example, we need to enable Bluetooth for users with bluetooth keyboards and so it is up to the user to chose to disable Bluetooth to save 1-2 Watts of power.

I've also set-up a PPA with a few tools to help measure power and track down misbehaving wake-up events and CPU intensive applications.  These tools don't replace tools like PowerTop and top, but do allow me to track trends on a system over a long running period.   You may find these useful too.

We also have a Ubuntu Power Consumption Project set up to help us track bugs related to power consumption issues and regressions.  

Last, but no way least,  I'd like to thank Steve Langasek and Martin Pitt for all their help with the pm-utils and various fixes to power sucking applications.

Monday 2 January 2012

Commodore 64 is 30

The C64 boot screen (running in vice)
30 years ago this week Commodore unveiled the Commodore 64 (C64) - a MOS 6510 based 8 bit microcomputer with a 64K of RAM. I was given a C64 and 1530 C2N cassette deck for Christmas when I was 15 years old and I eventually acquired a 1541 floppy drive. The C64's VIC II graphics chip was a powerful device that had various graphics modes, 8 pixels of smooth scrolling and 8 21x24 pixel sprites. The Sound chip (SID) sported 3 voices with 4 different waveform generators and fine control of the amplitude envelopes as well as filtering and tricks like ring modulation and synchronization.

The lack of a powerful BASIC interpreter directed my attention to learning 6502 assembler so I could start writing 3D wire frame vector graphics. I learned how to write cycle accurate timing code to drive the VIC II to make side borders disappear and with raster interrupts to make the the top and bottom borders disappear too. I also wedged in my own BASIC tokenizer and interpreter to extend the BASIC to provide better structured programming (while/wend, procedures, repeat/until) and sound, graphics and disk support - all this taught me how to structure large projects in assembler and how to write compact and efficient code.

I spent hours pouring over the disassembled C64 BASIC and Kernal ROMs and learned the art of reverse engineering from the object code. I figured out the tape format, analyzed the read/write characteristics of the tape drive head and re-wrote my own tape turbo loaders.
With the aid of an annotated ROM disassembly of the 1541 floppy drive I figured out how to write disk turbos and I hacked up my own fast formatting tools and my own file system.

By the time I was 17 I had acquired the the Super C Compiler and I learned how to write C on a system that had a 15 minute edit-compile-link-run turnaround cycle(!).

Elite on the C64.
All this 1MHz 8 bit goodness taught me valuable lessons in programming efficient code and the trade-off between compact code and fast code. I learned how to twiddle hardware, bit bang data down wires and push a system to squeeze a little more performance out of it.







I was fortunate to have the time and energy and the right hardware available in my formative years, so I am grateful for Commodore for producing the quirky and hackable C64.

See also  http://www.reghardware.com/2012/01/02/commodore_64_30_birthday