Questions about multi-threading

Marcus Brinkmann marcus.brinkmann at ruhr-uni-bochum.de
Thu Jul 6 08:58:44 CEST 2006


At Thu, 6 Jul 2006 00:19:52 +0200 (CEST),
haypo at inl.fr wrote:
> 
> Hi,
> 
> I'm working on the firewall NuFW [1]. I used gprof to find functions which
> takes a lot of time. I'm not sure, but I think that gcrypt really uses too
> much mutexes lock() and unlock(). I read gcrypt source code, and used gdb
> on server to catch lock() calls.
> 
> I didn't understood everything, but I have some questions.
> 
> (a) Why do ath_mutex_lock() and ath_mutex_unlock() call mutex_init()? It
> looks very weird for me, since this function use another mutex!

For static initialization to work (using ATH_MUTEX_INITIALIZER).

> (b) Why do ath_mutex_destroy() call mutex_init()??? It's stupid to create
> a mutex if it doesn't exist ... to destroy it just after its creation!?

Yeah, that seems to be superfluous.  However, I don't think this is a
big performance difference (or do you have data indicating
otherwise?).

We at least need to check if it is initialized or not.  I agree that
the initialization could be optimized out in the case the the mutex
wasn't initialized and is going to be destroyed.  However, this
increases code complexity a bit for a doubtful performance gain: How
often do you destroy a mutex that's not initialized?

Anyway, if you think that should be changed, feel free to send in a patch.

> (c) Can a mutex lock() or unlock() fails? (or: it is necessary to check
> error code?)

Depends on the thread implementation and configuration of the mutex.
We do not check for the internal check_init_lock.  Doing so would make
the code a tiny bit more robust.  Want to send in a patch?

> (d) Would it be possible to make random() functions (eg.
> gcry_random_bytes() and gcry_create_nonce()) really thread safe? (can be
> called in two different threads at the same time and not block one the
> call until the first ends)

I think only by either using two entropy pools, thereby underutilizing
a scarce resource, or by using a second process.

> (e) Why using REGISTER_(...); macro and not simply call them in a function
> like "gcrypt_global_init();"? Eg. "REGISTER_DEFAULT_DIGESTS" in
> cipher/md.c, it uses a mutex to check if digests are already registred or
> not. "REGISTER_DEFAULT_DIGESTS" is called in 7 different functions, but is
> it really needed?

Not my code, so I can't comment :)

Thanks,
Marcus





More information about the Gcrypt-devel mailing list