All of lore.kernel.org
 help / color / mirror / Atom feed
* per-thread global variables
@ 2002-07-12 16:15 J.A. Magallon
  2002-07-12 16:43 ` Alan Cox
  2002-07-12 19:17 ` Robert M. Hyatt
  0 siblings, 2 replies; 12+ messages in thread
From: J.A. Magallon @ 2002-07-12 16:15 UTC (permalink / raw)
  To: Lista Linux-SMP

Hi all.

I am looking for a method to have a global variable that has a unique
personality fot each thread. I don't want to use pthreads, but I would
like to emulate [get,set]specific. I just want to use clone() directly.

I have read something about a __thread variable modifier, or something
about an __attribute(( )) in gcc. Other solutions imply a search based
on pid, but I would like to find some more direct method.
Something like using the PRDA in IRIX.

Anybody has any pointer/info on this ?

TIA

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-12 16:43 ` Alan Cox
@ 2002-07-12 16:34   ` J.A. Magallon
  2002-07-12 17:41     ` Alan Cox
  0 siblings, 1 reply; 12+ messages in thread
From: J.A. Magallon @ 2002-07-12 16:34 UTC (permalink / raw)
  To: Alan Cox; +Cc: Lista Linux-SMP


On 2002.07.12 Alan Cox wrote:
>> about an __attribute(( )) in gcc. Other solutions imply a search based
>> on pid, but I would like to find some more direct method.
>> Something like using the PRDA in IRIX.
>
>If your stacks are the same size you can do the kernel trick with stack
>maths to hide thread globals. 
>-
>To unsubscribe from this list: send the line "unsubscribe linux-smp" in
>the body of a message to majordomo@vger.kernel.org
>More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

Uhm, something like reserving X bytes for stack, and telling clone()
I pass it a X-sizeof(prda) stack ?

How do I get the stack start from inside a thread ?

BTW, isn't there a barrier() syscall in Linux ? I could implement it 
with a semaphore with -N holes, but...man sem_init

       tially to value.  The pshared argument  indicates  whether
       the semaphore is local to the current process ( pshared is
       zero) or is to  be  shared  between  several  processes  (
       pshared is not zero). LinuxThreads currently does not sup­
       port  process-shared  semaphores,  thus  sem_init   always
       returns with error ENOSYS if pshared is not zero.


TIA

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-12 16:15 per-thread global variables J.A. Magallon
@ 2002-07-12 16:43 ` Alan Cox
  2002-07-12 16:34   ` J.A. Magallon
  2002-07-12 19:17 ` Robert M. Hyatt
  1 sibling, 1 reply; 12+ messages in thread
From: Alan Cox @ 2002-07-12 16:43 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Lista Linux-SMP

> about an __attribute(( )) in gcc. Other solutions imply a search based
> on pid, but I would like to find some more direct method.
> Something like using the PRDA in IRIX.

If your stacks are the same size you can do the kernel trick with stack
maths to hide thread globals. 

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-12 16:34   ` J.A. Magallon
@ 2002-07-12 17:41     ` Alan Cox
  0 siblings, 0 replies; 12+ messages in thread
From: Alan Cox @ 2002-07-12 17:41 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Lista Linux-SMP

> Uhm, something like reserving X bytes for stack, and telling clone()
> I pass it a X-sizeof(prda) stack ?

Use a 32K (say) 32K aligned stack
Load %esp into %eax, mask off the lower bits


> BTW, isn't there a barrier() syscall in Linux ? I could implement it 
> with a semaphore with -N holes, but...man sem_init

