Jump to page: 1 2
Thread overview
Threads and static initialization.
Dec 17, 2010
wrzosk
Dec 17, 2010
Jonathan M Davis
Dec 17, 2010
Vladimir Panteleev
Dec 17, 2010
Jonathan M Davis
Dec 18, 2010
Vladimir Panteleev
Dec 18, 2010
Jonathan M Davis
Dec 18, 2010
Vladimir Panteleev
Dec 18, 2010
Jonathan M Davis
Dec 18, 2010
Pelle Månsson
Dec 18, 2010
Jonathan M Davis
Dec 18, 2010
Pelle Månsson
Dec 18, 2010
Robert Jacques
Dec 18, 2010
Michel Fortin
Dec 18, 2010
Robert Jacques
Dec 18, 2010
Michel Fortin
Dec 17, 2010
Simen kjaeraas
Dec 18, 2010
Michel Fortin
Dec 18, 2010
Jonathan M Davis
Dec 18, 2010
Michel Fortin
December 17, 2010
I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming.
Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched.

What do you think
December 17, 2010
On Friday 17 December 2010 13:47:05 wrzosk wrote:
> I believe that when new thread is being created, all static data is
> initialized inside new thread. What worries me is the fact, that many
> 'mini' threads will initialize all static data inside application. This
> may be somewhat time consuming.
> Maybe there should be a possibility to define 'Pure' thread that doesnt
> touch any static data, and in turn it could leave static constructors
> untouched.
> 
> What do you think

That seems like it would be _really_ hard to do - probably impossible. The compiler would have to know which functions, types, and variables a thread accessed. I don't believe that compiler really knows anything about threads. It doesn't know which thread calls a particular function or accesses a particular variable. It knows about thread-local storage vs shared storage, and the type system restricts conversions between the two, but to do what you're suggesting, you'd have to have the compiler know which thread is calling which function and disallowing - at compile time - certain threads from calling certain functions. As it is, any thread can call anything and the compiler makes no attempt at tracking any of that. It just has restrictions with regards to thread-local and shared.

So, while it certainly seems like a good idea, I don't see how it would really be possible. It might be possible to make it so that a thread could be created which did not initialize any module or static variables (be they at class, struct, or function scope), but I don't see how the compiler could enforce that none of those variables were used. It would have to be up to the programmer to only call pure functions.

What _might_ be possible would be if you had a way of starting a thread which took a function (or overrode one) and that function _had_ to be strongly pure. Then it could skip running static constructors, because it would be impossible for any static variables to be accessed. However, the only way that you'd then get access to anything that thread did was from the return value of the function that started it, which not raises the issue of how you'd get the return value with the asynchronous nature of threads, but it would restrict the usage of such threads to the point that they'd be practically useless.

I think that you raise a valid concern, but I don't think that that's the way to handle it. Restricting static constructors and global or static variables in practice will help, and using immutable more will help. But if we want a means of making threads more lightweight, we probably need to look at a different way of doing it than you're suggesting.

This does make me wonder about static constructors and immutable though. It's currently possible to assign to both immutable and mutable module-scope variables in a static constructor. Such static constructors _must_ run for every thread or the thread-local portions are going to be wrong, but you _can't_ run them for immutable variables or you aren't sharing them between threads (or you're reassigning them each time that at new thread is created - I think that there's currently a bug on that). Perhaps static constructors which assign to immutable variables should have to be immutable, and mutable variables would have to be assigned in non-immutable static constructors. Then the immutable static constructors only get run once with the main thread, whereas the non- static ones get run for every thread.

- Jonathan M Davis
December 17, 2010
On Sat, 18 Dec 2010 00:33:43 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> That seems like it would be _really_ hard to do - probably impossible.

This is about TLS, right?

If so, can't we just add a way to create a thread without TLS, so that any attempts to access it will cause an access violation? Sounds simple and useful enough.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
December 17, 2010
On Friday 17 December 2010 15:17:14 Vladimir Panteleev wrote:
> On Sat, 18 Dec 2010 00:33:43 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > That seems like it would be _really_ hard to do - probably impossible.
> 
> This is about TLS, right?
> 
> If so, can't we just add a way to create a thread without TLS, so that any attempts to access it will cause an access violation? Sounds simple and useful enough.

Except that virtually _everything_ in D is in TLS. Only shared variables and some immutable variables aren't. So, unless you use a set of functions which uses shared variables for _everything_, that would be rather useless.

- Jonathan M Davis
December 17, 2010
wrzosk <dprogr@gmail.com> wrote:

> I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming.
> Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched.
>
> What do you think

Unless you are spawning lots of threads and at arbitrary times, this is
unlikely to be much of a problem. If it is, you likely should use a thread
pool instead.

Lastly, if you absolutely must, it is possible to spawn a thread using
methods other than D's built-in thread-spawning functions, and those would
not have their static constructors run. On the downside, you lose any
guarantees the compiler could give you, as just about anything that is not
a local variable is in TLS.

-- 
Simen
December 18, 2010
On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said:

