cd_smith@ou.edu wrote:
> What's wrong with user space solutions here? The normal approach is to
> put that pointer on the stack rather than requiring a system call to
> access it. It's faster, and it keeps stuff out of the kernel where it
> belongs (since by far the vast majority of programs don't use TLS).
Forgive me if my question sounds somewhat stupid: The fastest solution I
found was to compare the current stack pointer with the
stack/stack-limit pairs I store for each thread at startup. If esp lies
between those two, it looks like I've found the thread.
Is there a more efficient way? I considered storing my pointer in the
topmost stack address, but how do I know this address at an arbitrary
point of execution, with only esp available? Do I have a means to query
the limit of the stack segment (on an i386)? And is the limit of the
stack segment set to the pointer I pass to the kernel during a
__clone()?
> So just use pthread_*specific and be done with it. No problem there.
The problem is, but I forgot to mention this in the original mail, that
I can't make use of external libraries at all. There are some linker
problems that can't be solved right now, so everything I do has to be
based on system calls (int 0x80) alone. It would be very helpful to know
*how* PThreads implements this, though. I guess I'll have a look at the
source code...
> > (2) 1-based IDs for the threads belonging to a process (in addition to
> > the system-wide unique process IDs).
>
> What do you mean by 1-based? Do you mean that you want to require that
> the first thread in a process always has TID 1? That's pretty kuldgy, and
> very non-portable if you actually use it. If you need 1-based ID's, use
> TLS and a mutex-protected global variable and have threads allocate their
> process-local ID at startup and then increment the counter.
I need 1-based thread IDs because the thread local storage mechanism
implemented in the Pascal compiler run-time library expects 1-based IDs
for a simple lookup of a thread variable's value in a table. Kind of
address(variable) + (tid - 1) * total_tls_size.
It all works only for global variables, so total_tls_size is a fixed
value for the program. I guess it's exactly what Delphi does. I could
change this, of course, but I don't want to make more changes to the
original RTL than absolutely necessary.
> I doubt that the kernel really does any screwing around with the values of
> registers for the context. If so, I've lost a lot of what respect I
> previously had for any of these operating systems. More likely, the use
> of FS for that purpose is a convention used by the program, and the kernel
> properly context switches, without caring what you're using your registers
> for.
In OS/2 and Windows, the FS selector *initially* points to a thread
information block for the current thread. Of course you can change the
value of FS, and this value will still be valid after a context switch.
So the use of FS the way I described it is really a convention used by
the program (and recommended by the OS). But I don't see how I can
implement this convention in my program if the Linux kernel forces me to
use
ds=es=fs=gs
and doesn't allow me to create a new selector/offset pair for a given
address. On the other hand I'm not such an i386 protected mode assembler
geek, so it is possible that I've missed some command while browsing
through my assembler books.
-- Bye, E-Mail ......... mailto:joerg.pleumann@trantor.de Jörg Homepage ... http://www.trantor.de/joerg.pleumann
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/