tag:blogger.com,1999:blog-65017112024-03-07T16:21:45.319-05:00codebytezcode lessonscadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.comBlogger28125tag:blogger.com,1999:blog-6501711.post-688595277961734672016-05-14T17:21:00.003-04:002016-05-14T17:21:48.359-04:00What do the // in a URI stand for?The url spec basically has a scheme id followed by a colon, followed by a scheme specific part (RFC3986)<br />
<br />
As you can see, the mailto scheme basically has just the email address, so something like mailto:codebytez@example.com is a complete URL.<br />
<br />
For the http scheme, the slashes have a historical reason. In the old days (pre-1990s) many networks used double slash to indicate that the first token is a hostname.<br />
<br />
Therefore <span style="font-family: "courier new" , "courier" , monospace;">/someplace/file.txt</span> would mean <span style="font-family: "courier new" , "courier" , monospace;">file.txt</span> under the <span style="font-family: "courier new" , "courier" , monospace;">/someplace</span> directory on the current file system but <span style="font-family: "courier new" , "courier" , monospace;">//someplace/file.txt</span> would mean <span style="font-family: "courier new" , "courier" , monospace;">/file.txt</span> at server "<span style="font-family: "courier new" , "courier" , monospace;">someplace</span>"<br />
<br />
Therefore the full translation of <span style="font-family: Courier New, Courier, monospace;">http://example.com/item1</span> would be:<br />
<br />
<br />
<table><tbody>
<tr><td><span style="font-family: Courier New, Courier, monospace;">http:</span></td><td>Use the http protocol</td></tr>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">//example.com</span></td><td>Connect to example.com</td></tr>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">/item.html</span></td><td>Ask the server for item.html</td></tr>
</tbody></table>
<br />
(I've omitted port and fragment for simplicity)<br />
<br />
The // is technically unnecessary to distinguish from local server because http requires that you need to specify a host to connect to.<br />
<br />
When the file uri was originally implemented, it had the following forms and meanings<br />
<br />
<table><tbody>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">file:./file.txt</span></td><td>Load file from current directory (Browser's working directory)</td></tr>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">file:/directory/file.txt</span></td><td>Load file from root of current host</td></tr>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">file://mount/file.txt</span></td><td>Attempts to load file.txt from mount point. If mount point is invalid, attempts to load file.txt from root directory</td></tr>
<tr><td><span style="font-family: "courier new" , "courier" , monospace;">file:///directory/file.txt</span></td><td>Loads file.txt from root directory. This is the same as above with mount token missing.</td></tr>
</tbody></table>
<br />
In modern browsers, everything upto the first slash is pretty much ignored. The mountpoint still works but often the browser ignores it and treats <span style="font-family: "courier new" , "courier" , monospace;">file://mount/file.txt</span> as <span style="font-family: "courier new" , "courier" , monospace;">file:///file.txt</span>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-51150128912623815312013-03-04T11:13:00.002-05:002013-03-04T11:19:03.394-05:005 minutes to linux securityMuch better than I can ever explain it:<br />
<br />
<a href="http://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servers">http://plusbryan.com/my-first-5-minutes-on-a-server-or-essential-security-for-linux-servers</a>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-47799889801065320662012-05-25T00:44:00.000-04:002012-05-25T20:24:15.540-04:00Simple way to use getoptsMost getopts examples show complex case switches in a while loop and complicated logic to set defaults.<br />
<br />
In general, getopts is very simple to use:<br />
<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">#!/bin/bash</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"># example options -t and -a with args and -x with no args</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">C=0</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">while getopts xt:a: arg</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">do</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> # remove punctuations to prevent shell injection</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> V=$(echo $OPTARG | perl -lpe 's/[^a-zA-Z0-9_. ]/_/gs')</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> eval "$arg='${V:-true}'"</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> if [ -n "$OPTARG" ]; then C=$[C+2] ; else C=$[C+1] ; fi</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">done</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">shift $C</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">echo $@ # args after params</span><br />
<div>
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<span style="font-family: 'Courier New', Courier, monospace;"># in case option was not passed set defaults</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">t=${t:-template}</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">#err check/usage</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">if [ -z "$a" ] </span><br />
<span style="font-family: 'Courier New', Courier, monospace;">then </span><br />
<span style="font-family: 'Courier New', Courier, monospace;"> echo Usage: $0 [-x] [-t text] -a address; exit 1; </span><br />
<span style="font-family: 'Courier New', Courier, monospace;">fi</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="font-family: 'Courier New', Courier, monospace;"># use it!</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">echo T is $t and A is $a and X is $x</span><br />
<div>
<br /></div>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-86128791664643248172012-04-25T22:55:00.003-04:002012-04-29T12:50:04.573-04:00Installing FreeNAS using virt-installA simple way to install FreeNAS on a VM is to use virt-install. I had to add a sata controller since I have more than 4 drives:<br />
<br />
<br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;">virt-install -nFreeNAS -r 6144 --vcpus=2 --autostart --os-variant=freebsd7 --accelerate --network bridge=br0,model=rtl8139 --disk path=/mnt/img/FreeNAS.img --disk path=/dev/sda2,bus=sata --disk path=/dev/sdb2,bus=sata --disk path=/dev/sdb1,bus=sata -c /mnt/img/FreeNAS8.2.0B3.iso --vnc --controller sata</span><br />
<div>
<br />
Note: I ended up not using the FreeNAS on a VM because attaching the host partitions to the VM ended up giving terrible performance on disk IO. This was true for both UFS and ZFS on fully or paravirtualized drivers.<br />
<br />
Abandoning this approach and having the host manage its own disks greatly improved performance and am very happy with it. For every compartmentalized task such as media servers I'm still using a VM with the filesystem from the host mounted over NFS.</div>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-58351887875367313322012-04-21T18:56:00.002-04:002012-04-21T19:06:36.727-04:00<h2>
Running FreeNAS on a virtual machine</h2>
I prefer to have my physical servers bare, containing only the barest changes required to run virtual machines. Thus, when I need to migrate to a different hardware, its as simple as moving the VMs.<br />
<br />
Usually, I only have the base server packages running with the packages needed to act as a virtual machine host. On linux systems, this translates to libvirt and related utilities. In addition, I also usually install hardware monitoring packages to check for overheating, etc.<br />
<br />
The only config change I make are usually to make the network interface bridged:<br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"># The loopback network interface</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;">auto lo</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;">iface lo inet loopback</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"># The primary network interface</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;">auto br0</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;">iface br0 inet dhcp</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"> bridge_ports eth0</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"> bridge_fd 9</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"> bridge_hello 2</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"> bridge_maxage 12</span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"> bridge_stp off</span><br />
<br />
<br />
So when I need to install FreeNAS, I wanted it to directly interact with the underlying disks yet the ability to simply ship my VM (and disks) to another server if desired. So I decided to install FreeNAS on a VM using qemu.<br />
<h3>
<b>Here is how I finally got it working:</b></h3>
Your root filesystem where FreeNAS is installed should be ide. FreeNAS refuses to install on other types. You can get it to work on scsi by adding a boot option, but using ide is a lot simpler.<br />
<br />
Once you install the system, you need to enable virtio for paravirtualized devices.<br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;"><br /></span></span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"><span style="background-color: #f9f9f9;">mount -uw /</span><span style="background-color: #f9f9f9;">wget http://people.freebsd.org/~kuriyama/virtio/8.2/virtio-kmod-0.228301.tbz</span><span style="background-color: #f9f9f9;">pkg_add virtio-kmod-0.228301.tbz > /tmp/out</span></span><span style="background-color: #f9f9f9; font-family: inherit;"><br /></span><br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;">/tmp/out contains instructions to enable virtio drivers. Essentially, change /boot/loader.conf to load virtio drivers and /etc/rc.conf and /etc/fstab to point to the virtualized device names.</span><span style="background-color: #f9f9f9;"><br /></span></span><br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;"><br /></span></span><br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;">You can then go to the admin console and setup the volumes. My ZIL partitions were only 2GB and it failed to create a zpool with zil. So I had to create a volume without a ZIL, ssh into the box and add it manually using:</span></span><br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;"><br /></span></span><br />
<span style="color: blue; font-family: 'Courier New', Courier, monospace;"><span style="background-color: #f9f9f9;">zpool add log zfs_pool_name mirror </span>vtbd1 vtbd2<span style="background-color: #f9f9f9;"> </span></span><br />
<span style="background-color: #f9f9f9; font-family: inherit;"><br /></span><br />
<span style="background-color: #f9f9f9; font-family: inherit;">(Use actual names of the devices from the FreeNAS volume manager in place of vtbd1,vtbd2)</span><br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;"><br /></span></span><br />
You can now use the admin GUI to perform the rest of the setup.<br />
<span style="font-family: inherit;"><span style="background-color: #f9f9f9;"><br /></span></span><br />
<br />
<br />cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com1tag:blogger.com,1999:blog-6501711.post-53790193658963935492012-02-26T21:00:00.001-05:002012-02-26T21:00:12.314-05:00Flaw in yahoo mail allows spam messages to stay at the top of Inbox<br />
<br />
Its sunday afternoon and imagine my surprise when I see an email sent from Monday. First, neutrinos time travel and now email!<br />
<br />
Turns out yahoo mail blindly trusts the Date header in the message and uses it to sort and present the email. So as long as its Monday in any part of the world, (i.e. international date line) an email can be sent with that date in the header and is accepted as valid. This means that a spam message can be sent to the other side of the international date line with 11:59 PM in the date header and the email will stay on top of the inbox for upto 24 hours (if you were just on the other side of the dateline)<br />
<br />
Note that the actual email could be sent from anywhere. This particular email was sent from Massachusetts.<br />
<br />
Note the Received-SPF header. This is a great way to pass spam controls since yahoo (and many other mail providers) trust that such a header is automatic guarantee of legitimate email. This of course, is nonsense. A spammer can register a domain and add IP addresses of the nodes he controls as a designated sender and until the domain is banned, he can bypass spam easily.<br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">Return-Path: <3eb.4.18052-1304933@exclamationboards.com></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Received-SPF: pass (domain of exclamationboards.com designates 199.250.223.35 as permitted sender)</span><br />
<span style="font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<br />
<span style="font-family: 'Courier New', Courier, monospace;">Message-Id: <SJbdaejddmfdBH@ExclamationBoards.com></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Reply-To: <CreditReportScoreFinder@ExclamationBoards.com></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">From: =?ISO-8859-1?Q?=0CB=1AlackPeopleMeet.com=20D=0Eating=20=19?= <CreditReportScoreFinder@ExclamationBoards.com></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Subject: =?ISO-8859-1?Q?Photos of Black Singles in DALLAS=A0 =A0=A0=A0=A0=A0 =A0?=</span><br />
<span style="font-family: 'Courier New', Courier, monospace;">Date: <b><span style="color: red;">Mon, 27 Feb 2012 11:31:05 GMT</span></b></span><br />
<span style="font-family: 'Courier New', Courier, monospace;">List-Unsubscribe: <http://SJbdaejddmfdBH.ExclamationBoards.com/t2.asp?</span>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-76461068416762451542011-10-16T21:36:00.000-04:002011-10-16T21:36:48.273-04:00Prime algorithm in assemblerOne of the greatest strengths of assembly language is the extreme compactness of code. Digging though my old files I found this gem that prints all prime numbers under 2^32. The COM file size is 165 bytes. That's right! You could memorize the bytes if you wanted to and hand assemble it.<br />
<br />
The algorithm is not sieve (which would create 2^31 locations and strike off multiples of primes). Rather this is a space optimized algorithm that repeatedly divides each number n from 2 to sqrt(n) to determine if a number is prime. This algorithm uses no additional storage than the 165 bytes to hold the code.<br />
<br />
<br />
<br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">.model tiny</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">.code</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">.386</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> org 100h</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">start:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">main proc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor eax,eax</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov al,3</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@m2:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> call isprime</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jnc @@m1</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> call printdword</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> call printcrlf</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@m1:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc eax</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jnz @@m2</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ax,4c00h</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> int 21h</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">main endp</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">isprime proc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pushad</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov esi,eax ; save number</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor ecx,ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ebx,ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov edx,ecx ; edx = 0</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> call sqrt</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov cx,ax ; save sqrt</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov bl,2 ; ebx = 2 (divisor)</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@i2:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov eax,esi ; restore number</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> cmp ecx,ebx ; is sqrt < divisor?</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jl @@i4 ; yes, no need to divide any more</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> div ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> or edx,edx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jz @@i1</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor edx,edx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jnz @@i2</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@i4:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> stc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jmp @@i3</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@i1:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> clc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@i3:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> popad</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> ret</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">isprime endp</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">sqrt proc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> push ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> push ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor ecx,ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ebx,ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@s2:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> sub eax,ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jl @@s1</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc cx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jmp @@s2</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@s1:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ax,cx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pop ecx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pop ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> ret</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">sqrt endp</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">printdword proc</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pushad</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor ebx,ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov cx,bx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov bl,10</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@p1:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> xor edx,edx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> div ebx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> push dx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> inc cx</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> or eax,eax</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> jnz @@p1</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">@@p2:</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pop ax</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> add al,'0'</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov dl,al</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ah,02</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> int 21h</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> loop @@p2</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> popad</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> ret</span><br />
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">printdword endp</span><br />
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"><br /></span></div>
<div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">printcrlf proc</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> pusha</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov dl,13</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ah,02</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> int 21h</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov dl,10</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> mov ah,2</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> int 21h</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> popa</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> ret</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;">printcrlf endp</span></div>
<div>
<span class="Apple-style-span" style="color: #274e13; font-family: 'Courier New', Courier, monospace;"> end start</span></div>
</div>
<div>
<br /></div>
<br />
<br />
<br />cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-67649109787263668992011-08-16T23:06:00.000-04:002011-08-16T23:06:56.586-04:00Fix for NFS v4 inverse squashingDue to an <a href="https://bugs.launchpad.net/ubuntu/+source/nfs-utils/+bug/662711">NFS Bug</a>, when ZFS is shared over NFS4 on the client side all files will appear owned by nobody:nogroup. If idmapd is not set it will be <span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'UbuntuBeta Mono', 'Ubuntu Mono', monospace; font-size: 12px; line-height: 18px;">4294967294:</span><span class="Apple-style-span" style="background-color: white; color: #333333; font-family: 'UbuntuBeta Mono', 'Ubuntu Mono', monospace; font-size: 12px; line-height: 18px;"> 4294967294.</span><br />
<br />
The client can still read and write and the files will appear normally on the server. Chown will fail, which means you cannot run VM images off this share.<br />
<br />
Mounting this with nfs option vers=3 in /etc/fstab is the only workaround until the bug is fixed.<br />
<br />
<br />cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com1tag:blogger.com,1999:blog-6501711.post-63070851273188890452011-08-16T19:22:00.001-04:002012-07-01T21:41:14.377-04:00Native (non-FUSE) ZFS on linuxThanks to Darik Horn, we can have native ZFS on linux. Instructions <a href="http://zfsonlinux.org/faq.html">here</a>. Works on natty, but may have issues on Lucid.<br />
<br />
Note:<br />
<br />
<ol>
<li>Preemptible kernels not supported. This should be OK for servers. </li>
<li>The ppa does not actually cover all dependencies. I had to figure out zlib1g-dev and uuid-dev</li>
</ol>
<br />
<pre><tt>
sudo add-apt-repository ppa:dajhorn/zfs
sudo apt-get update
sudo apt-get install zlib1g-dev uuid-dev ubuntu-zfs
</tt></pre>
<br />
If you get the following error, the build is unsuccessful:
<br />
<pre><tt>
Failed to load ZFS module stack.
Load the module manually by running 'insmod <location>/zfs.ko' as root.
</location></tt></pre>
<br />
To determine missing dependencies:
<br />
<pre><tt>
cd /var/lib/dkms/zfs/*/build
./configure. # Error message will tell you what dependencies are missing
</tt></pre>
<pre><tt>make</tt></pre>
<pre><tt>make install</tt></pre>
<br />
Repeat or other directories under dkms if they had errors. If you get any error regarding unknown symbol or module format, you have booted the wrong kernel.<br />
<br />
Update: As of Ubuntu precise 12.04, ubuntu-zfs installs flawlessly and takes care of all dependencies.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-26185986197552508562011-07-27T20:39:00.004-04:002011-07-27T20:42:32.052-04:00Migrating running VMs using virshPrerequisites:<br />
<br />
<br />
<ol>
<li>All VM images are mounted on a shared location, for example: /vmimages. If any images are qcow2 images with a backing file, those files also need to be present on shared locations.</li>
<li>kvm-pxe needs to be installed. If not, the migration occurs, but the VM is suspended at the destination.</li>
<li>Optional: If you want to be able to do this from scripts, setup ssh keys so you don't need to enter passwords</li>
</ol>
<br />
<br />
Migrate with the following command as root on the source host:<br />
<br />
<pre><tt>
virsh migrate --live vmname qemu+ssh://destination.host/system
</tt></pre>
<br />
or if you are not on source, you can first connect to the source host<br />
<br />
<pre><tt>
virsh --connect qemu://source.host/system migrate --live vmname \
qemu+ssh://destination.host/system
</tt></pre>
<br />
<br />
<br />cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-83471584407570456022011-07-03T11:52:00.001-04:002011-07-05T08:52:06.636-04:00Read only root on VMsFollow the instructions from here: https://help.ubuntu.com/community/aufsRootFileSystemOnUsbFlash<br />
<br />
<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
disable app-armor on dhclient (otherwise networking will fail)</div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
<span class="Apple-style-span" style="font-family: 'Helvetica Neue', 'Lucida Grande', Helvetica, Arial, Verdana, sans-serif; font-size: 14px;"></span></div>
<pre style="background-color: #f0eee6; border-bottom-color: rgb(193, 180, 150); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(193, 180, 150); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(193, 180, 150); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(193, 180, 150); border-top-style: dashed; border-top-width: 1px; font-family: courier, monospace; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 4pt; padding-left: 4pt; padding-right: 4pt; padding-top: 4pt; white-space: pre-wrap; word-wrap: break-word;">sudo aa-complain /etc/apparmor.d/sbin.dhclient</pre>
<br />
<br />
<br />
<br />
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
edit /etc/grub.d/00_header to not show menu on unclean close:<br />
<br /></div>
<div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;">
</div>
<pre style="background-color: #f0eee6; border-bottom-color: rgb(193, 180, 150); border-bottom-style: dashed; border-bottom-width: 1px; border-left-color: rgb(193, 180, 150); border-left-style: dashed; border-left-width: 1px; border-right-color: rgb(193, 180, 150); border-right-style: dashed; border-right-width: 1px; border-top-color: rgb(193, 180, 150); border-top-style: dashed; border-top-width: 1px; margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px; padding-bottom: 4pt; padding-left: 4pt; padding-right: 4pt; padding-top: 4pt; word-wrap: break-word;"><span class="Apple-style-span" style="font-family: courier, monospace; white-space: pre-wrap;">
# if [ "\${recordfail}" = 1 ]
# then
set timeout=-1
#else
set timeout=${2}
#fi
</span></pre>
<br />
Optionally, you can choose to not unmount NFS paritions, etc in /etc/rc0.d/S35networking and S40unmountfscadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-74756963459030347422011-06-30T20:24:00.010-04:002011-08-11T22:17:00.614-04:00Exporting ZFS filesystem over NFSFirst you need to install nfs-kernel-server. You also need a later kernel: 2.6.35 or better<br />
<br />
Install zfs native (or zfs-fuse):<br />
<tt></tt><br />
<pre><tt>sudo add-apt-repository ppa:dajhorn/zfs
sudo apt-get update
sudo apt-get install ubuntu-zfs
</tt></pre>
<br />
By default NFS sharing is off. To export a zfs filesystem, say zfs/home:<br />
<br />
<tt></tt><br />
<pre><tt>#Setup shared FS
zfs create -o compression=on -o atime=off -o sharesmb=on zfs/home
#export RO
zfs set sharenfs=ro zfs/home
#stop exporting. Also for next command to take effect
zfs set sharenfs=off zfs/home
# export RW, fsid needs to be unique per filesystem
zfs set \
sharenfs=10.1.1.0/24:rw,fsid=100,no_subtree_check,async,no_root_squash zfs/home
# add this to /etc/rc.local
zfs share -a
#To mount from OSX use the following command. -P option is for secure (<1024) ports
mount_nfs -P 10.1.1.1:/zfs/home/${USER} /mnt/home
</tt></pre>
<br />
Later invocations override earlier, so to export RW to only one host and RO to others:<br />
<br />
<br />
<tt></tt><br />
<pre><tt>zfs set sharenfs=off zfs/backup
zfs set sharenfs=10.0.0.0/8:ro,no_subtree_check,async,no_root_squash zfs/backup
zfs set sharenfs=10.1.1.1:rw,no_subtree_check,async,no_root_squash zfs/backup
</tt></pre>
<br />
The host writing the backup is 10.1.1.1 and will get read/write access. The rest will get read only access.<br />
<br />
<em><strong>Note: </strong>Setting the mountpoint property of a ZFS dataset to anything other than the default <tt>pool/dataset</tt> will cause it to be exported with <tt>all_squash</tt>. Do not change the mountpoint if you want to NFS share a dataset</em>
<br />
<br />
If you are getting a lot of stale NFS handles, the IO requests are timing out before they can be serviced due to heavy IO load. Mount your NFS shares using these options (example fstab entry):
<p>
<pre><tt>
server:/zfs/dataset /mnt nfs defaults,timeo=20,retrans=5,rsize=8192,wsize=8192,intr 0 0
</tt></pre>
<br/>
The timeo to 2 seconds from default of 0.7 seconds is the most important attribute.
cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com2tag:blogger.com,1999:blog-6501711.post-26497377513404929162011-06-03T22:57:00.003-04:002011-07-21T21:59:25.591-04:00Minimal graphical Ubuntu install<tt></tt><br />
<pre><tt>#!/bin/sh
# Minimal Ubuntu Graphical install
sudo apt-get install gnome-panel gdm gnome-terminal network-manager-gnome \
network-manager gnome-power-manager chromium-browser \
ubuntu-artwork libaudiofile0 flashplugin-installer
</tt></pre>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-70887247068348455952011-05-18T11:52:00.002-04:002011-05-18T11:59:28.244-04:00Time machine on a network drive<div dir="ltr" style="text-align: left;" trbidi="on">
A very good explanation of <a href="http://safalra.com/other/time-machine-network-drive/">how to use a network drive for time machine</a>. However, there is no need to reboot your OS X once you change the setting. I also make a shell script to create a time machine compatible network drive using all the above steps automatically. Enjoy!<br />
<br />
<br />
<tt></tt><br />
<pre><code>#!/bin/sh
# Create a time machine compatible network drive
# (c) codebytez.blogspot.com
NETLOC=$1
if [ -z "$1" ]
then
echo Usage: $0 /Volumes/network_volume \[size\]
exit 1
fi
if [ -z "$2" ]
then
SIZE=100g
else
SIZE=$2
fi
defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
MAC=`ifconfig en0 | grep ether | perl -lne 'print @f if (@f = /[0-9a-f]{2}/g)'`
HOST=`echo $HOSTNAME | perl -F'\.' -lane 'print $F[0]'`
VOL=${HOST}_${MAC}.sparsebundle
hdiutil create -size $SIZE -fs HFS+J -volname "Time Machine" $VOL
rsync -aE $VOL $NETLOC
rm -rf $VOL
echo Created $NETLOC/$VOL
echo Select as backup disk in Time Machine Preferences
</code></pre>
</div>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1123258752913974962005-08-22T20:35:00.000-04:002005-08-23T11:55:18.173-04:00Gates' Law<span style="font-style: italic;">"The speed of processors doubles every 18 months" -- Moore's law</span><p>
<span style="font-style: italic;">"The speed of software halves every 18 months" -- Gates' law </span>
<p>
I'm uncertain if Gates' Law was meant as a joke, but I did notice that Lotus 123 ran at about the same speed on an old 80286 as excel runs on your modern PC.
<p>
Some of it is certainly because newer hardware makes more things possible, such as the graphical interface and tooltips. Newer software does try to be sexier by doing flashy things such as the talking paperclip. This causes a tendency for the software to bloat to the point of saturation, i.e. until it performs at barely acceptable speeds.
<p>
But application programming seems to get worse with faster processors. Even with more memory, faster disks and multiple CPUs, your average web application runs slower. Is it possible that the faster hardware has made us worse programmers?
<p>
In the old days, to set a register to the value 1, even an average assembly programmer would do something like this:<pre><tt>
xor ax,ax
inc ax</tt></pre>
rather than:<tt><pre>
mov ax,1</pre></tt>
The reason was simple. The programmer knew the latter alternative required access to memory, which is generally ten times slower than accessing registers. Modern programming languages hide details like this from the programmer, so he does not know the real cost of bad programming.
<p>
With garbage collection now part of many languages, we see many applications having to deal with memory problems. Why? Because the average programmer does not know the cost of object creation since he does not have to deal with cleanup.
<p>
For example in C++ you would do this:
<pre><tt>
// case 1: allocate on stack
int a = 1;
// other code
DirEnt de;
</tt></pre><pre><tt>
// case 2: allocate on heap
int *a = new int;
// other code
DirEnt *de = new DirEnt;
</tt></pre>
In the first case, the variable is allocated on the stack and disappears when execution moves outside the scope. The compiler calculates the required space at compile time and generates a simple instruction such as:
<pre><tt>
sub bp, 2+248 ; int is 2 bytes, dirent is 248 bytes
</tt></pre>
In the second case, the variable is allocated on the heap, which is a comparatively slow operation. First, a check is made for sufficient free memory. The heap is then searched for contiguous free memory of the desired size and then initialized. The region is marked "in-use" and a pointer to the memory is returned. If there is no contiguous memory, the system may choose to compact/defragment memory.
<p>
Two characteristics of the heap vs stack in the above example are that the memory allocation routine would need to be called twice, since the compiler has no way of knowing if the allocations can be combined given there is other code between the two allocations. Also while each thread has its own stack, multiple threads compete for the same heap allocator (except a small portion of thread local heap, which is not really a factor in large memory footprints).
<p>
In languages such as Java you cannot really allocate anything except primitives on the stack even if you don't intend to use them beyond the immediate scope. This represents a big load on the memory management system. Objects that properly belong on the stack now crowd the heap, putting a strain on the entire system.
<p>
"But how slow can memory allocation be? Isn't memory accessible in nanoseconds?"
<p>
In most operating systems, for practically all applications, the memory allocated is virtual memory from the theoretical address space rather than actual physical memory. This implies that you need huge amounts of memory to never have a page fault. Page faults generally work at the speed of storage, which is measured in milliseconds unless you have a solid state disk.
<p>
With fragmented memory and a large memory footprint, we end up dealing with multiple page faults, causing the system to thrash. This is especially apparent in multi-threaded programming where the locality of reference principle does not save you from multiple simultaneous page faults.
<p>
Unfortunately, even a programmer who is aware of these issues is helpless if the language itself is restrictive. What java could have done is allocate objects on the stack if they are not passed to other methods.
<pre><tt>
// new translates to alloc on stack
DirEnt e = new DirEnt(".");
e.list();
</tt></pre><pre><tt>
// passed to other class, alloc on heap
DirEnt e = new DirEnt("..");
stack.add(e);
</tt></pre>
Theoretically, the java compiler could follow the object in the call tree and see if anyone retains a reference to it, but that would render the compiler prohibitively slow and perhaps incorrect if reflection is used.
<p>
It is therefore up to the programmer to not trust the much touted features of any language (or any technology) without sufficient experience. Failing which, your programs end up testifying for Gates' Law.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com23tag:blogger.com,1999:blog-6501711.post-1123517739259334202005-08-08T06:10:00.000-04:002005-08-08T15:03:30.656-04:00The problem with DTDs and schemasMany would agree with me that XML is too bulky for its intended purposes. But would you say the same about HTML? probably not.
<p>
And why should that be? Isnt XML a glorified, genericized HTML? Despite what the historians say about both being children of SGML, the fact of the matter is that XML only came into being after the spectacular success of HTML and if you remember the original marketing hype, it was all about how web documents would be XML in the future and how they would be rendered or used differently by other consumers.
<p>
One of the important factors for the failure of XML is the reliance on DTDs and schemas. HTML succeeded simply because there was no predefined format for any given web page. Browsers ignored what they did not understand, and did the best with what they could. HTML was a <i>language</i> that browsers and servers spoke. There was a syntax, but no schema. The schema came later, long after HTML was refined through multi-year, multi-user testing.
<p>
Your typical enterprise application does not have that luxury.
<p>
Consider this snippet of XML:
<p>
<pre><code>
<orders>
<date>Dec-24</date>
<order>
<customer>Joe Schlubbs</customer>
<customer-address>10 drowning st</customer-address>
<customer-city>London</customer-city>
<order-line>
<quantity>100</quantity>
<item-number>J-350</item-number>
<item-name>extra large onions</item-name>
<price-per-item>12.35</price-per-item>
<!-- other fields -->
</order-line>
</order>
<order>
<customer>Joe Schlubbs</customer>
<customer-address>10 drowning st</customer-address>
<customer-city>London</customer-city>
<order-line>
<quantity>100</quantity>
<item-number>J-007</item-number>
<item-name>extra large bullets</item-name>
<price-per-item>1.99</price-per-item>
</order-line>
</order>
</orders>
</code></pre>
<p>
Lets assume we are writing an application that needs a list of all customers who spent more than a thousand bucks in the last month so we could mail them some coupons.
<p>
An SQL programmer would simply do a <tt>SELECT customer, sum(price*qty) group by customer having sum(price*qty) > 1000</tt>. The typical XML programmer on the other hand, has to get all orders for the last month and skim through large amounts of text to produce the necessary results. Depending on the number of tags, close to 90 percent of the input will be useless to the application.
<p>
Could the server simply omit the unnecessary data? Probably not, because the tags are not optional. Thats because when they designed the XML, they could not forsee that business would be so good that they would send out coupons.
<p>
It is simply impossible to forsee all possible future needs, so to really future-proof your schema, you would need to make nearly every tag optional. This pretty much void the purpose of a schema.
<p>
A schema where every tag is optional could still useful, to describe what tags go where and what they mean -- sort of like HTML.
<p>
Or you could just deal with the bulk.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1123172102493542562005-08-04T20:00:00.000-04:002005-08-04T19:51:24.510-04:00Semaphores in assembler and javaHow do you implement a semaphore in assembler taking into account the fact that you may have multiple CPUs with each CPU possibly executing multiple threads of code at any time?
We use the <code>xchg</code> instruction, which performs atomic exchange of its arguments.
<pre><code>
;acquire semaphore
xor ax, ax ; set AX to zero
L1:
xchg ax, sema ; atomic test and set. sema = 0, ax = sema
or ax, ax ; is the value we obtained from sema 0?
jz L1 ; yes, wait for someone to release semaphore
dec ax ; no, we got the semaphore.
xchg ax, sema ; decrease by one and store
;process stuff
; release semaphore
xchg ax, sema ; sema value may have been changed by other threads
inc ax ; bump to notify we have released it
xchg ax, sema ; atomic store
</code></pre>
This is why there is an atomic exchange instruction in many processors. An atomic test and set instruction is indispensable for a variety of systems programming, semaphores being one of them. On systems with multiple processors, you probably want to lock the bus before executing the <code>xchg</code>. The code becomes:
<pre><code>
lock xchg ax, sema
</code></pre>
In case you have forgotten, the <code>lock</code> instruction locks the memory bus for the duration of the next instruction, which ensures that another processor does not read or write to sema when we are writing to it.
The sequence of instructions
<pre><code>
L1:
xchg ax, sema
or ax, ax
jz L1
</code></pre>
form an anti-pattern called "busy-waiting" and burns up CPU resources when waiting to acquire the semaphore. In real life systems programming, it is often replaced by a spin lock, (which is a "design pattern")
A spin lock busy waits for a few instruction cycles and then goes to sleep. The idea behind this is that context switches are expensive, and for many operations, semaphores are held briefly enough that the majority of the time, the waiting thread acquires the semaphore without the added cost of a context switch.
<pre><code>
;acquire semaphore
L0:
mov cx, 0800h ; spin the test loop so many times ...
xor ax, ax ; ... choose 1/2 cost of context switch and tweak
L1:
xchg ax, sema
or ax, ax
jnz L2 ; got the semaphore, go to update
loop L1 ; repeat till cx is zero
call monitor_wait ; context switch
jmp L0 ; need to retest after notify
L2:
dec ax
xchg ax, sema
</code></pre>
As you can see this implementation is very efficient and wastes very few cycles. A semaphore variable needs to be initialized with the number of simultaneous threads that can access it. For a mutex (equivalent to java's synchronized) we set the value to 1.
The Linux kernel approaches the problem in a similar manner (albeit in C).
The java equivalent looks like this:
<pre><code>
synchronized(lock) // sema is an invisible variable inside object lock
{ // sema acquired if you get here
// process
} // release sema
</code></pre>
Given that mutexes are nothing but special case of semaphores which have been in use in systems programming since antiquity and the relative simplicity of the machine code to implement them, its surprising that the <code>monitorenter</code> and <code>monitorexit</code> instructions were prohibitively expensive in early JVM implementations.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1123116569407630412005-08-03T20:01:00.000-04:002005-08-04T00:05:27.370-04:00SEXMLXML has the unfortunate side effect of being bulky. While bulk is good for the large intestine, its pretty much useless in computing.
Which is why I devised SEXML. That's Simple Elemental XML.
This is how it was derived:
First, we get rid of attributes. What good are attributes for? They can easily be replaced by elements:
<pre>
<order qty="12" price="13.5" brokerage="15%">
<order-type>buy</order-type>
<effective-time>market-close</effective-time>
</order>
</pre>
can be rewritten as:
<pre>
<order>
<qty>12</qty>
<price>13.5</price>
<brokerage>15%</brokerage>
<order-type>buy</order-type>
<effective-time>market-close</effective-time>
</order>
</pre>
Next, we get rid of the irritating double tags. We accomplish this by turning <qty>12</qty> into qty<12>. The XML above becomes:
<pre>
order<
qty<12>
price<13.5>
brokerage<15%>
order-type<buy>
effective-time<market-close>
>
</pre>
To avoid confusion between XML and SEXML, and to enable embedding one in the other, lets replace <> with something else, say {} and while we are at it, put them on just one line:
<pre>
order{qty{12}price{13.5}brokerage{15%}order-type{buy}effective-time{market-close}}
</pre>Perhaps we should separate the items with a comma, in case there are empty elements:
<pre>order{qty{12},price{13.5},brokerage{15%},order-type{buy},effective-time{market-close}}
</pre>
There we go. If we had used parantheses, it would look too much like lisp and scare people off.
Of course, you would put everything on one line only for use in URLs and the like.
<p>
The above has the same informational content of the XML above, but is much more compact and simpler to parse.
</p><p>
"But wait!" I hear screams. "What about schemas? What about the XML header? Character encoding? Entities?"
</p><p>
Nothing prevents you from using a schema. After all, it only describes structure and type information, not whether you use braces or angle brackets. Your schema just wont mention any attributes. As an exercise, try writing a schema for the above in SEXML.
</p><p>
As for the header, I dont see why you cant SEXML it up.
</p><pre>
sexml {
version{1.0}, encoding{utf-8},
order{
qty{12},price{13.5},brokerage{15%},order-type{buy},effective-time{market-close}
}
}
</pre>
Entities such as &lt; can live as is.
<p>
I believe CDATA is quite unnecessary for SEXML and in fact, seems to be rarely used in XML. If you believe otherwise, please enlighten me.
</p><p>
/*<br>
Since the original reason the comment in xml became the unweildy <!-- --> to maintain compatibility with HTML, we can break it here to use C++ style comments.
(Do you really need 4 chars to start a comment?)<br>
*/
</p><p>
Lets see what it looks like with parantheses:
</p><p>
</p><pre>sexml (
version(1.0), encoding(utf-8),
order (
qty(12),price(13.5),brokerage(15%),order-type(buy),effective-time(market-close)
)
)
</pre> Guess the Lisp folks were right. Everything is a list of lists.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com5tag:blogger.com,1999:blog-6501711.post-1107240893081156302005-02-01T01:09:00.000-05:002005-02-25T23:44:11.233-05:00Assembling a home theatre PCI've wanted to build an AMD-64 for some time and I finally got started with the following parts. All items were located on <a href='http://www.pricewatch.com'>Pricewatch</a>. For some items, I did not automatically choose the cheapest vendor if the vendor had less than best ratings.
<p/>
The general plan is to have a media box such as <a href='http://angerman.net/articles/jukebox/'>this</a>.
<p/>
<table border=1 align='right'>
<tr><th>Item</th><th align='right'>Price (w/. shipping)</th><th>Qty</th><th>Amount</th></tr>
<tr align='right'><td>AMD Athlon 64 939 3500+</td> <td>$262.70</td><td align='right'>1</td><td>$262.70</td></tr>
<tr align='right'><td>Asus A8N SLI skt939</td><td>$194.00</td><td>1</td><td> $194.00 </td></tr>
<tr align='right'><td>Ahanix D4 </td><td>$229.58</td><td> 1</td><td> $229.58 </td></tr>
<tr align='right'><td>Zalman CNPS7000B-CU Cooler </td><td>$52.00</td><td> 1</td><td> $52.00 </td></tr>
<tr align='right'><td>Samsung PC3200 512MB</td><td> $82.00 </td><td> 2</td><td> $164.00 </td></tr>
<tr align='right'><td>HITACHI 250GB SATA</td><td> $120.00 </td><td> 2</td><td> $240.00 </td></tr>
<tr align='right'><td>Hauppage WinPVR-250 </td><td>$128.00 </td><td> 1</td><td> $128.00 </td></tr>
<tr align='right'><td>PCI express eVGA 6600 256MB </td><td>$129.00 </td><td> 1</td><td> $129.00 </td></tr>
<tr align='right'><td>Arctic Silver 5</td><td>$6.00</td><td> 1</td><td> $6.00 </td></tr>
</table>
<p>
In addition, I bought some <a href='http://www.bevmo.com/productinfo.asp?area=home&seref=froogle&pf_id=00000012007'>Everclear 95% grain alcohol</a> from a liquor store for cleaning the computer parts. (Never use anything other than pure grain alcohol!)
<p>
In general, stores where shipping is free tend to ship via <a href='http://www.usps.com'>snail mail</a>, so when looking at the price, factor that in.
<p>
Most items were packed perfectly. I was impressed with the packing of the hard drives and the Ahanix case. Other items were packaged adequately. The only exception was the Zalman cooler, which had some copper cooling blades bent because they did not seal the box. Copper is a soft metal and bends easily. the fan also looked very slightly scuffed. I straightened out the fins of the Zalman carefully. Then I verified that the fan ran silently and decided not to ask for an exchange.
<p>
<h4>First impressions:</h4>
The <a href='http://www.ahanix.com/ahanix_product.asp?pid=9'>Ahanix D4</a> case looks like a stereo component device. The front metal face is about a quarter inch thick and feels luxurious. A hinged door that covers the 5.25 inch bays is held together by magnets and impresses quality. The entire case is aluminum and is very well constructed. The included power supply is silent and the case is designed to be kept cool. I wont review the case fully here since its been reviewed elsewhere, but suffice to say this is the best case you can get that holds a full ATX board and worth every penny. The D5 is cooler looking, but does not seem to have front USB/firewire ports and has an infra-red remote control sensor that is plugged to the USB port. I was not sure how it would work with <a href='http://www.lirc.org'>lirc</a>, so I did not buy it. The only negetive about this box is that smudges can be easily seen when you touch it.
<p>
The <a href='http://www.amd.com/us-en/Processors/ProductInformation/0,,30_118_9485_9487,00.html'>AMD Athlon 64 CPU</a> looked like it had some extremely thin layer of gunk on it (returned item?) but I washed it with alcohol and it evaporated.
<p>
The <a href='http://www.zalmanusa.com/usa/product/view.asp?idx=145&code=005009'>Zalman CNPS7700-Cu cooler</a> is a thing of beauty. It looks like a copper flower. The fan is large and silent. It comes with a fan control device, some thermal grease and various brackets. I cleaned its bottom with alcohol too.
<p>
The <a href='http://usa.asus.com/products/mb/socket939/a8nsli-d/overview.htm'>Asus A8N SLI deluxe</a> motherboard truly deserves the <em>Deluxe</em> tag. It comes with every imaginable cable and fixture including a SATA fixture that allows you to plug in SATA drives at the back. The chipset fan is reasonably silent. The optical SPDIF out makes this board attractive to Home Theater projects. The 8 SATA RAID interfaces don't hurt either. The most important feature however, is Nvidia chipset, which has good Linux support from the vendor.
<p>
The <a href='http://www.arcticsilver.com/as5.htm'>Arctic silver 5</a> compound comes in a tiny syringe with a rubber dome top.
<p>
The <a href='http://www.hitachigst.com/portal/site/hgst/?epi_menuItemID=268b770f407cc00ae4c0c516bac4f0a0&epi_menuID=8d237906f078b6fd25ad4e8060e4f0a0&epi_baseMenuID=22f0deefa8f3967dafa0466460e4f0a0'>Hitachi SATA hard drives</a> run great, but are not as silent as their IBM counterparts (before IBM sold their hard drive division to Hitachi). It could be because I have 2 SATA drives in raid config (more on that later) and they make the seek sound simultaneously. I need to investigate into silencing the drives a bit more.
<p/>
The <a href='http://evga.com/products/moreinfo.asp?pn=256-P2-N369-TX'>eVGA GeForce 6600 with 256MB</a> seems to be the fastest card at the price. This card comes with a shrouded fan. If you are a serious gamer (I'm not), its a good idea to go with the <a href='http://www.nvidia.com/page/geforce_6800.html'>6800 GT</a> and get the <a href='http://www.arctic-cooling.com/vga1.php'>Arctic cooler</a> for it.
<p/>
The RAM looked like ... RAM. The DIMMS had Copper heat spreaders on them and the word RAMSES printed. I complained to the vendor that he had sent me Ramses brand when I had requested Micron. He told me that the heat spreader was Ramses and the RAM was actually Samsung, which was allegedly better than Micron. I decided to keep the RAM if it ran stable. Fortunately, it did.
<p/>
I had an <a href='http://www.plextor.com/english/products/712A.htm'>old Plextor 712A DVD Writer</a>, which I plugged into the system.
<p/>
<h4>Hardware installation:</h4>
First, I removed the motherboard backplate provided by Ahanix. The items simply did not match my motherboard. I replaced it with one included by ASUS. The motherboard comes with a bracket and baseplate for the stock CPU cooler which I removed and then attached the baseplate that came with the Zalman cooler (using the nipples provided). I placed the motherboard on a flat surface and lifted the ZIF socket's lever and then aligned the CPU's golden triangle with the triangular mark on the ZIF socket. It fell into place easily. Placing the CPU on the ZIF socket and pushing the lever back to horizontal position is about the easiest thing to do.
<p/>
Next, I took the Arctic silver 5 syringe and punctured the top with a pin and then squeezed about 1 and a half rice grain lengths on the CPU. I then gently lowered the Zalman cooler and aligned the screw holes with the nipples. Once the cooler sits on the CPU, a suction prevents you from easily picking up the cooler. but you can turn it slightly. I then screwed in the cooler tight alternating each screw.
<p/>
I then lifted the motherboard with the CPU and cooler into the case and screwed it to the base. (Some folks prefer to attach the board first and then install the CPU and heatsink, but given that Arctic silver is slightly capacitative, I needed to be absolutely sure that not a single particle would fall onto the motherboard.)
<p/>
Next, I installed the Samsung 512MBx2 PC3200 RAM which had copper heat spreaders on them into the appropriate banks (A1 and B1) to make best use of DDR feature.
<p/>
Next, I installed the Hitachi SATA hard drives. You only get access to one side of the bay, so I screwed them in.
<p/>
Next, I installed the PCI-Express eVGA card into the blue PCIe slot (as recommended if using a single slot)
<p/>
Last, I connected all the case connections such as the power and hard drive LEDs
<p/>
Linux Installation: Most folks would do well to just install the <a href='http://www.mysettopbox.tv/knoppmyth.html'>KnoppMyth distribution</a>, but I'm a <a href='http://www.gentoo.org/'>gentoo</a> fanatic, so I downloaded the AMD64 ISO and installed gentoo and installed from stage3. <a href='http://www.gentoo.org/doc/en/handbook/handbook-amd64.xml?full=1'>Standard procedure</a> with some hints for <a href='http://www.gentoo.org/doc/en/gentoo-x86-tipsntricks.xml'>raid</a>.
<p/>
The only things I need to tell you are: For the sound card, I chose snd-intel8x0 (alsa driver) and for the net I chose forcedeth. Although I got nvidia's <a href='http://www.nvidia.com/object/linux_nforce_amd64_1.0-0292.html'>nvsound and nvnet</a> to work after applying <a href='http://www.nvnews.net/vbulletin/showthread.php?p=510644#post510644'>patches</a>, I saw no advantage over standard kernel provided drivers. For the video, I emerge nvidia-kernel and added nvidia to modules.autoload. I managed to setup SPDIF using instructions <a href='http://www.wlug.org.nz/NForce2Notes'>here</a>.
I see that my SPDIF is properly setup:
<pre>
# cat /proc/asound/pcm
00-00: Intel ICH : NVidia CK804 : playback 1 : capture 1
00-01: Intel ICH - MIC ADC : NVidia CK804 - MIC ADC : capture 1
00-02: Intel ICH - IEC958 : NVidia CK804 - IEC958 : playback 1
</pre>
So I should be able to play it like this:
<pre>
# mplayer -ao alsa:device=hw=0.2 mozart.mp3
</pre>
But either my receiver has no support for it or I need to do something <a href='http://opensrc.org/alsa/index.php?page=intel8x0'>like this</a> or <a href='http://www.alsa-project.org/alsa-doc/doc-php/template.php?company=Intel&card=.&chip=440MX%2C+i810%2C+i810%2C+i810E%2C+i820%2C+i820&module=intel8x0'>this</a>. So I went back to analog sound output.
<p/>
The video was tricky. I finally managed to get the right xorg.conf file but I had two serious problems. The first, the cursor was a transparent square area with a cluster of black dots and second, the icons and text would disappear if the mouse went over them (or sometimes just by themselves). Fortunately, I found a <a href='https://bugs.freedesktop.org/show_bug.cgi?id=2322'>patch</a> on the internet for xorg and recompiled with it. All I did was emerge it, when it said 'Source unpacked' I pressed control+Z, applied the patch and resumed the job. I really should do something <a href='http://www.sable.mcgill.ca/~clump/Gentoo%20Install.html'>like this (go to bottom)</a>, but I'm guessing that they will have the bugfix in the next version anyway.
<p/>
Its important to autoload the nvidia module or you get a "failure to load nvidia" error when you start X.
<p/>
I struggled to setup the RAID, until I realized that the onboard RAID controllers are nothing more than a place in the BIOS to store your settings. Linux still sees the physical hard drives. Grub probes the BIOS, so it sees the real drives. You cannot install GRUB with fakeraid. The best option was to use mdadm and Linux software raid, which is just as fast if not faster. The utility <a href='http://www.linuxdevcenter.com/pub/a/linux/2002/12/05/RAID.html'>mdadm</a> was part of the installation cd, so I used it to setup the raid. The trick of course, is to set your boot partition as RAID-1, so that grub will load off it. Install grub in both partitions as shown <a href='http://www.linuxsa.org.au/mailing-list/2003-07/1270.html'>here</a>. I could probably have used the hardware using instructions <a href='http://forums.gentoo.org/viewtopic.php?t=69554'>here</a>.
<p/>
I got the Vacuum Fluorescent Display (part of the D4 case) working using <a href='http://venky.ws/forums/viewtopic.php?t=14'>these instructions</a>. The VFD displays y with umlaut when the it tries to display a filled square for which I found a patch <a href='http://angerman.net/articles/jukebox/'>here</a>
<p/>
Wealth of info <a href='http://www.nforcershq.com/forum/viewtopic.php?t=45973'>here</a>
<h4>Noise</h4>
In general, I can constantly hear the constant whoosh of the fans at the back (I've disconnected one). The motherboard chip fan was the noisiest and I noticed that it was running at 8000+ RPM. I fixed the fan speed regulator that came with the CPU cooler and attached it to the motherboard chip fan and turned it fully down. The fan now runs at 4000+ RPM, but has almost negligible sound. The hard disks are silent unless there is activity, which I figure is the sound echoing off the case. The activity is occaisional even when compiling the kernel due to the 8MB caches.
<p>
<h4>Infrared</h4>
I purchased the parts off <a href='http://www.radioshack.com'>Radio Shack</a> and soldered my own infra red receiver. I attached the IR sensor off a long wire, so I could squeeze it into the space provided by the D4 case (just above the HDD light left of the VFD).
<h4>Heat</h4>
In general, the CPU runs at 35C with the case open and 43C with the case closed at idle. On heavy load, it goes upto 55C. The motherboard temp and the case ambient temperature is generally about 5C and 15C below the CPU temperature.
<p>
<h4>Conclusion</h4>
All in all, I'm happy with the power and performance of this machine. I aim to install the arctic cooler for my VGA card and I also need to figure out how to reduce the noise of the fans and the hard disks.cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com1tag:blogger.com,1999:blog-6501711.post-1106625331888377512005-01-24T22:52:00.000-05:002005-01-24T22:55:31.890-05:00Historical: TypewriterWhen I was a kid, I wrote this assembly program that would play with the VGA fonts (I wrote a whole bunch of programs that messed with the VGA fonts) One particular program that comes to mind is one that shifts the lines on the VGA font one scan line upward, making it look like it was typed on a typewriter with an errant key.
<pre><tt>
SCANLINES equ 16
SHIFT equ 2
.model small
.code
org 100h
main proc
mov ax,1130h ; read char vector
mov bh,06 ; 8*16 vga/mcga
int 10h
mov ah,0 ; read char
int 16h
cbw
push ax
mov cl,4 ; map of offending char
shl ax,cl
add bp,ax
add bp,SHIFT
mov cx,SCANLINES-SHIFT ; save char bitmap
push ds
push es
pop ds
pop es
mov si,bp ; ds:si->original map
lea di,charmap ; es:di->our buf
cld
rep movsb
mov ax,1100h ; set char
mov cx,1
pop dx
mov bh,10h ; 8*16 vga/mcga
lea bp,charmap
int 10h
mov ax,4c00h
int 21h
main endp
charmap db SCANLINES dup(0) ; init to 0 as last lines must be blank
end main
</tt></pre>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com1tag:blogger.com,1999:blog-6501711.post-1106622845095036512005-01-24T21:51:00.000-05:002005-01-24T22:14:05.096-05:00History: Executing a program in DOSA common trick in the old days was to execute an application from within another. Here is some code example of how that was normally done:
<pre><tt>
.model tiny
.code
ExecBlk Struc
Psp dw ?
Cmdline dw ?
CmdSeg dw ?
FCB1 dw ?
FCB1seg dw ?
FCB2 dw ?
FCB2seg dw ?
ExecBlk ends
org 100h
main proc
lea bx,pspblk
mov sp,bx
call resize
mov execb.psp,0 ; copy our environment
mov execb.cmdline,80h ; pass command line as is
mov execb.FCB1,5ch
mov execb.FCB2,6ch
mov execb.cmdseg,cs
mov execb.FCB1seg,cs
mov execb.FCB2seg,cs
lea dx,execf
push ds
pop es
lea bx,execb
mov ax,4b00h
int 21h
merr:
mov ax,4c00h
int 21h
main endp
resize proc
add bx,15
mov cl,4
shr bx,cl
mov ax,cs
add bx,ax
mov ah,4ah
int 21h
jc merr
ret
resize endp
execf db "PAT.COM",0 ; ASCIIZ pathname of file to be execd
execb ExecBlk <>
_stack dw 1000h dup(?)
pspblk label byte
end main
</tt></pre>
cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1104523693739776902004-12-31T14:51:00.000-05:002005-01-24T22:35:57.723-05:00Is BASIC good for anything?Has BASIC become the red haired stepchild that nobody wants?
<p>
Some folks look down upon BASIC programmers; in fact they even avoid thier company. I'm not trying to say that all programmers are equal in the eyes of the CPU or anything, but remember that Bill Gates is basically a BASIC programmer and that BASIC was once the language of choice for many music related application in the 80's. BASIC's <tt>PLAY</tt> keyword makes it simple to program musical notes and I'm sure the language has a couple of other redeeming features as well (I just can't remember what they are at the moment).
<p>
BASIC's lack of the need for formal structure such as class declarations or include statements plus its interpreted nature makes it a popular language to learn programming even in places like India where everyone is allegedly born partially a programmer.
<p>
Speaking of India, here is a song written entirely in BASIC.
<tt><pre>
10 '+------------------------------------------------------------------------+
20 '| The Indian National Anthem |
90 '+------------------------------------------------------------------------+
110 PLAY "L8C#D#FFFFFFL4FL8FFD#FL4F#" '| Jana gana mana adhinayaka jaya hai|
120 PLAY "L4FL8FFL4D#L8D#D#CD#L2C#" '| Bharatha bhagya vidhatha |
130 PLAY "L4D#G#L8G#L4G#L5G#" '| Punjaba Sinda |
140 PLAY "L8G#L4G#L8G#G#G#L8A#L4G#" '| Gujaratha maratha |
150 PLAY "L4F#L8F#F#L4FL8FFD#F#L1F" '| Dravida uthkala vanga |
160 PLAY "L4FL8FFl4Fl8fd#g#g#l4g#f#f#" '| Vindhya Himachala Yamuna Ganga |
170 PLAY "L4fl8ffd#d#d#l8cl4d#l1c#" '| Uthkala jaladi taranga |
180 PLAY "L8ffffl4fl4fl8d#fl1f#" '| Tava shubha name jage |
190 PLAY "L8ff#g#g#l4g#l8f#fd#l8f#l1f" '| Tava shubha ashisa mage |
200 PLAY "l4ffl8d#d#d#d#cd#l1c#" '| Gahe Tava jaya gatha |
210 PLAY "l8g#g#g#g#l4g#l8g#g#" '| Jana gana mangala |
220 PLAY "l4g#l8g#g#g#l8a#l4g#" '| Dayaka jaya hai |
230 PLAY "l4f#l8f#f#l4fl8ffl8d#f#l1f" '| Bharatha bhagya vidhata |
240 PLAY "o5l8ccl1c#l8co4a#l1o5c" '| Jaya hai jaya hai |
250 PLAY "l8o4g#g#o5l1o4a#" '| Jaya hai |
260 PLAY "l8c#d#fff#f#d#fl1f#" '| Jaya jaya jaya jaya hai |
270 END '+-----------------------------------+
</pre></tt>cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com1tag:blogger.com,1999:blog-6501711.post-1104521946873356792004-12-31T14:24:00.000-05:002004-12-31T14:39:06.873-05:00Choosing the best suited languageBut its got to be done in Jaavaa! (or .NET or VB or whatever)
<p>
No, Dr. Dre, you need to choose what's the most suitable language to solve the problem. Believe it or not, the complexity of the application changes dramatically with a language that thinks differently from the problem class at hand.
<p>
For example, consider a simple app that converts strips non-ASCII characters by converting them to their ASCII counterparts.
<p>
Lets say your manager loves BASIC and writes it as below
<pre><tt>
OPEN "unstripped" FOR INPUT AS #1
OPEN "stripped" FOR OUTPUT AS #2
WHILE NOT EOF(1)
a$ = INPUT$(1, 1)
n = ASC(a$)
IF n > 127 THEN
PRINT #2, CHR$(ASC(a$) - 128);
ELSE
PRINT #2, a$;
END IF
WEND
CLOSE
END
</tt></pre>
That is quite reasonable, isn't it? You could probably write something equivalent in C, Java or related languages.
<br>
Yes, but look how much simpler it would be if Perl was chosen as the language of choice.
<pre><tt>
perl -pe 'y/\x80-\xff/\x00-\x7f/'
</tt></pre>
Its a one liner you type on the command line. For text processing, Perl tends to beat any other language.
cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1102448324707382492004-12-07T13:56:00.000-05:002005-02-02T23:51:56.766-05:00Writing good hashcodes and equalsHow would one write a good hashcode?
Here is one I've seen in real life:
<pre><span style="font-family:courier new;">
class Thing
{
List itemlist;
public int hashCode()
{
return toString().hashCode();
}
public boolean equals(Object o)
{
return o.toString().equals(toString());
}
public String toString()
{
return "Items = " + itemlist.toString() ;
}
}
</span></pre>
For reasons of brevity, I've drastically reduced the size of the original toString() function, but suffice to say, it printed the all elements of the entire complex Object with appropriate keywords. And the member <span style="font-family:courier new;">itemlist</span> was one that could grow indefinitely long.
It was obvious that the dude who wrote it does not know what a hashcode is at all. A hashcode serves as a value for quick comparison between Objects. It is essentially used to quickly locate which bucket the item is stored in HashMaps and other data structures that provide near constant access time.
If the hashCode computation takes <span style="font-style: italic;">longer </span>than the equals comparison, then you need to brush up on your fundamentals.
What could be done differently?
A simple way to define a good hashCode is given below:
<span style="font-family:courier new;"><pre>
class A
{
Integer a, b;
String c;
Set d;
public int hashCode()
{
// Sum of (prime number * hashcode) for selected members
return 7 * a.hashCode() + 11 * b.hashCode();
}
public boolean equals(Object o)
{
if(o == null || !getClass().equals(o.getClass()) || o.hashCode() != hashCode())
return false;
A other = (A)o;
return other.a == a && other.b == b
&& c.equals(other.c) && d.equals(other.d);
}
}
</pre></span>
As you can see, while equal Objects imply equal hashCodes, the converse is not necessarily true.
Most of the time, the check for class and hashCode will eliminate most matches. Among the few that do match, you just need to compare the itemlists without converting them to String first. This has the added benefit that the comparison can terminate early for example if the lengths are different.
If you do not have any other members or you believe that they do not sufficiently provide a proper distribution of the hashcodes, you can define the functions as below:
<span style="font-family:courier new;"><pre>
class Thing
{
private List itemlist;
public int hashCode()
{
if( itemlist != null && itemlist.size() > 0 )
return itemlist.size() * 7 + itemlist.get(0).hashCode();
else
return 0;
}
public boolean equals(Object o)
{
if (o == null || !getClass().equals(o.getClass()) || o.hashCode() != hashCode())
return false;
Thing thing = (Thing)o;
return thing.itemlist == null && itemlist == null ||
thing.itemlist.equals(itemlist);
}
public String toString()
{
return "Items = " + itemlist.toString() ;
}
}
</pre></span>
Of course, you have to ask yourself what business you have in returning toString() of classes that can be very large. If unavoidable, you should at least cache the results of toString() and hashCode() and update them on changes. This may need synchronization, so generally keeping hashcodes and toString functions simple is the better choice.
cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0tag:blogger.com,1999:blog-6501711.post-1095432799869170772004-09-16T22:07:00.000-04:002004-09-27T16:32:30.490-04:00Does Java pass Objects by reference?You often hear that Java passes primitives by value and Objects by reference. Unfortunately, this is misleading.
A reference has a specific meaning in programming terminology. A reference is the variable itself. Its not a pointer, its not a copy, its the actual variable. This means that if a variable is passed by reference to a function and the function assigns another value to it, the changes are visible outside the function.
C++ implements references faithful to the original meaning while Java does not.
<tt><pre>
#include <iostream.h>
class Ref
{
public:
int one(int& it) { it = 1; } // Reassign variable
void two(int& it) { it++; } // Change variable
};
int main()
{
Ref ref;
int item = 0;
ref.one(item);
cout << "Item is " << item << endl;
ref.two(item);
cout << "Item is " << item << endl;
int* i = new int(0);
ref.one(*i);
cout << "I is " << *i << endl;
}
</pre></tt>
Prints:
<tt><pre>
Item is 1
Item is 2
I is 1
</pre></tt>
Java on the other hand, passes a <em>copy</em> of the reference. This means that any changes to the variable are preserved, but you cannot reassign the variable to point to something else within the traditional meaning of "reference."
<tt><pre>
import java.util.Date;
public class Ref
{
public void one(Date item) { item = new Date(); }
public void two(Date item) { item.setTime(365*24*60*60*1000L); }
public static void main(String[] args)
{
Date item = new Date();
item.setTime(0);
Ref ref = new Ref();
ref.one(item); // Change not reflected here
System.out.println("Item is "+item);
ref.two(item); // Change is reflected here
System.out.println("Item is "+item);
}
}
</pre></tt>
Prints:
<tt><pre>
Item is Wed Dec 31 19:00:00 EST 1969
Item is Thu Dec 31 19:00:00 EST 1970
</pre></tt>
The net effect of this is that a Java function can change the Object passed to it, but any reassignment to something else is lost. Many argue that this is indeed safer and C++ funtionality can be achieved by having the function return the new value and let the caller assign it to the actual variable. It also protects the programmer from having to overload the = operator when calling outside code to ensure that the reference is not reassigned.
<A href="http://burks.brighton.ac.uk/burks/language/cpp/cppfaq/references.html">Click here for good reference on References</A>
cadaverhttp://www.blogger.com/profile/00205606370921389742noreply@blogger.com0