Too slow, way too slow. Read the x86 architecture manual and do it nicely 8)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-12 16:15 per-thread global variables J.A. Magallon
  2002-07-12 16:43 ` Alan Cox
@ 2002-07-12 19:17 ` Robert M. Hyatt
  2002-07-13  0:12   ` J.A. Magallon
  1 sibling, 1 reply; 12+ messages in thread
From: Robert M. Hyatt @ 2002-07-12 19:17 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Lista Linux-SMP



I do this in Crafty.  The approach I chose is to create a structure
for each thread (I also use clone() since the glibc guys broke 
pthreads a while back) and then let each thread set its pointer to
its own private structure (really shared, but since only one thread
has a pointer to each structure, it is like a private but global
group of variables).

Doing it like this will guarantee it will work with any compiler,
which might be a plus...

On 
Fri, 12 Jul 2002, J.A. Magallon wrote:

> Hi all.
> 
> I am looking for a method to have a global variable that has a unique
> personality fot each thread. I don't want to use pthreads, but I would
> like to emulate [get,set]specific. I just want to use clone() directly.
> 
> I have read something about a __thread variable modifier, or something
> about an __attribute(( )) in gcc. Other solutions imply a search based
> on pid, but I would like to find some more direct method.
> Something like using the PRDA in IRIX.
> 
> Anybody has any pointer/info on this ?
> 
> TIA
> 
> 

-- 
Robert Hyatt                    Computer and Information Sciences
hyatt@cis.uab.edu               University of Alabama at Birmingham
(205) 934-2213                  115A Campbell Hall, UAB Station 
(205) 934-5473 FAX              Birmingham, AL 35294-1170


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-12 19:17 ` Robert M. Hyatt
@ 2002-07-13  0:12   ` J.A. Magallon
  2002-07-13  1:50     ` Alan Cox
  2002-07-13  3:20     ` Robert M. Hyatt
  0 siblings, 2 replies; 12+ messages in thread
From: J.A. Magallon @ 2002-07-13  0:12 UTC (permalink / raw)
  To: Robert M. Hyatt; +Cc: Lista Linux-SMP


On 2002.07.12 Robert M. Hyatt wrote:
>
>
>I do this in Crafty.  The approach I chose is to create a structure
>for each thread (I also use clone() since the glibc guys broke 
>pthreads a while back) and then let each thread set its pointer to
>its own private structure (really shared, but since only one thread
>has a pointer to each structure, it is like a private but global
>group of variables).
>
>Doing it like this will guarantee it will work with any compiler,
>which might be a plus...
>

I think something is very dark for me...The hard way in pseudo-C

short id[PID_MAX];
#define setself(k) do { tid[getpid()]=k; } while(0)
#define self() (id[getpid()])

// master
  setself(-1);
// slaves
  for (i in 0..nslaves-1)
    clone(f(),CLONE_VM,i);

f(void *arg)
{
  setself((int)arg);
  print(self());
}

But how about the 32K*2 array ??? (hash table, ordered vector and binary
search...)

Quoting your answer:

>pthreads a while back) and then let each thread set its pointer to
                                                     ^^^
>its own private structure (really shared, but since only one thread

How do you define 'its' pointer ? That is like if I just defined

short id;

and tried to set 'its id' for each thread ?
Whichever method you use, at the end you always need one, the last, the
unique variable (one int, a pointer to a data area), declared as a global
variable in C that you need to be distinct for each thread. The only
thing (in my short undestanding) that can distinguish a thread from one
other is _pid_. Of course, I don't want to mess passing an info struct
to all functions in my code.

On IRIX, you have a

// Fixed address space always private for each process/thread
#define PRDA        ((struct prda *)0x00200000L)

struct prda*	thrprda;
int*	self;

f(int k)
{
  thrprda = (struct prda*)PRDA; // The magic global pointer
                                // different for each thread
  self = &(thrprda->user_area);
  *self = k;
}

If Linux supported this it will make many many things simpler.
A fixed zone of virtual address space that is never shared.

Or perhaps... Could I do in Linux:

#define PRDA        ((void*)0x00200000L) // Or get any free address space

int* self = PRDA; // will be shared over clone(), so we fix it before

for (i in 0..nslaves-1)
  clone(f(),CLONE_VM,i);

f(void *arg)
{
  // Get a chunk, mapped on a fixed address, and do not propagate the
  // map to parent or siblings
  mmap(self,1024,PROT_??,MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE,0,0);
  *self = (int)arg;
}


??

TIA

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  1:50     ` Alan Cox
@ 2002-07-13  1:11       ` J.A. Magallon
  2002-07-13  2:05         ` J.A. Magallon
  0 siblings, 1 reply; 12+ messages in thread
From: J.A. Magallon @ 2002-07-13  1:11 UTC (permalink / raw)
  To: Alan Cox; +Cc: Robert M. Hyatt, Lista Linux-SMP


On 2002.07.13 Alan Cox wrote:
>On Sat, 2002-07-13 at 01:12, J.A. Magallon wrote:
>> On IRIX, you have a
>> 
>> // Fixed address space always private for each process/thread
>> #define PRDA        ((struct prda *)0x00200000L)
>> 
>> struct prda*	thrprda;
>> int*	self;
>> 
>
>Which goes to show they weren't planning for clone like performance. A
>single unshared page means two seperate mm structs, two sets of page
>tables and switches causing TLB flushes. All because
>
>	movl %esp, %eax
>	andl $ffff8000, %eax
>	
>and casting that is 'hard'
>

