mtx_init/lock_init and uninitialized struct mtx
Dmitry Krivenok
krivenok.dmitry at gmail.com
Thu Feb 24 16:10:48 UTC 2011
Hello Hackers,
Is it allowed to call mtx_init on a mutex defined as an auto variable
and not initialized explicitly, i.e.:
static int foo()
{
struct mtx m; // Uninitialized auto variable, so it's value is undefined.
mtx_init(&m, "my_mutex", NULL, MTX_DEF);
…
// Do something
...
mtx_destroy(&m);
return 0;
}
I encountered a problem with such code on a kernel compiled with
INVARIANTS option.
The problem is that mtx_init calls lock_init(&m->lock_object) and
lock_init, in turn, calls:
79 /* Check for double-init and zero object. */
80 KASSERT(!lock_initalized(lock), ("lock \"%s\" %p already
initialized",
81 name, lock));
lock_initialized() just checks that a bit is set in lo_flags field of
struct lock_object:
178 #define lock_initalized(lo) ((lo)->lo_flags & LO_INITIALIZED)
However, the structure containing this field is never initialized
(neither in mtx_init nor in lock_init).
So, assuming that the mutex was defined as auto variable, the content
of lock_object field of struct mtx
is also undefined:
37 struct mtx {
38 struct lock_object lock_object; /* Common lock
properties. */
39 volatile uintptr_t mtx_lock; /* Owner and flags. */
40 };
In some cases, the initial value of lo_flags _may_ have the
"initialized" bit set and KASSERT will call panic.
Is it user's responsibility to properly (how exactly?) initialize
struct mtx, e.g.
memset(&m, '\0', sizeof(struct mtx));
Or should mtx_init() explicitly initialize all fields of struct mtx?
Thanks in advance!
--
Sincerely yours, Dmitry V. Krivenok
e-mail: krivenok.dmitry at gmail.com
skype: krivenok_dmitry
jabber: krivenok_dmitry at jabber.ru
icq: 242-526-443
More information about the freebsd-hackers
mailing list