Thursday, February 01, 2007

Off-Topic :: Wait-Free/Lock-less synchronization crash course

Well, results are not that good as I have hoped. (In depth info at Wikipedia. Read the first reference on the page written by Maurice Herlihy in 1993.)

  1. Rule of thumb: lock-less can only be data structures which synchronize using single datum.
  2. Compare-And-Swap( ptr, old, new ) can be used for implementation of atomic counters. The operation is supported by all high performance platforms (e.g. PowerPC & IA-32).
  3. One cannot make lock-less FIFO for N:M (N readers/M writers) nor for 1:M (1 reader/M writers) configurations. Seems that 1:1 (1 read and 1 writer) only possible configuration and in fact it doesn't require any special support at CPU level. (Reference to rule of thumb: FIFO requires two data items for implementation - head/tail (or next/prev).)
  4. Stack (LIFO) can be implemented wait-free/lock-less using Compare-And-Swap() op, since it needs only single pointer for implementation - head - pointing to first element to remove/last element inserted.
Conclusion:
  1. Unixes were 100% right putting pipes at foundation of I/O: pipe can be implemented as couple of FIFOs and as long as pipe isn't shared between more than 2 applications, it can be completely lock free.
  2. Stack (along with Compare-And-Swap op) allows to implement memory management (for static block size) very efficiently. (Edit1. In preemptive SMP OS, that might lead to situation when Compare-And-Swap would succeed despite fact that state of queue already changed. Proper implementation for multiple CPUs would use several (at minimum 2) stacks. Allocations are made from one stack, freeing is done on next stack. Allocation function rotates stacks when detects that current stack is empty. Allocation is failed when all stacks were queried at least once and all are empty. Alternatively, one can introduce additional counter: generation counter. That way Compare-And-Swap needs to be able to write double word. When element is allocated, generation counter is incremented. When element is freed, we put on stack pair - pointer and generation counter - which would be with high probability unique.)
  3. Message passing systems suck big time because (i) 1:1 FIFOs are inapplicable and (ii) it is impossible to optimize memory allocation with lock-less stack since it is impossible to tell where the message would end up. (The later can only be implemented in worst case scenario of shared memory.)

Monday, January 29, 2007

vim 7.0 :: tabs / tabbed editing

Not that I fun of all the GUI niceties, but some people cannot live without mouse and think :b#/:bn/:bp are bore. So vim7 has added a way for mouse fans (*) to work with multiple files.

For tab fans, Linux.com published intro into vim7' tabs: Vim tips: Using tabs.

(*) How people edit text files with mouse is beyond me. Do they use charmap or what? [/sarcasm]

Monday, November 20, 2006

Sample Ex/Vim Ranges

Here we go.

:%s/[a-z]/\u&/g

Substitute in all lines (the range defined by '%') all lower case latin letters ('[a-z]') with upper case letters ('[A-Z]'). Substitute in all lines (the range defined by '%') every lower case latin letter ('[a-z]') with upper-case letter ('\u&', see for more info :h s/\u).

:<'>' w new_file_from_selection.txt

Write ('w') all selected lines ("<'>'") into new_file_from_selection.txt. (You do not need to type that "<'>'" thing. Select lines in visual mode (entered by Shift-V) and then press ':' - vim will put the <'>' in prompt line for you)

:5,+99 w new_file.txt

Write ('w') to the file "new_file.txt" lines: 5th and next 99 ones included, total of 100 lines. (Provided that the actual file has minimum 1054 lines).

:0,$ ! tac

Filter ('!') all lines ('%' is simple shortcut for '0,$') through the external application 'tac'. The filter command would then replace all affected lines with the output of the application - in that case the lines would reappear in inverse order, thanks to the 'tac' command. ('tac' is of course opposite of 'cat'. man tac.).

:<'>' ! wc -l

That would replace all selected (in visual mode) lines with the count of selected lines, as counted by 'wc -l'.

