[dmd-concurrency] What is protected by synchronization?

Michel Fortin michel.fortin at michelf.com
Sun Jan 31 04:51:58 PST 2010


Le 2010-01-31 à 0:54, Robert Jacques a écrit :

> I understand your concerns and share them. It's why I've supported and proposed different ownership type systems that address these issues. The problem is that your proposal is effectively re-creating either a lent or owned type poorly. At this point, since we are not going to get ownership types, I'd much rather have something safe and allow the gurus to cast stuff away as needed then to have a situation where there are loop-holes you could drive a Mac truck through. Honestly, I've read enough horror stories of threading gurus getting it wrong and of software killing people to prefer being safe to being sorry.

We have to strike a balance somewhere. We can design something simple, safe, and unusable; we can design something complex, safe, and usable; or we can design something simple, not entirely safe, and usable. There's a compromise to draw somewhere. If you want full safety, the type system has to cope with it. If it doesn't you're restricting synchronization to small trivial cases.

I'm a proponent of full safety too, and it's easy to add safety to my proposal: just add 'lent'. Well, adding 'lent' isn't necessarily easy, but it's all you need to plug the hole in my proposal.


> On that note, although I heard there were problems with owned/lent/unique, I never heard exactly what they were. Does anyone know what the particular issues were?

I think in Bartosz terminology 'owned' is a type modifier meant to say that some variable is protected by a particular mutex. 'owned' should be see as 'owned by X', where X is the particular mutex protecting a variable. Owned is a parametrized type modifier.

In my proposal, all non-shared fields in a class are implicitly owned by the class while 'shared' variable are not owned.

What 'lent' means is that you temporarily give access to a variable to a function. No reference can escape from this variable beyond the lifetime of the function. In general you need to propagate the owner's information with lent too. For instance if you're implementing a swap function, you must ensure the owner of the data referenced by the two swapped values is the same.

Something 'unique' is accessible through only one reference in the whole program, it is guarantied to have no aliasing. With 'lent' you can lend a unique reference to a function: you know once it returns your reference is still unique. As long as this 'unique' property holds, you can safely *move* the reference between threads. As long as the unique reference is kept thread-local you can access it without atomic operations or locks. 'unique' can be seen as a temporary state as you can safely move it to immutable, mutable, shared, etc.

Andrei wants to implement unique as a template, but it'll be very limited without 'lent'. If I remember well, there's no general Unique template, just a UniqueArray for arrays of primitive types. Arrays of structs would allow taking the address of struct members and create aliasing.


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





More information about the dmd-concurrency mailing list