OK, I do not know a word on x86 assembler, but lets see if at least I understand
this.

stack = reserve 32K+sizeof(my_private_area) (say, 1Kb)
clone() lying about stack start: stack + 32K - 1
   (private on top and stack grows downwards)

   |---- stack ----||--- private -----|
   0                32K               33k
                   ^
                   stack passed to clone()

void* getpriv()
{
  // get my stack frame pointer, can be anywhere depending on my
  // 
  movl %esp, %eax
  |---- stack ----||--- private -----|
           ^
           %eax
  // Round it to 32k multiple, cause I know the thread stack is 32k aligned
  // So I have the thread stack end, ie, bottom
  andl $ffff8000, %eax
  |---- stack ----||--- private -----|
  ^
  %eax
  // Move after top of stack
  addl 32K,%eax
  |---- stack ----||--- private -----|
                   ^
                   %eax
  // and I have the begining of my private area, upwards
}

Could it even be correct ?

TIA

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  0:12   ` J.A. Magallon
@ 2002-07-13  1:50     ` Alan Cox
  2002-07-13  1:11       ` J.A. Magallon
  2002-07-13  3:20     ` Robert M. Hyatt
  1 sibling, 1 reply; 12+ messages in thread
From: Alan Cox @ 2002-07-13  1:50 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Robert M. Hyatt, Lista Linux-SMP

On Sat, 2002-07-13 at 01:12, J.A. Magallon wrote:
> On IRIX, you have a
> 
> // Fixed address space always private for each process/thread
> #define PRDA        ((struct prda *)0x00200000L)
> 
> struct prda*	thrprda;
> int*	self;
> 

Which goes to show they weren't planning for clone like performance. A
single unshared page means two seperate mm structs, two sets of page
tables and switches causing TLB flushes. All because

	movl %esp, %eax
	andl $ffff8000, %eax
	
and casting that is 'hard'

Alan


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  1:11       ` J.A. Magallon
@ 2002-07-13  2:05         ` J.A. Magallon
  0 siblings, 0 replies; 12+ messages in thread
From: J.A. Magallon @ 2002-07-13  2:05 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Alan Cox, Robert M. Hyatt, Lista Linux-SMP


On 2002.07.13 J.A. Magallon wrote:
>
>>
>>Which goes to show they weren't planning for clone like performance. A
>>single unshared page means two seperate mm structs, two sets of page
>>tables and switches causing TLB flushes. All because
>>
>>	movl %esp, %eax
>>	andl $ffff8000, %eax
>>	
>>and casting that is 'hard'
>>

It can be done even arch-independent (__builtin_frame_address is at least
since 2.96):

#include <sched.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <sys/user.h>

#define MAXT 4

// User definable
#define STACK_PAGES 8
#define PRIV_PAGES 1
//

#define STACK_SIZE (STACK_PAGES*PAGE_SIZE)
#define PRIV_SIZE (PRIV_PAGES*PAGE_SIZE)
#define TOTAL_PAGES (STACK_PAGES+PRIV_PAGES)
#define TOTAL_SIZE (TOTAL_PAGES*PAGE_SIZE)
#define TOTAL_MASK (~(TOTAL_SIZE-1))

void* getpriv();
#define self() (*(int*)getpriv())
#define setself(k) do { *(int*)getpriv() = k; } while(0)

int slave(void *arg);
void f();

int main(int argc,char** argv)
{
	void*	stack[MAXT];
	int		i;

	for (i=0; i<MAXT; i++)
	{
		stack[i] = memalign(TOTAL_SIZE,TOTAL_SIZE);
		clone(slave,stack[i]+STACK_SIZE-1,CLONE_VM|SIGCHLD,(void*)i);
	}
	for (i=0; i<MAXT; i++)
		wait(0);

	for (i=0; i<MAXT; i++)
		free(stack[i]);

	return 0;
}

void* getpriv()
{
	void* frame = __builtin_frame_address(0);
	void* priv = (void*)((unsigned long)frame&TOTAL_MASK);

	return priv+(ptrdiff_t)STACK_SIZE;
}

int slave(void *arg)
{
	setself((int)arg);
	printf("priv=%p\n",getpriv());
	printf("self=%d\n",self());

	f();

	return 0;
}

void f()
{
	printf("f self=%d\n",self());
}

Code for getpriv():