And to conclude, the most useless (unless you're vim scripting addict) range example:

:.=

Print current line (range '.') number (command '=').

Edit1 Fix the uppercase command, as per anon comment. It should have been some real weird booze I had that day. N.B. more optimal is of course this: :%s/.\+/\U&/.

ZQ

Friday, October 20, 2006

Off Topic :: GNU Arch (TLA) Commands Quick Reference

User identification

$ tla my-id  "John Doe <user@aol.com>"
$ tla my-id # to print currently set id

Create Archive

$ mkdir  ~/{archives}
$ tla make-archive user@aol.com--2006-quickref ~/{archives}/2006-quickref

Find Archives

$ tla archives                    # to print all available archives
$ tla whereis-archive user@aol.com--2006-quickref

Default Archive

$ tla  my-default-archive  user@aol.com--2006-quickref
$ tla my-default-archive # to print it
$ tla my-default-archive -d # to delete the preference

Provisioning Archive Space

$ tla archive-setup hello-world--mainline--1.0
$ tla categories # prints hello-world
$ tla branches hello-world # prints hello-world--mainline
$ tla versions hello-world--mainline # prints hello-world--mainline--1.0

Initializing before Import

$ cd ~/wd/hello-world
$ tla init-tree hello-world--mainline--1.0
$ tla tree-root # prints /home/jdoe/wd/hello-world
$ tla tree-version # prints user@aol.com--2006-quickref/hello-world--mainline--1.0
$ tla log-versions # prints user@aol.com--2006-quickref/hello-world--mainline--1.0
$ tla set-tree-version [new-version-name]
$ tla add-log-version [new-log-name]
$ tla remove-log-version [existing-log-name]

Checking Inventory

$ tla inventory --names --source  # to see what arch classifies as sources
$ tla inventory --source --ids # to see ids given by arch to sources
$ tla inventory --names --backups # to see what arch classifies as backups
$ tla inventory --junk | xargs rm # remove all what arch think is junk

Adding/Removing Files

$ tla add hw.c main.c
$ tla delete hw.c
$ mv hw.c hello.c
$ tla move hw.c hello.c
$ tla tree-lint # to see if all clean, tla won't import/ci from unclean directory

Import (Initial check in)

$ tla make-log                    # create log file and print its name
$ vim `tla make-log` # edit log in vim
$ tla import # copy working copy into archive
$ tla revisions hello-world--mainline--1.0 # prints base-0
$ tla revisions --summary --creator --date hello-world--mainline--1.0
$ tla log-revisions
$ tla logs hello-world--mainline--0.1 # prints base-0
$ tla logs --summary --creator --date hello-world--mainline--1.0
$ tla cat-log hello-world--mainline--1.0--base-0

Committing Changes

$ tla changes --diffs             # or (in tla 1.3) just "tla diff"
$ tla make-log # create log, required
$ tla commit # do it, creates patch-1
$ tla commit -s "Summary" -L "Log Message" # commit with log auto generated
$ tla revisions --summary hello-world--mainline--1.0 # last revision info
$ tla logs --summary hello-world--mainline--1.0 # last log entry info

Checking Out

$ tla my-default-archive          # check where is default archive is
$ tla whereis-archive user@aol.com--2006-example # display local/net path
$ tla categories # lists available project in default archive "hello-world"
$ tla branches hello-world # lists available branches of the project "*--mainline"
$ tla versions hello-world--mainline # lists available version of the branch "*--0.1"
$ tla revisions hello-world--mainline--0.1 # lists available revisions base-0 & patch-1
$ tla get hello-world--mainline--0.1 hello-world # check out most recent revision of into "hello-world" directory, or
$ tla get hello-world--mainline--0.1--base-0 hello-world # check out specific revision
$ ls # should list "hello-world"

Update (Replay)

$ tla undo              # back off local changes
$ tla replay # get latest patches from repository
$ tla redo # reapply local changes
$ tla update # all of three steps above with one command.

Networked Archives

$ tla register-archive lord@emf.net--2003b          
http://regexps.srparish.net/{archives}/lord@emf.net--2003b # HTTP, R/O
$ tla register-archive lord@regexps.com--2002
ftp://ftp.regexps.com/{archives}/lord@regexps.com--2002 # FTP, R/W
$ tla register-archive user@aol.com--2006
sftp://random.homeunix.org/home/jdoe/{archives}/2006-quickref # SFTP, R/W
$ tla my-default-archive [archive-name] # and the rest is just like described above

Mirroring (Locally) Network Archives

$ tla register-archive lord@emf.net--2003b-SOURCE $remote_location   # once
$ tla make-archive --mirror-from lord@emf.net--2003b-SOURCE $local_location # once
$ tla archive-mirror lord@emf.net--2003b # repeat to pull latest changes

Mirroring (Remotely) Local Archives

$ tla make-archive --mirror mine@somewhere.com $remote_location      # once
$ tla archive-mirror mine@somewhere.com # repeat to push latest changes

P.S. Made after this tutorial.

Wednesday, October 18, 2006

Thursday, October 12, 2006

Vim Cookbook by Steve Oualline

Vim Cookbook by Steve Oualline. Interesting reading. Lots of little tips.

P.S. Delves a bit into ranges supported in ex commands. I still cannot get myself to write entry on vim ranges.

Friday, September 15, 2006

VIM 7 :: RE: turn off paren/parenthesis/whatever highlighting

The fix submitted before isn't reliable. That piece of magic in .vimrc does the job:

let loaded_matchparen = 1

It tells some plug-in/script/whatever that it has already did the job. If you put that in .vimrc - it would think that way always and would not load anymore. Nice.

P.S. The Tip was found here :help pi_paren.txt. It would be all really nice if computers had a special interface to read my mind - and tell me how the devels named particular feature. That way I will not need to waste weeks to find the corresponding help entry.

Wednesday, September 13, 2006

VIM7 :: file type detection

New in VIM7 is file type detection. To get info whether it is present/activated try that:

:filetype

and that to turn it off:

:filetype off

File types are made to allow bulk customization for particular file type. At moment it doesn't provide any advantages over plain :au - but probably more to come in future.

P.S. :filetype off must be at top of .vimrc - it tries to manage everything so many options changed before would be reset.

P.P.S. Relevant help pages/see also: :help filetype, :help 'filetype' and :help ftplugin.