Posts

Showing posts from June, 2007

Comparison of PTHREAD_PROCESS_SHARED in Soaris and FreeBSD

Let us begin with the sample code below (headers omitted for brevity): int main(int argc, const char* argv[]) { void* mmap_ptr = mmap (NULL, sizeof (pthread_mutex_t), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0); if (mmap_ptr == MAP_FAILED) { perror ("mmap failed"); return -1; } fprintf (stderr, "mmaped at: %x\n", mmap_ptr); pthread_mutex_t* mutp = (pthread_mutex_t*)mmap_ptr; // initialize the attribute pthread_mutexattr_t attr; pthread_mutexattr_init (&attr); pthread_mutexattr_setpshared (&attr, PTHREAD_PROCESS_SHARED); // this is what we're testing // initialize the mutex pthread_mutex_init (mutp, &attr); pthread_mutexattr_destroy (&attr); // acquire the lock before fork pthread_mutex_lock (mutp); pid_t chld = fork (); if (chld != 0) { // parent fprintf (stderr, "parent: going to sleep...\n"); sleep (30); fprintf (stderr, "parent: unlocking.\n"); pthread_mutex_unlock (mutp); } else { /...

Infnite loop while doing ++map.begin() on empty map

Look at this seemingly simple program: int main(int argc, const char* argv[]) { map mymap; map ::iterator it = mymap.begin(); ++it; return 0; } What do you think would happen when I compile and run this program? Infinite loop! I tried this program in two different versions of compilers: Sun Forte 6 suite on Solaris and gcc 3.4.6 on FreeBSD. In most of the library distributions, maps and sets are implemented using red-black trees. The iterator above seem to have three links: parent, left and right. For some strange reason, when the map is empty, the iterator returned by begin() (and end() too) has parent as NULL and left and right to be pointing to itself! (gdb) print it $1 = {_M_node = 0xbfbfecd4 } (gdb) print *it._M_node $2 = {_M_color = std::_S_red, _M_parent = 0x0, _M_left = 0xbfbfecd4 , _M_right = 0xbfbfecd4 } You can have a look at the _M_increment function to know why this results in an infinite loop. Now the history. One of our programs running in test region behaved very wei...

Zombies due to pipes in system() function call

Today I solved an interesting problem. One of my fellow developers used system() function in his code to run some command. The code looks like: while (condition) { if(system (...) == 0) dosomething (...); sleep (...); } When we ran the application, I observed that the system was crawling. I verified the IO utilization and found it was normal. I checked the CPU utilization using top and that too was normal. When I did a ps, I found that there were too many defunct processes in the system. I grabbed a cup of coffee and dug what could have caused so many defunct processes. There was only one place, which I suspected, could have caused the defuncts. That piece of code is given above. So I thought what was wrong with the argument to the system () command. It goes something like this: system ("head -1 input.txt | grep pattern") I modified the command above as it would be executed in system (), and run it through truss to find out if all the forked processes are reaped using wait...

How to free memory held by a container?

I have a test program like this: int main() { string large_str; for (int i = 1; i <= 1000; ++i) { string slice(100*i, 'X'); large_str += slice; large_str.clear (); printf ("size: %-5d, capacity: %-5d\n", large_str.size(), large_str.capacity()); } } The last line of the output is: size: 0, capacity: 131043 The question is: It is very obvious that the string container still holds memory that it allocated for the longest string it contained. How to deallocate this memory, without destructing the object? Thanks to James Kanze who posted an answer in this usenet thread , here is an elegant solution for this problem. template <typename Container> void reset( Container& c ) { Container().swap( c ) ; } So when you have to free the memory, just call reset(large_str) .

A script to monitor IO activities

This follows my discussion posted earlier regarding iostat. The script given below might be helpful in monitoring a device that has the given directory in it. #!/bin/ksh # This script will print IO activity for the partition given in the argument. # If no partition is given, it will print IO activity for the partition # that contains the current directory. # if [ -z "$1" ] ; then DIR=`pwd` else DIR="$1" fi ORIG_DIR=$DIR while [ "$DIR" != "/" -a "$DIR" != "." ] ; do MDEV=`mount -p | grep $DIR | nawk '{print $1;}'` if [ ! -z "$MDEV" ] ; then MDEV=`basename $MDEV` break else DIR=`dirname $DIR` fi done if [ -z "$MDEV" ] ; then echo "Unable to find out the mounted device for $ORIG_DIR." exit 1 fi echo "Mounted device for $ORIG_DIR is $MDEV" iostat -x -p -n -z 5 | egrep "$MDEV|device" This script was tested in SunOS 5.9 running ksh.

Using iostat for monitoring disk activities

There could possibly be a lot of reasons for application slow down. Identifying the cause for the slow down could be a bit tricky. iostat is a tool that helps in monitoring I/O activities in the system, which might have been caused your application slowdown. iostat helps to monitor I/O activity on a per-disk and per-partition basis. There are a number of options that might suite your particular need. But I find the ones below to be good enough for my needs: iostat -x -n -p -z 5 10 -x : Show me extended statistics for each disk. -n : Don't show cryptic names of devices, if possible show readable names. -p : Show per device statistics and per partition statistics. -z : Don't show me the rows that have all zeros in them. Let us take a sample output and explore. extended device statistics r/s w/s kr/s kw/s wait actv wsvc_t asvc_t %w %b device 0.0 0.8 0.0 10.8 0.0 0.0 0.0 0.6 0 0 c2t7d3s6 The following is what the 'man i...

An interesting question on Fibonacci series

I was thinking about an interesting question regarding the Fibonacci series. Here it is. Assume that we draw the Fibonacci series of n as an inverted tree, where each node has its two additive terms as child nodes. For e.g. root node F(n) has F(n-1) and F(n-2) as children, and so on. Give an expression for the number of times node i occurs in the entire tree, where 1 Try to solve this problem. There is an interesting pattern to observe here.