getpriv:
    pushl   %ebp
    subl    $8, %esp
    movl    %ebp, 4(%esp)
    movl    4(%esp), %eax
    andl    $-36864, %eax
    movl    %eax, (%esp)
    movl    (%esp), %eax
    addl    $32768, %eax
    addl    $8, %esp
    popl    %ebp
    ret

So it does not look too slow. I could do also sysconf(_SC_PAGESIZE), but
that adds a function call everywhere. Indeed it will be safer.

And you could fill private area before clone(), so children do not have to
worry about anything like setself(). Yup, it would be nicer...

Thanks for everything !!!

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  0:12   ` J.A. Magallon
  2002-07-13  1:50     ` Alan Cox
@ 2002-07-13  3:20     ` Robert M. Hyatt
  2002-07-13  9:43       ` J.A. Magallon
  1 sibling, 1 reply; 12+ messages in thread
From: Robert M. Hyatt @ 2002-07-13  3:20 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Lista Linux-SMP


In the "master thread" I define an array of structures, one per
thread.  When I start a thread, I pass it the address of its private
structure.  Note that this has nothing to do with the stack.  Each
thread _must_ have a stack (mine is 1mb per thread) and you have to
(on intel) pass the _end_ address since stacks go backward on
X86 machines.

Another idea is to set up an array of pointers to the private
(global) structures.  Then have each thread do something
like pointer[thread_id]->stuff to get to stuff in its private
structure.




On Sat, 13 Jul 2002, J.A. Magallon wrote:

