Valgrind
tried playing with valgrind to debug evolution-mail at home here, on my celeron 400 w/ 256 mb ram and it was just a might bit slower than molasis flowing uphill in january while being debugged under gdb on a low-end solaris machine remotely over ssh with X forwarding (well, it would be if molasis was a unix X application).
just so you don't get your panties in a twist, I don't put the full blame of this on valgrind (which is why I mention I'm running a celeron - not to mention evolution-mail is a heavy weight champion on steroids).
valgrind has certainly come a long way since I last looked at it a few months ago - in fact, last time I looked at it, it wasn't able to handle any multithreaded application at all, and now it can even handle evolution-mail (albeit a bit slowly on my hardware).
overall, I'm still impressed to say the least. sure beats
the pants off my libeaks LD_PRELOAD hack.
POSIX Threads
Let me just say... they screwed the pooch on this one.
I'm extremely disappointed that pthread_once()
doesn't block until the callback has been completed. Rather,
the first thread to get to the pthread_once() function gets
to call the callback while the other threads return
immediately and go on their merry way. The whole point of
this function as far as I can tell is to provide a means for
applications to initialise some static data for later use by
the rest of the library/function/whatever. Unfortunately,
the fact that all other threads return immediately makes
this totally useless for that operation because initialising
data in that pthread_once() callback function is not
an atomic operation. So here, let me give you the way this
should have been implemented
in-my-not-so-humble-but-correct-opinion:
typedef struct { pthread_mutex_t mutex; unsigned int complete; } pthread_once_t;#define PTHREAD_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, 0 }
int pthread_once (pthread_once_t *once, void (*init_func) (void)) { if (!once->complete) { pthread_mutex_lock (&once->mutex); if (!once->complete) { init_func (); once->complete = 1; } pthread_mutex_unlock (&once->mutex); }
return 0; }
While I'm on the subject, I think I'm gonna write a library called ppthreads (Portable Portable Operating System Interface Threads) or maybe tppthreads (Truly Portable Portable Operating System Interface Threads) since pthreads are notoriously not portable at all. Well, at least not beyond the very basics. I've spent a lot of time stumbling over inconsistancies between Linux and Solaris pthreads (and apparently Mac OS X pthreads aren't so complete either) in the Mono project. Everytime I get time to hack on the SPARC port I find myself porting the code over to Solaris.
Isn't it sad when portable doesn't mean portable?