> I believe that when new thread is being created, all static data is initialized inside new thread. What worries me is the fact, that many 'mini' threads will initialize all static data inside application. This may be somewhat time consuming.
> Maybe there should be a possibility to define 'Pure' thread that doesnt touch any static data, and in turn it could leave static constructors untouched.
> 
> What do you think

You mean something like this:

	pure void doSomething(Tid parent) {
		int result = 1 + 1;
		parent.sendMessage(result);
	}

	void main() {
		spawn(&doSomething);
		... wait for message ...
	}

Perhaps 'spawn' could do this when you feed it with a pure function.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 18, 2010
On Friday 17 December 2010 16:02:27 Michel Fortin wrote:
> On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said:
> > I believe that when new thread is being created, all static data is
> > initialized inside new thread. What worries me is the fact, that many
> > 'mini' threads will initialize all static data inside application. This
> > may be somewhat time consuming.
> > Maybe there should be a possibility to define 'Pure' thread that doesnt
> > touch any static data, and in turn it could leave static constructors
> > untouched.
> > 
> > What do you think
> 
> You mean something like this:
> 
> 	pure void doSomething(Tid parent) {
> 		int result = 1 + 1;
> 		parent.sendMessage(result);
> 	}
> 
> 	void main() {
> 		spawn(&doSomething);
> 		... wait for message ...
> 	}
> 
> Perhaps 'spawn' could do this when you feed it with a pure function.

That would only work if send() can be pure, and I really doubt that it can be. If it _can_, then that might be a good optimization, but I'm betting that it can't be done. Someone more familiar with how send() work would have to say on that though, since I'm not intimately familiar with how send() works.

- Jonathan M Davis
December 18, 2010
On 2010-12-17 19:15:07 -0500, Jonathan M Davis <jmdavisProg@gmx.com> said:

> On Friday 17 December 2010 16:02:27 Michel Fortin wrote:
>> On 2010-12-17 16:47:05 -0500, wrzosk <dprogr@gmail.com> said:
>>> I believe that when new thread is being created, all static data is
>>> initialized inside new thread. What worries me is the fact, that many
>>> 'mini' threads will initialize all static data inside application. This
>>> may be somewhat time consuming.
>>> Maybe there should be a possibility to define 'Pure' thread that doesnt
>>> touch any static data, and in turn it could leave static constructors
>>> untouched.
>>> 
>>> What do you think
>> 
>> You mean something like this:
>> 
>> 	pure void doSomething(Tid parent) {
>> 		int result = 1 + 1;
>> 		parent.sendMessage(result);
>> 	}
>> 
>> 	void main() {
>> 		spawn(&doSomething);
>> 		... wait for message ...
>> 	}
>> 
>> Perhaps 'spawn' could do this when you feed it with a pure function.
> 
> That would only work if send() can be pure, and I really doubt that it can be.
> If it _can_, then that might be a good optimization, but I'm betting that it
> can't be done. Someone more familiar with how send() work would have to say on
> that though, since I'm not intimately familiar with how send() works.

That's an interesting question.

There isn't much difference between sendMessage and appending a value to an array. A pure function can append things to a mutable array it gets as a parameter, so why couldn't it append to another thread's message queue it gets as a parameter?

Your question is probably more about wether manipulating synchronization primitives should be pure or not. Things like locking a mutex or waiting on a condition. I don't see why they should not. Consider a strongly pure function that creates its own synchronization primitive for internal usage; how is that going to affect the rest of the program considering that no other parts of the program has access the same instances of those primitives?

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/

December 18, 2010
On Sat, 18 Dec 2010 01:27:01 +0200, Jonathan M Davis <jmdavisProg@gmx.com> wrote:

> Except that virtually _everything_ in D is in TLS. Only shared variables and
> some immutable variables aren't. So, unless you use a set of functions which
> uses shared variables for _everything_, that would be rather useless.

But isn't that what OP's asking?

Also, I wouldn't say it's useless... By _everything_ you mean global and class/function static variables, right? I can imagine lots of examples of using threads without having to access those variables.

-- 
Best regards,
 Vladimir                            mailto:vladimir@thecybershadow.net
December 18, 2010
On Friday 17 December 2010 16:44:19 Vladimir Panteleev wrote:
> On Sat, 18 Dec 2010 01:27:01 +0200, Jonathan M Davis <jmdavisProg@gmx.com>
> 
> wrote:
> > Except that virtually _everything_ in D is in TLS. Only shared variables
> > and
> > some immutable variables aren't. So, unless you use a set of functions
> > which
> > uses shared variables for _everything_, that would be rather useless.
> 
> But isn't that what OP's asking?
> 
> Also, I wouldn't say it's useless... By _everything_ you mean global and class/function static variables, right? I can imagine lots of examples of using threads without having to access those variables.

And how about every other variable? If it's not shared or immutable, it's in TLS. Do you want to mark every single variable with shared? I believe that that's pretty much what you'd have to do. It's _rare_ in D that a variable is shared. You'd basically have to create a set of functions explictly intended to be used with such special threads.

- Jonathan M Davis
« First   ‹ Prev
1 2