Suspend/Resume obsolete?

G

Guest

What can be used now to control threads, if these are considered obsolete?

To pre-empt the obvious and standard questions due to this change:
1. No we don't have control over the particular code being executed so we
can not put a flag into it to detect when we want to suspend and even if we
could it may not be at the granularity we would need.
2. No mutex, semaphore, etc. are not appropriate things in this scenario.

Many of the MS profile API's still rely on suspend/resume with no
alternative either.

This seems really unreasonable to remove these API's due to presumably the
unwillingness to fix the bug/architecture that can cause .NET CLR deadlocks.

Ideas? Alternatives? Unmanaged really isn't a viable option for this since
the code being run is written managed, we would have to rewrite for managed I
guess.
 
C

Carl Daniel [VC++ MVP]

WXS said:
What can be used now to control threads, if these are considered
obsolete?

Suspend and Resume have been deprecated in .NET (and, incidentally, in Java)
because it's nearly impossible to use them correctly and very easy to create
deadlocks in the process. The surprising thing is not that suspend and
resume were deprecated in .NET, but that they were ever put in in the first
place, since there's been research showing the difficulties associated with
these facilities for many years.
To pre-empt the obvious and standard questions due to this change:
1. No we don't have control over the particular code being executed
so we can not put a flag into it to detect when we want to suspend
and even if we could it may not be at the granularity we would need.
2. No mutex, semaphore, etc. are not appropriate things in this
scenario.

Many of the MS profile API's still rely on suspend/resume with no
alternative either.

This seems really unreasonable to remove these API's due to
presumably the unwillingness to fix the bug/architecture that can
cause .NET CLR deadlocks.

They're not architectural bugs, but inherent weaknesses of the
suspend/resume model that affect every system that exposes these low-level
primitives.
Ideas? Alternatives? Unmanaged really isn't a viable option for this
since the code being run is written managed, we would have to rewrite
for managed I guess.

In some cases there may be no sensible alternative - you can still use
Suspend/Resume, but before you ignore the deprecation warnings, make sure
you understand the potential implications of using suspend/resume and make
sure that you're using them in a way that can't lead to deadlocks.

-cd
 
G

Guest

Suspend and Resume have been deprecated in .NET (and, incidentally, in Java)
because it's nearly impossible to use them correctly and very easy to create
deadlocks in the process.
They're not architectural bugs, but inherent weaknesses of the
suspend/resume model that affect every system that exposes these low-level
primitives.

In some cases there may be no sensible alternative - you can still use
Suspend/Resume, but before you ignore the deprecation warnings, make sure
you understand the potential implications of using suspend/resume and make
sure that you're using them in a way that can't lead to deadlocks.
 
B

Barry Kelly

WXS said:
What can be used now to control threads, if these are considered obsolete?

To pre-empt the obvious and standard questions due to this change:
1. No we don't have control over the particular code being executed so we
can not put a flag into it to detect when we want to suspend and even if we
could it may not be at the granularity we would need.
2. No mutex, semaphore, etc. are not appropriate things in this scenario.

Many of the MS profile API's still rely on suspend/resume with no
alternative either.

This seems really unreasonable to remove these API's due to presumably the
unwillingness to fix the bug/architecture that can cause .NET CLR deadlocks.

Consider the existence of a resource allocator which is shared across
multiple threads (any kind of resource: memory, database access,
whatever). If one thread suspends another while it is holding the lock
on this resource, and that thread in turn tries to allocate a resource
before resuming the other thread, it will deadlock.

It's like writing code like this:

---8<---
AcquireRandomLocks(); // "suspend"
foo(); // hope you don't need any of the locks
ReleaseRandomLocks(); // "release"
--->8---

-- Barry
 
B

Barry Kelly

WXS said:
I'm pretty sure Win32 does this and it is safe from the OS perspective.
This is effectively how you implement an operating system threading model
with API's like those, so there are ways to make it safe, but it does
require a proper architecture model and implementation.

What do you intend to do between Suspend() and Resume()?

Not even the CLR tries to do much between Suspend() and Resume(), FWIW:
for example, for suspension because of GC, it simply sets a flag and let
the threads resume, and waits for all the threads to come to a safe
synchronization spot. Check clr/src/vm/threads.cpp in the SSCLI, for
example.
There was some mention they may even remove these. Also they need to
fix the .NET issues that would cause .NET to deadlock on it's own.
Developers can prevent their own code deadlocks but can't do much about .NET.
So if these are needed... they should not deprecate the API's... now I have
this scenario where it is needed, but we are worried about code based on it,
if for the even more unreasonable decision to remove these came about.

Can you say more about your scenario?

-- Barry
 
C

Carl Daniel [VC++ MVP]

Win32 exposes Suspend and Resume, and they're just as dangerous when applied
to native threads.

No, it's not. It's a decision by the CLR team to take heed of significant
research that these threading primitives are dangerous and much more easily
misused than used correctly.

-cd
 
G

Guest

Yep, I understand the scope of the issue. Win32 handles this by stopping at
a safe point where the kernel will not block other kernel code. .NET Could
do the same for CLR code and let the developer worry about the user mode code.

In the scenario I am considering the thread calling suspend would call few
other methods of consequence (except resume and maybe sleep or wait for an
event (on a timeout to avoid any deadlocks))