> 
> On 2002.07.12 Robert M. Hyatt wrote:
> >
> >
> >I do this in Crafty.  The approach I chose is to create a structure
> >for each thread (I also use clone() since the glibc guys broke 
> >pthreads a while back) and then let each thread set its pointer to
> >its own private structure (really shared, but since only one thread
> >has a pointer to each structure, it is like a private but global
> >group of variables).
> >
> >Doing it like this will guarantee it will work with any compiler,
> >which might be a plus...
> >
> 
> I think something is very dark for me...The hard way in pseudo-C
> 
> short id[PID_MAX];
> #define setself(k) do { tid[getpid()]=k; } while(0)
> #define self() (id[getpid()])
> 
> // master
>   setself(-1);
> // slaves
>   for (i in 0..nslaves-1)
>     clone(f(),CLONE_VM,i);
> 
> f(void *arg)
> {
>   setself((int)arg);
>   print(self());
> }
> 
> But how about the 32K*2 array ??? (hash table, ordered vector and binary
> search...)
> 
> Quoting your answer:
> 
> >pthreads a while back) and then let each thread set its pointer to
>                                                      ^^^
> >its own private structure (really shared, but since only one thread
> 
> How do you define 'its' pointer ? That is like if I just defined
> 
> short id;
> 
> and tried to set 'its id' for each thread ?
> Whichever method you use, at the end you always need one, the last, the
> unique variable (one int, a pointer to a data area), declared as a global
> variable in C that you need to be distinct for each thread. The only
> thing (in my short undestanding) that can distinguish a thread from one
> other is _pid_. Of course, I don't want to mess passing an info struct
> to all functions in my code.
> 
> On IRIX, you have a
> 
> // Fixed address space always private for each process/thread
> #define PRDA        ((struct prda *)0x00200000L)
> 
> struct prda*	thrprda;
> int*	self;
> 
> f(int k)
> {
>   thrprda = (struct prda*)PRDA; // The magic global pointer
>                                 // different for each thread
>   self = &(thrprda->user_area);
>   *self = k;
> }
> 
> If Linux supported this it will make many many things simpler.
> A fixed zone of virtual address space that is never shared.
> 
> Or perhaps... Could I do in Linux:
> 
> #define PRDA        ((void*)0x00200000L) // Or get any free address space
> 
> int* self = PRDA; // will be shared over clone(), so we fix it before
> 
> for (i in 0..nslaves-1)
>   clone(f(),CLONE_VM,i);
> 
> f(void *arg)
> {
>   // Get a chunk, mapped on a fixed address, and do not propagate the
>   // map to parent or siblings
>   mmap(self,1024,PROT_??,MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE,0,0);
>   *self = (int)arg;
> }
> 
> 
> ??
> 
> TIA
> 
> 

-- 
Robert Hyatt                    Computer and Information Sciences
hyatt@cis.uab.edu               University of Alabama at Birmingham
(205) 934-2213                  115A Campbell Hall, UAB Station 
(205) 934-5473 FAX              Birmingham, AL 35294-1170


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  3:20     ` Robert M. Hyatt
@ 2002-07-13  9:43       ` J.A. Magallon
  2002-07-13 14:07         ` Robert M. Hyatt
  0 siblings, 1 reply; 12+ messages in thread
From: J.A. Magallon @ 2002-07-13  9:43 UTC (permalink / raw)
  To: Robert M. Hyatt; +Cc: Lista Linux-SMP


On 2002.07.13 Robert M. Hyatt wrote:
>
>In the "master thread" I define an array of structures, one per
>thread.  When I start a thread, I pass it the address of its private
>structure.

So:

struct tinfo* data[n];

for (nthreads)
  data[i] = new private struct
  clone(f,data[i])

f(struct tinfo* mydata)
{
  me = mydata->mysefl; // OK till here
  g();
}

g()  // Note I do not pass any tinfo here
{
  // Who am I ?????????
}

You can't call any function from you thread-main function that
needs to self-identify ??

>Note that this has nothing to do with the stack.  Each
>thread _must_ have a stack (mine is 1mb per thread) and you have to
>(on intel) pass the _end_ address since stacks go backward on
>X86 machines.
>
>Another idea is to set up an array of pointers to the private
>(global) structures.  Then have each thread do something
>like pointer[thread_id]->stuff to get to stuff in its private
>structure.
>

We are in the same problem, if thread_id is pid, you need a big array.
If it is not, you need a multi-personality thread_id.

-- 
J.A. Magallon             \   Software is like sex: It's better when it's free
mailto:jamagallon@able.es  \                    -- Linus Torvalds, FSF T-shirt
Linux werewolf 2.4.19-rc1-jam3, Mandrake Linux 8.3 (Cooker) for i586
gcc (GCC) 3.1.1 (Mandrake Linux 8.3 3.1.1-0.7mdk)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: per-thread global variables
  2002-07-13  9:43       ` J.A. Magallon
@ 2002-07-13 14:07         ` Robert M. Hyatt
  0 siblings, 0 replies; 12+ messages in thread
From: Robert M. Hyatt @ 2002-07-13 14:07 UTC (permalink / raw)
  To: J.A. Magallon; +Cc: Lista Linux-SMP

On Sat, 13 Jul 2002, J.A. Magallon wrote:

> 
> On 2002.07.13 Robert M. Hyatt wrote:
> >
> >In the "master thread" I define an array of structures, one per
> >thread.  When I start a thread, I pass it the address of its private
> >structure.
> 
> So:
> 
> struct tinfo* data[n];
> 
> for (nthreads)
>   data[i] = new private struct
>   clone(f,data[i])
> 
> f(struct tinfo* mydata)
> {
>   me = mydata->mysefl; // OK till here
>   g();
> }
> 
> g()  // Note I do not pass any tinfo here
> {
>   // Who am I ?????????
> }
> 
> You can't call any function from you thread-main function that
> needs to self-identify ??


pass each new lightweight its ID thru the "arg" facility on the
clone() call.  That is how I do this...



> 
> >Note that this has nothing to do with the stack.  Each
> >thread _must_ have a stack (mine is 1mb per thread) and you have to
> >(on intel) pass the _end_ address since stacks go backward on
> >X86 machines.
> >
> >Another idea is to set up an array of pointers to the private
> >(global) structures.  Then have each thread do something
> >like pointer[thread_id]->stuff to get to stuff in its private
> >structure.
> >
> 
> We are in the same problem, if thread_id is pid, you need a big array.
> If it is not, you need a multi-personality thread_id.
> 
> 

-- 
Robert Hyatt                    Computer and Information Sciences
hyatt@cis.uab.edu               University of Alabama at Birmingham
(205) 934-2213                  115A Campbell Hall, UAB Station 
(205) 934-5473 FAX              Birmingham, AL 35294-1170


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2002-07-13 14:07 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-07-12 16:15 per-thread global variables J.A. Magallon
2002-07-12 16:43 ` Alan Cox
2002-07-12 16:34   ` J.A. Magallon
2002-07-12 17:41     ` Alan Cox
2002-07-12 19:17 ` Robert M. Hyatt
2002-07-13  0:12   ` J.A. Magallon
2002-07-13  1:50     ` Alan Cox
2002-07-13  1:11       ` J.A. Magallon
2002-07-13  2:05         ` J.A. Magallon
2002-07-13  3:20     ` Robert M. Hyatt
2002-07-13  9:43       ` J.A. Magallon
2002-07-13 14:07         ` Robert M. Hyatt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.