Re: Threading contexts
Re: Threading contexts
- Subject: Re: Threading contexts
- From: Jim Magee <email@hidden>
- Date: Thu, 22 May 2003 20:43:53 -0400
On Thursday, May 22, 2003, at 1:21 AM, Wally Crooze wrote:
Jim Magee wrote:
Wally Crooze wrote:
Continuing on from the locking and synchronization primitives... I
have the need to be able to associate particular information with a
thread which is specific to my kext project.
In other OSes an interface is provided to allow information stored
which doesn't effect the control of the thread. I found the
following interfaces which set/retrieve thread_t->saved.misc:
extern void thread_set_cont_arg(int);
extern int thread_get_cont_arg(void);
These aren't used anywhere in xnu, but thread_t->saved is a union
and is used for other information. Are these interfaces expected to
be used for miscellaneous thread information within my own code?
Also, can I treat this int as a void* ?
You can only use this to save information while you are causing the
thread to block. Some such blocks can occur at continuation points
(where the kernel stack is thrown away). These are the continuation
arguments that you can use to build context back up when the thread
resumes. If you aren't blocking the thread, you can't claim
ownership of these fields.
Does this mean that I can expect that at no time the thread is in my
code these fields will be in use? And that they wont be effected in
any blocking (i.e. locking/synchronisation) calls?
The "rule" for use of these fields is that they only get used while you
are preparing for and recovering from a thread blocking within your own
code. If the thread blocks within code that you call, you can't assume
that the fields will be left alone/restored. It's not a stack. But if
you never call any code that can block, they (in theory) could be used
by you.
I guess that I must use a lookup table mechanism on the thread to
retrieve my data. This will certainly effect the performance. Is there
a reason why a generic pointer for use within kexts (or drivers) isn't
available?
A generic pointer does no good if any two layers of software need to
use it. You need something akin to
pthread_set_specific()/pthread_get_specific() with a key to identify
_your_ pointer. That's pretty much what I was talking about us adding.
So, the only reason it doesn't exist yet is that it just hasn't been
implemented yet. I have not found any philosophical opposition to it.
An example for this use is part of my sema implementation requires
to store whether the thread was woken normally or by an (software)
interrupt from my code.
This is a situation where use of the cont_arg mechanism would be
appropriate. But you might want to use the wait_result value for
this indication (depending upon what sleep/wakeup mechanism you are
using). Remember that unless you block threads as "uninterruptible",
the signal/Mach thread_abort mechanisms may do the interruptions
without your wakeup code ever getting involved. You must deal with
those cases. They will result in a wait_result of
THREAD_INTERRUPTED. If you want to "poke at" a thread without making
it look like a signal, the THREAD_RESTART wait_result is commonly
used.
Is there an interface to "interrupt" a semaphore as opposed to waking
it? Or is it easier to mimic this in software with my own flags?
Again, this is heavily tied to whatever sleep/wakeup mechanism you
employed in your semaphore implementation. But there is
thread_abort_safely() which targets specific threads (regardless of
what they are waiting on), and there is thread_wakup_prim()-derived
wakup mechanism that takes a wait_result parameter to apply to each
thread it wakes up.
--Jim
_______________________________________________
darwin-kernel mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/darwin-kernel
Do not post admin requests to the list. They will be ignored.