Thanks Terry -- appreciate your response. Although, I suspect you may not have read my message (where I mentioned the pseudo-code) completely ? See snippet of it below. I had come to same conclusions vis-a-vis the after-effects of not handling the ABORTED error, and was asking for the best way to handle the ABORTED error. Your reference to kern_exec.c helped, and now, my_malloc() too returns if the semaphore_wait returns KERN_ABORTED.
<snip-from-earlier-message>
...
...
Notice, I am not checking the result of lock.
If somebody does a
thread_terminate() on one of the threads waiting on lock, thread-safety
is compromised ie, multiple threads may access the critical section.
The memory allocator may assign the same chunk of memory to different
threads, one of them may free it, crashing the others.
Is my reasoning correct ie. consistent with how darwin works ?
What
is the best way to handle such a situation ? Should my_malloc() have
returned if lock() returned a KERN_ABORTED ? Should it have retried ?
Will KERN_ABORTED always imply thread termination ?
</snip-from-earlier-message>
I am not really sure if lck_mtx_* is a good option for me. Its not clear how it will behave in situations where mutex is destroyed while it is locked etc -- Since these functions don't seem to have a return code. With semaphore_wait(), I at-least get a KERN_TERMINATED.
Regards,
Ratheesh
----- Original Message ----
From: Terry Lambert <email@hidden>
To: Ratheesh Ramachandran <email@hidden>
Cc: Darwin-Kernel List <email@hidden>
Sent: Thursday, 20 March, 2008 1:10:14 AM
Subject: Re: kernel panic on wakeup from hibernation
On
Mar
19,
2008,
at
1:40
AM,
Ratheesh
Ramachandran
wrote:
>
>
See
execargs_alloc
in
xnu
in
bsd/kern/kern_exec.c
for
an
example
of
>
>
how
to
do
an
allocation
using
semaphore_wait()
without
breaking.
>
>
I
looked
at
this.
It
is
returning
without
allocating
if
the
>
semaphore_wait()
returns
a
KERN_ABORTED...
which
is
fine.
Your
allocation
does
not
do
this,
and
that's
what's
wrong
with
your
allocation,
at
least
according
to
your
pseudo-code.
You
try
to
get
the
lock,
if
you
don't
get
it,
you
allocate
anyway,
because
you
have
a
lock()
function
that
internally
uses
semaphore_wait(),
and
you
don't
check
the
return
on
your
lock()
function
to
decide
to
abort
the
allocation
attempt.
So
then
you
attempt
the
allocation
and
stomp
over
a
pointer
that's
supposed
to
be
protected
by
the
lock
(semaphore),
but
isn't,
and
then
you
wonder
why
you
have
problems.
Then
you
compound
the
problem
by
calling
the
unlock(0
function,
which
if
it
has
transactional
semantics,
means
you
drop
the
semaphore
that
someone
else
allocated,
causing
them
to
be
unprotected
in
their
data
access
as
well.
-
You
need
to
follow
rigid
rules
when
you
involved
locking;
you
have
to
pick
whether
you
are
locking
code
(critical
sectioning)
or
data
(object
access
protection).
Locking
data
is
typically
a
better
approach,
just
from
a
general
CS
standpoint,
since
it
increases
parallelism.
And
then
you
never,
never,
never
violate
the
locking
protocol
that
protects
the
integrity
of
whatever
it
is
you
lock.
>
>
Alternately,
indicate
that
your
thread
us
uninterruptible
until
it
>
>
gets
the
lock
(and
make
sure
that
you
_get_
the
lock
sometime,
or
>
you
>
>
will
block
forever
--
better
to
just
do
it
right).
>
>
Will
this
approach
work
with
semaphores
?
I
mean
--
does
>
semaphore_wait
require
thread
to
be
interruptible
?
>
>
And,
how
do
you
set
the
thread
to
be
uninterruptible
?
Any
samples
>
for
this
around
?
thread_set_state
seems
promising,
but,
not
sure
if
>
thats
the
one.
Can
this
be
done
on
the
current_thread
?
Forget
that
I
said
this.
"Doing
it
right"
means
handling
the
interruption.
The
alternatative
requires
a
deeper
understanding
of
how
the
Mach
synchronization
primitives
work.
I
could
point
you
at
xnu
bsd/kern/kern_synch.c,
but
I
doubt
that
without
the
context
behind
it
that
that
would
be
very
useful
to
you.
If
you
truly
want
to
go
down
this
path,
then
you
should
get
a
copy
of:
Mac
OS
X
Internals
Amit
Singh
Addison
Wesley
Publishers
ISBN
0-321-27854-2
...and
look
up
assert_wait(),
thread_block(),
and
thread_should_abort().
-
My
personal
recommendation
would
be
that:
+
Keep
it
simple
+
Don't
"roll
your
own
locks"
using
semaphores
+
Use
lck_mtx_*
or
IOLock*
primitives
(depending
on
if
you
are
an
IOKit
driver)
+
lock
access
to
data
objects
+
forget
trying
to
play
with
preventing
aborts
happening
+
just
catch
when
they
do
and
implement
error
recovery
--
Terry