This is like MS not including sharing in TFS - saying you really shouldn't
be doing this, even though we know in some cases there is no viable
alternative (oh well you're on your own). (Which is pretty much what they did
there too.. I'm sensing a pattern).
 
G

Guest

No, it's not. It's a decision by the CLR team to take heed of significant
research that these threading primitives are dangerous and much more easily
misused than used correctly.

That is like taking away my cell phone because I may use it for a crime, or
to order a high fat pizza or something. Since for certain cases there are no
viable alternatives you still have to use them, so they must be safe from a
CLR perspective and leave the rest up to the user let them order whatever
pizza they want... it's there perogative. Why don't we just get rid of
threads they are pretty unsafe as well :)

Sometimes this protect you from yourself stuff goes too far, and this is
definately one of those cases if that is the intention, but I suspect that MS
really didn't want to invest the time to make the CLR suspend point totally
safe, as while this functionality is critical when you need it, there are not
a lot of users that use it.
 
B

Bruno Jouhier

WXS said:
That is like taking away my cell phone because I may use it for a crime,
or
to order a high fat pizza or something. Since for certain cases there are
no
viable alternatives you still have to use them, so they must be safe from
a
CLR perspective and leave the rest up to the user let them order whatever
pizza they want... it's there perogative. Why don't we just get rid of
threads they are pretty unsafe as well :)

No, the analogy is wrong:

Cell phones are very useful, don't take them away.

Deprecating Suspend/Resume is more like preventing people to buy heroin.
They don't need it, and it will do them serious harm.

I have done quite a bit of multi-threading programming and I have never
understood how anybody could do anything useful with these calls. Once,
someon introduced a third party piece of code that contained calls to
Suspend and Resume into our framework, it broke everything and there was no
other way to fix it than to remove these calls and repplace them with good
old monitor based synchronization (fortunately we had the source).

So, deprecating Suspend/Resume is a very wise decision. Like Carl, I don't
understand why they were put in in the first place. Probably another
instance where the .NET designers had to rush and copied the Java design
without taking enough time to analyze it.

Now, if you want to live on dangerous drugs, that's your choice :-(

Bruno
 
N

Norman Diamond

I have done quite a bit of multi-threading programming and I have never
understood how anybody could do anything useful with these calls.

You've done quite a bit of multi-threading programming. You've never had a
timing problem that you wanted to experiment with, you never wished that you
could suspend one thread while letting another run and then later resume the
suspended thread?
 
G

Guest

I think maybe a different analogy is needed, it's like taking away my sharp
knife because I might use it as a hammer or a toothpick. (Yes that statement
is a bit rediculous and to my point so is taking away these methods and/or
not properly supporting them.) Why the analogy is appropriate, is sure you
could do something dangerous and stupid with a sharp knife, but it is also a
tool that can be used and is irreplaceable.

Multithreaded operating systems could not be implemented without the
effective functionality of suspend resume.

It sounds like the tool was inappropriately used in the scenario you
mentioned, but you don't take away all the knives in the world just because
someone might do something dumb with one of them.
 
G

Guest

Good points. Also, debuggers use suspend resume functionality to allow you to
Freeze and Thaw the threads. So when diagnosing thread issues it can be very
useful.
 
B

Bruno Jouhier

Norman Diamond said:
You've done quite a bit of multi-threading programming. You've never had
a timing problem that you wanted to experiment with, you never wished that
you could suspend one thread while letting another run and then later
resume the suspended thread?

No, I try to approach the multi-thread issues in a rigorous rather than
experimental manner. I try to keep the locking code as clean and well
organized as possible and I use assertions whenever I can to verify that the
right monitors are acquired in the right order. So far, this approach has
worked really well and I have never worked by trial and error with timings
to slow some threads down.

If I had to experiment with slowing down some threads, I would probably do
it by inserting wait calls rather than suspending and resuming threads.

It looks to me that Suspend and Resume do not belong to application code,
the VM may use such calls, and special tools like debuggers may use them
too, but it does not make sense to call them from the application itself,
because you have no way to control whether or not a thread has acquired
monitors or not when you suspend it, and if it has acquired some monitor,
all sorts of deadlocks will happen, and you cannot control and cannot
guarantee anything.

The situation with the .NET suspend/resume is very different from the
situation with the OS
suspend/resume because in the OS case,you have a clear boundary between user
mode and kernel mode and you only care about avoiding deadlocks in kernel
mode, you can guarantee this by delaying the suspend until the kernel
critical sections have been exited. In .NET code you cannot do this because
there is no such boundary and monitors may be acquired anywhere.

So, maybe Suspend/Resume would make sense in a namespace like
System.Diagnostics but not where they are today (in System.Threading.Thread)
because they should never be used as a general purpose synchronization
mechanims.

Bruno
 
N

Norman Diamond

Bruno Jouhier said:
No, I try to approach the multi-thread issues in a rigorous rather than
experimental manner. I try to keep the locking code as clean and well
organized as possible and I use assertions whenever I can to verify that
the right monitors are acquired in the right order.

Me too, but my question was about debugging not design.
If I had to experiment with slowing down some threads, I would probably do
it by inserting wait calls rather than suspending and resuming threads.

And recompile between every run? Well OK, actually that's not such a rare
technique any more...
It looks to me that Suspend and Resume do not belong to application code,
the VM may use such calls, and special tools like debuggers may use them
too, but it does not make sense to call them from the application itself,

Mostly I agree. The exception is that there are occasions when a thread has
to be created as suspended and the application code has to fix it up and
resume it once.
The situation with the .NET suspend/resume is very different from the
situation with the OS suspend/resume

Oh yeah, this isn't a Win32 newsgroup. OK.
 
B

Bruno Jouhier

It looks to me that Suspend and Resume do not belong to application code,
Mostly I agree. The exception is that there are occasions when a thread
has to be created as suspended and the application code has to fix it up
and resume it once.

Why not do it with a monitor?

Bruno
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top