Notes about programming

Floating point arithmetic

What every computer scientist should know about floating point arithmetic

http://perso.ens-lyon.fr/jean-michel.muller/goldberg.pdf

How to write files properly on Unix

Ted Ts'o, https://bugs.edge.launchpad.net/ubuntu/+source/linux/+bug/317781/comments/54

OK, so let me explain what's going on a bit more explicitly. There are application programmers who are rewriting application files like this:

  1. open and read file ~/.kde/foo/bar/baz
  2. : fd = open("~/.kde/foo/bar/baz", O_WRONLY|O_TRUNC|O_CREAT) --- this truncates the file
  3. : write(fd, buf-of-new-contents-of-file, size-of-new-contents-of-file)
  4. : close(fd)

Slightly more sophisticated application writers will do this:

  1. open and read file ~/.kde/foo/bar/baz
  2. : fd = open("~/.kde/foo/bar/baz.new", O_WRONLY|O_TRUNC|O_CREAT)
  3. : write(fd, buf-of-new-contents-of-file, size-of-new-contents-of-file)
  4. : close(fd)
  5. : rename("~/.kde/foo/bar/baz.new", "~/.kde/foo/bar/baz")

What emacs (and very sophisticated, careful application writers) will do is this:

  1. open and read file ~/.kde/foo/bar/baz
  2. : fd = open("~/.kde/foo/bar/baz.new", O_WRONLY|O_TRUNC|O_CREAT)
  3. : write(fd, buf-of-new-contents-of-file, size-of-new-contents-of-file)
  4. : fsync(fd) --- and check the error return from the fsync
  5. : close(fd)
  6. : rename("~/.kde/foo/bar/baz", "~/.kde/foo/bar/baz~") --- this is optional
  7. : rename("~/.kde/foo/bar/baz.new", "~/.kde/foo/bar/baz")

The fact that series (1) and (2) works at all is an accident. Ext3 in its default configuration happens to have the property that 5 seconds after (1) and (2) completes, the data is safely on disk. (3) is the only thing which is guaranteed not to lose data. For example, if you are using laptop mode, the 5 seconds is extended to 30 seconds.

Now the one downside with (3) is that fsync() is a heavyweight operation.

Basic valgrind usage

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes
--num-callers=20 --track-fds=yes ./your_program arg1 arg2 ...