Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

thread safety

1 view
Skip to first unread message

E. Robert Tisdale

unread,
Jun 7, 2003, 3:05:48 PM6/7/03
to
My understanding is that all local storage
in a Fortran subroutine of function could be static
and that this means that they *cannot* be "thread safe".
If one thread is interrupted before completing
a function or subroutine and another thread
calls that same function or subroutine
and modifies the local static storage
the result for the previous thread could be corrupted.

Steve Lionel

unread,
Jun 7, 2003, 4:52:14 PM6/7/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE2378C...@jpl.nasa.gov...

> My understanding is that all local storage
> in a Fortran subroutine of function could be static
> and that this means that they *cannot* be "thread safe".

This was true in Fortran 77 (emphasis on the "could"), but as of Fortran 90,
it's possible to have non-static local variables - especially automatic
arrays. More important, Fortran 90 introduced the RECURSIVE procedure
attribute which specifies that the procedure be reentrant (but reentrant is
not the same as thread-safe), implying non-static storage.

> If one thread is interrupted before completing
> a function or subroutine and another thread
> calls that same function or subroutine
> and modifies the local static storage
> the result for the previous thread could be corrupted.

True, though there's more to it than that. The Fortran standard doesn't say
anything about threads - not even to acknowledge the existence of the
concept - so whether or not you can write thread-safe Fortran code is
implementation-dependent. Most implementations do make it possible, but you
need to consult the vendor documentation for the details.

Thread safety requires more than just non-static data. First, the code must
be able to withstand having two (or more) invocations of the same procedure
executing in parallel. Simple recursion/reentrancy implies a strict
nesting, which is not as rigorous. Less obvious is that the run-time
environment (I/O in particular) also has to be thread-safe. In the
implementations I am familiar with, you need to specify an option when
compiling to enable thread-safety in the run-time environment. If your
compiler doesn't offer a thread-safe environment, you need to make sure that
run-time library calls are not executed in more than one thread at a time.

Consult your compiler's documentation for further information.
--

Steve Lionel
Software Products Division
Intel Corporation
Nashua, NH

User communities for Intel Fortran and Compaq Visual Fortran:
http://intel.com/IDS/forums/fortran


Richard Maine

unread,
Jun 9, 2003, 1:54:47 AM6/9/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> writes:

> My understanding is that all local storage
> in a Fortran subroutine of function could be static
> and that this means that they *cannot* be "thread safe".

Um. That would seem to be a non-sequitur. Your "could"
and "cannot" don't go together right, even if the first
part were true, but...

1. No, all storage cannot be static. There are several
things that cannot be implemented with static storage.
Automatic arrays, for example. Or more interestingly
for this question, non-saved local variables in recursive
procedures.

2. The fact that a compiler "could" implement something
as static, doesn't mean that it has to. If the compiler
were required to implement things as static memory, then
yes, that would mean that it "cannot" be thread safe.
But there is no such requirement. The fact that a compiler
may implement something as static just means that there
*MAY* be implementations that are non-thread-safe.
That's a pretty big difference from saying that they
cannot be thread safe.

3. Consider my point 1. In particular the bit about recursive.
If you want a procedure to be thread safe, I recommend
declaring it to be recursive. While that doesn't actually
guarantee thread safety, it certainly improves the odds.

4. If you want a guarantee of thread safety, check the documentation
of the particular compiler. For some recent compilers, I've
seen specific command-line switches to request thread-safe
code.

--
Richard Maine
email: my last name at domain
domain: isomedia dot com

E. Robert Tisdale

unread,
Jun 9, 2003, 2:11:22 PM6/9/03
to
Richard Maine wrote:

Evidently, it is impossible to write *portable* thread safe programs
in Fortran because the compiler may make local storage "static".

Richard Edgar

unread,
Jun 9, 2003, 3:51:55 PM6/9/03
to

>Evidently, it is impossible to write *portable* thread safe programs
>in Fortran because the compiler may make local storage "static".

What if the routines in question are declared PURE?

Richard

--
Richard Edgar
Robinson College
All Opinions My Own etc.

James Giles

unread,
Jun 9, 2003, 3:38:25 PM6/9/03
to

"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE4CDCA...@jpl.nasa.gov...

> Richard Maine wrote:
...
> > 1. No, all storage cannot be static. There are several
> > things that cannot be implemented with static storage.
> > Automatic arrays, for example. Or more interestingly
> > for this question, non-saved local variables in recursive
> > procedures.
...

> > 3. Consider my point 1. In particular the bit about recursive.
> > If you want a procedure to be thread safe, I recommend
> > declaring it to be recursive. While that doesn't actually
> > guarantee thread safety, it certainly improves the odds.
...

> Evidently, it is impossible to write *portable* thread safe programs
> in Fortran because the compiler may make local storage "static".

You didn't read what Rich wrote. A recursive procedure may not
be guaranteed thread-safe. But, the cause any threading problems
would *not* be static storage. There is no non-saved variable
that can be implemented with static storage in a recursive
procedure. Presumably your procedures would not have
SAVEd variables if you want to make them thread-safe.
Well, not without protecting them with semaphores or
other locks (maybe such variables would be part of the
semaphore mechanism on a given implementation).

--
J. Giles


E. Robert Tisdale

unread,
Jun 9, 2003, 5:22:11 PM6/9/03
to
Richard Edgar wrote:
> In article <3EE4CDCA...@jpl.nasa.gov>, E.Robert...@jpl.nasa.gov wrote:
>
>
>>Evidently, it is impossible to write *portable* thread safe programs
>>in Fortran because the compiler may make local storage "static".
>
>
> What if the routines in question are declared PURE?

I'll bite.

Dick Hendrickson

unread,
Jun 9, 2003, 6:15:29 PM6/9/03
to

James Giles wrote:
>
> "E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
> news:3EE4CDCA...@jpl.nasa.gov...
> > Richard Maine wrote:
> ...
> > > 1. No, all storage cannot be static. There are several
> > > things that cannot be implemented with static storage.
> > > Automatic arrays, for example. Or more interestingly
> > > for this question, non-saved local variables in recursive
> > > procedures.
> ...

This isn't completely true. A lame-brained, half-baked implemenmtation
could easily reserve 100 words for each automatic array at compile time
and at run time check the dimensions. If the size is less than 100,
it runs (using only part of the static reserved storage) otherwise,
it issues an error message about too much storage. (This is, in
effect, what happens now with stacks and heaps anyhow.) Similarly,
a compiler could limit recursive depth to 10 and then compile 10
copies of the routine, each with static storage, and do enough
name mangling to get the calls straight. I think you can treat
pointers that are allocated just like allocatable arrays, but I'm
too lazy to think that one through.

The real point is that Fortran doesn't contemplate threads, and so
you can't count on implementations to do the right thing for
threads by magic. But, if an implementation tries to be thread safe,
it can make it work. But, you can't guarantee portability in a
way that the standard guarantees will work on all machines.

Dick Hendrickson

James Giles

unread,
Jun 9, 2003, 6:17:39 PM6/9/03
to

"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE4FA83...@jpl.nasa.gov...
> Richard Edgar wrote:
...

> > What if the routines in question are declared PURE?
>
> I'll bite.
>
> What if the routines in question are declared PURE?

Well, PURE was specifically designed to support a certain kind
of parallel computing. They aren't automatically completely thread-
safe. They can depend on COMMON and/or MODULE variables
that other threads may change. If you use the parallel computing
paradigm the feature was designed for, then you'll be safe. If you
avoid using COMMON and/or MODULE variables, at least among
the different threads, you should still be safe.

--
J. Giles

James Giles

unread,
Jun 9, 2003, 6:31:15 PM6/9/03
to

"Dick Hendrickson" <dick.hen...@att.net> wrote in message
news:3EE50844...@att.net...

...
> This isn't completely true. A lame-brained, half-baked implemenmtation
> could easily reserve 100 words for each automatic array at compile time
> and at run time check the dimensions. If the size is less than 100,
> it runs (using only part of the static reserved storage) otherwise,
> it issues an error message about too much storage. (This is, in
> effect, what happens now with stacks and heaps anyhow.) Similarly,
> a compiler could limit recursive depth to 10 and then compile 10
> copies of the routine, each with static storage, and do enough
> name mangling to get the calls straight. I think you can treat
> pointers that are allocated just like allocatable arrays, but I'm
> too lazy to think that one through.

Even guaranteed thread-safe parallel computing environments
may have limits on the number of instances that mey operate
together. This is independent of the question of whether the
threads operating *within* those limits are safely independent.
The point is that recursive routines have useful limitations
on what the implementation can do. If you have them supported,
you can be assured the instances of your variables don't interfere
with each-other in the different invocations of the procedure.

How this is accompished internally is irrelevant. Their user-visible
behavior is *not* consistent with the semantics of static storage.
If the feature is emulated using static storage internally, that fact
*must* be transparent to the program.

> The real point is that Fortran doesn't contemplate threads, and so
> you can't count on implementations to do the right thing for
> threads by magic. But, if an implementation tries to be thread safe,
> it can make it work. But, you can't guarantee portability in a
> way that the standard guarantees will work on all machines.

That is the point. But, whatever mechanism used by implementations
that *do* support threads, it cannot hurt to consider the semantic
properties of RECURSIVE as a starting model. The actual implementation
is likely to have similar rules.

--
J. Giles


Richard Maine

unread,
Jun 9, 2003, 9:48:52 PM6/9/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> writes:

> Evidently, it is impossible to write *portable* thread safe programs
> in Fortran because the compiler may make local storage "static".

No, that is still not a correct inference. The compiler *MAY NOT*
make nonsaved local storage static in a recursive procedure. If
avoiding static storage were the only issue, then you can do that
quite portably by declaring procedures to be recursive.

It is impossible to write portable thread-safe programs for reasons
much more fundamental than that. As Steve discussed, being thread safe
involves a lot more than avoiding static variables. See his post for
more on that. It is a much bigger issue than just avoiding static
variables, which is easy.

E. Robert Tisdale

unread,
Jun 10, 2003, 12:17:58 AM6/10/03
to
Richard Maine wrote:

> E. Robert Tisdale writes:
>
>>Evidently, it is impossible to write *portable* thread safe programs
>>in Fortran because the compiler may make local storage "static".
>
> No, that is still not a correct inference. The compiler *MAY NOT*
> make nonsaved local storage static in a recursive procedure. If
> avoiding static storage were the only issue, then you can do that
> quite portably by declaring procedures to be recursive.
>
> It is impossible to write portable thread-safe programs for reasons
> much more fundamental than that. As Steve discussed, being thread safe
> involves a lot more than avoiding static variables.
> See his post for more on that. It is a much bigger issue
> than just avoiding static variables, which is easy.

I *can* write portable thread safe programs in C.

I can't write portable thread safe programs in Fortran 77 because
Fortran 77 does *not* support recursive subroutines or functions.

I *can* write portable thread safe programs in Fortran 90
only by declaring every subroutine and function RECURSIVE.

Greg Lindahl

unread,
Jun 10, 2003, 2:47:56 AM6/10/03
to
In article <3EE55BF6...@jpl.nasa.gov>,

E. Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:

>I *can* write portable thread safe programs in Fortran 90
>only by declaring every subroutine and function RECURSIVE.

How does that make common blocks thread-safe?

Does the standard guarantee that the system Fortran library is
thread-safe? Remember that F77 functions have I/O limits due to
re-entrancy issues; threading is subtly different.

greg

Rob

unread,
Jun 10, 2003, 2:33:36 AM6/10/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE55BF6...@jpl.nasa.gov...

> Richard Maine wrote:
>
> > E. Robert Tisdale writes:
> >
> >>Evidently, it is impossible to write *portable* thread safe programs
> >>in Fortran because the compiler may make local storage "static".
> >
> > No, that is still not a correct inference. The compiler *MAY NOT*
> > make nonsaved local storage static in a recursive procedure. If
> > avoiding static storage were the only issue, then you can do that
> > quite portably by declaring procedures to be recursive.
> >
> > It is impossible to write portable thread-safe programs for reasons
> > much more fundamental than that. As Steve discussed, being thread safe
> > involves a lot more than avoiding static variables.
> > See his post for more on that. It is a much bigger issue
> > than just avoiding static variables, which is easy.
>
> I *can* write portable thread safe programs in C.

No you can't. As the C standard says nothing that is even loosely
related to multithreading, it is not possible to write a multithreaded
program (let alone a thread safe one) in C, and guarantee portability.

There are separate specifications, such as posix, that are concerned
with (among other things) multithreading. If you follow those
specifications, you can usually write multithreaded C code that
is portable between (say) posix compliant systems. But not portable
to other systems.


>
> I can't write portable thread safe programs in Fortran 77 because
> Fortran 77 does *not* support recursive subroutines or functions.

Not really. Recursion and multithreading are two separate things, even
if some of the requirements for recursion are also requirements
for thread safety.

The most common reason that it isn't possible to write multithreaded
code in f77 is that most f77 compilers do not support the notion of
multithreading.


>
> I *can* write portable thread safe programs in Fortran 90
> only by declaring every subroutine and function RECURSIVE.
>

That's a bit of an overstatement. There is more to making a
F90 subprogram thread safe than declaring it recursive. It is
certainly possible to write a recursive function that is not
thread safe.

The Fortran standards, like the C standard, are totally silent on
the topic of threads. So multithreaded programming typically
relies on compiler and library extensions beyond the standard.

Dan Nagle

unread,
Jun 10, 2003, 8:41:54 AM6/10/03
to
Hello,

On Mon, 09 Jun 2003 21:17:58 -0700, "E. Robert Tisdale"
<E.Robert...@jpl.nasa.gov> wrote:

<snip>


>
>I *can* write portable thread safe programs in C.

Only by avoiding certain standard C constructs, e.g., errno.
And only if the supporting rtl allows it. For example, MSVC
requires that you link with a different version of the rtl
to execute a multithreaded program. Note that the words "thread",
"parallel" and "multiprocessor" do not appear in the C99 standard.

Furthermore, the C standard is written in terms of a sequential
abstract processor; a C99 standard conforming implementation
need not support multithreaded programs.


>
>I can't write portable thread safe programs in Fortran 77 because
>Fortran 77 does *not* support recursive subroutines or functions.

You can write portable thread safe programs in Fortran 77.
Recipe: take all local variables for the procedures you want
to execute in parallel, and put them into a common block;
then change them into arrays of a size with one element for each
thread, indexed by thread number. (Win32 threads and pthreads
have functions which perform this same trick.)


>
>I *can* write portable thread safe programs in Fortran 90
>only by declaring every subroutine and function RECURSIVE.

For some compilers, you may have to use the recursive keyword.
For any compiler, Fortran or C, you must set a compiler option
to request a multithreaded program, *if* such an option exists
for that compiler. And, for any compiler, the underlying
operating system must support multithreading. For example,
an MSVC program which runs multithreaded on WinNT won't run
multithreaded on Win98.

Multithreading is a popular, but not universal, implementation.
Some compilers, run time libraries and operating systems support
multithreading, some don't. What do you mean by "portable"?
(Any "modern" OS? What's "modern"?)

--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.

Greg Chien

unread,
Jun 10, 2003, 9:59:27 AM6/10/03
to
"Dan Nagle" wrote

> And, for any compiler, the underlying operating system must support
> multithreading. For example, an MSVC program which runs
> multithreaded on WinNT won't run multithreaded on Win98.

What?! I don't know how our product works on Win98 ;-)

From Chapter 14 of Windows 98 Developers Handbook by Ezzell and Blaney (in
MSDN):
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnw98bk/html/chapterfourteenmultiplethreadingapplications.asp
(all in one line)

--
Best Regards,
Greg Chien
e-mail: remove n.o.S.p.a.m.
http://protodesign-inc.com


Dan Nagle

unread,
Jun 10, 2003, 11:40:08 AM6/10/03
to
Hello,

On Tue, 10 Jun 2003 13:59:27 GMT, "Greg Chien"
<gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

>"Dan Nagle" wrote
>> And, for any compiler, the underlying operating system must support
>> multithreading. For example, an MSVC program which runs
>> multithreaded on WinNT won't run multithreaded on Win98.

^^^^^^^^^^^^^
By which I mean "with more than one thread executing at a time",
perhaps an overly strict meaning. Hmm... OK, more than
one thread can exist at a time with Win98, but they may use
only s subset of the Win32 thread API without generating errors.


>
>What?! I don't know how our product works on Win98 ;-)

Your product works one thread executing at a time on Win98.
Multiple processors are supported by the WinNT/2000/XP side
of the Win family.

And don't tell me you're using the single threaded version
of the MSVC rtl. :-) You had to select an option in the MSVS
to do that (or equivalent on the command line). If said option
didn't exist, your standard C program is single threaded.
The point I was trying to make (evidently, badly) was that
multithreading requires rtl and OS support, as well as language
support. Where the rtl and OS support exists, there's likely
to be a way to get the language support as well.

In a way, your experience with your product proves the point.
It's only multithreaded to the extent the version of Windows allows.


>
>From Chapter 14 of Windows 98 Developers Handbook by Ezzell and Blaney (in
>MSDN):
>http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnw98bk/html/chapterfourteenmultiplethreadingapplications.asp
>(all in one line)

Which simply re-directs me to
http://msdn.microsoft.com/library/shared/deeptree/bot/bot.asp?dtcnfg=/library/deeptreeconfig.xml
OK, I'll poke about a bit ...

Ah! Perhaps you meant (well, MS "updated" their web site :-)
http://msdn.microsoft.com/library/en-us/dnw98bk/html/chapterfourteenmultiplethreadingapplications.asp
from which I quote (third paragraph)
"This is how threads work in a single-CPU system, ..."
before going on to discuss future systems,
which we'll all have Real Soon Now.
By future systems, context indicates MS means multiprocessors.
So perhaps a future version of the Win98 side of the Windows family
will support multiprocessors, or perhaps Windows
will have achieved unity by then.

James Giles

unread,
Jun 10, 2003, 11:54:30 AM6/10/03
to

"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE55BF6...@jpl.nasa.gov...
...

> I *can* write portable thread safe programs in Fortran 90
> only by declaring every subroutine and function RECURSIVE.

Or, PURE or ELEMENTAL. Or, the program may be thread-safe
if you just carefully don't use those features that aren't (like
referencing global or SAVEd data without a semaphore). But,
even that doesn't make the program necessarily portable since
there is nothing in the Fortran standard pertaining to threads.

Threads, in most languages, are system dependent. An Ada
implementation presumably allows portable parallel programming
on those systems that actually have support for it (otherwise,
the parallelism is emulated). Fortran can run on parallel
implementations that conform to the expectations of HPF
and the like. Other than that, you're on your own.

--
J. Giles


Greg Chien

unread,
Jun 10, 2003, 12:18:29 PM6/10/03
to
"Dan Nagle" wrote

> Your product works one thread executing at a time on Win98.

Looks to me that Win98 does time-slicing pretty well when multiple threads
are executing with a uni-processor machine.

> Multiple processors are supported by the WinNT/2000/XP side
> of the Win family.

Oh. I get it. You meant multi-processing. To me, multi-threading (one
process contains multiple reentrant execution threads), multi-programming
(a computing environment that allows multiple programs to run in separate
processes), and multi-processing (a computing environment that has
multiple processors) have different meanings. From these definitions,
Win98 does multi-threading and multi-programming, but not
multi-processing.

SIMON Claude

unread,
Jun 11, 2003, 7:49:12 AM6/11/03
to

A good way to do parallelism with Fortran in portable way is to
mix Ada tasking and Fortran. You don't need HPF nor OpenMP compiler.
Just a Fortran compiler wich can allocate local variable in the stack
and Gnat.
For shared array in writing access, the best way is to give each task an
index
range non overlapping the others ranges.

You can Mix G77 and Gnat at no cost.

Using local variable or array may speedup the program because of best
localisation
of data for cache use. For that, allocating them in the stack is the
best method.

C. Simon

Richard Maine

unread,
Jun 11, 2003, 11:33:19 AM6/11/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> writes:

> I *can* write portable thread safe programs in Fortran 90
> only by declaring every subroutine and function RECURSIVE.

I get the feeling that you didn't actually read most of the replies,
because you seem to be completely ignoring the main point made in
most of them. Avoiding static variables is the least of the
difficulties involved.

No, you can't write portable thread-safe programs in f90. There exist
compilers that do not have thread-safe run-time support. For that
matter, there exist operating systems that don't have a concept of
threads at all...but I suppose those don't count because one could say
that everything is "thread safe" on such systems in that the threads
(which don't exist) won't get you in trouble.

I don't think you can write portable thread-safe programs in C either.
Others have pointed that out and given more supporting data than I
could confidently do (though their data does agree with what I
expected to be the case).

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain

E. Robert Tisdale

unread,
Jun 11, 2003, 1:03:02 PM6/11/03
to
Richard Maine wrote:

> E. Robert Tisdale writes:
>
>>I *can* write portable thread safe programs in Fortran 90
>>only by declaring every subroutine and function RECURSIVE.
>
> I get the feeling that you didn't actually read most of the replies,

I have read and studied them all carefully
and they appear to me to be communicating some ambiguous
and even contradictory messages.

> because you seem to be completely ignoring
> the main point made in most of them.
> Avoiding static variables
> is the least of the difficulties involved.

But it *is* a show stopper.
If the Fortan compiler reserves static storage for any local variables,
they must be protected by mutual exclusion.
If the standard [de jure] permits the Fortran compilers
to reserve static storage for all local variables,
then, practically speaking, no two threads can execute
the same subroutine or function concurrently.
It would be practically impossible to implement
a high performance threaded application this way.


> No, you can't write portable thread-safe programs in f90.

James Giles wrote:

> E. Robert Tisdale wrote:
>
> > I *can* write portable thread safe programs in Fortran 90
> > only by declaring every subroutine and function RECURSIVE.
>

> Or, PURE or ELEMENTAL. Or, the program may be thread-safe
> if you just carefully don't use those features that aren't

> (like referencing global or SAVE'd data without a semaphore).

James Giles seems to imply that


I *can* write portable thread safe programs in Fortran 90
only by declaring every subroutine and function

RECURSIVE, PURE or ELEMENTAL.

> There exist compilers that do not have thread-safe run-time support.
> For that matter, there exist operating systems
> that don't have a concept of threads at all...

> but I suppose that those don't count because one could say that


> everything is "thread safe" on such systems
> in that the threads (which don't exist) won't get you in trouble.
>
> I don't think you can write portable thread-safe programs in C either.

I know how to write portable thread safe [sub]programs in C.
But I recommend that further discussion on this subject
be redirected to the comp.lang.c newsgroup.

> Others have pointed that out
> and given more supporting data than I could confidently do
> (though their data does agree with what I expected to be the case).

A colleague has told me that virtually all modern Fortran 77 compilers
do, in fact, use automatic storage (the stack) for all local variables
unless explicitly SAVE'd so it is indeed possible to write
portable thread safe [sub]programs in Fortran 77
if we can substitute the de facto standard for the standard de jure
(the ANSI/ISO Fortran 77 standard).

Duane Bozarth

unread,
Jun 11, 2003, 2:01:39 PM6/11/03
to

"E. Robert Tisdale" wrote:
>
> Richard Maine wrote:
>
> > E. Robert Tisdale writes:
> >

...snip...

> A colleague has told me that virtually all modern Fortran 77 compilers
> do, in fact, use automatic storage (the stack) for all local variables
> unless explicitly SAVE'd so it is indeed possible to write
> portable thread safe [sub]programs in Fortran 77
> if we can substitute the de facto standard for the standard de jure
> (the ANSI/ISO Fortran 77 standard).

Well, that is a non sequitor--substituting a non-standard subset of
compilers for standard-compliant compilers pretty much defines
"non-portable" to me... :)

James Giles

unread,
Jun 11, 2003, 2:55:40 PM6/11/03
to
I wrote:
> Or, PURE or ELEMENTAL. Or, the program may be thread-safe
> if you just carefully don't use those features that aren't (like
> referencing global or SAVE'd data without a semaphore).

E. Robert Tisdale wrote:

> James Giles seems to imply that
> I *can* write portable thread safe programs in Fortran 90
> only by declaring every subroutine and function
> RECURSIVE, PURE or ELEMENTAL.

Where do you see that? If the program doesn't use SAVEd
variables, COMMON variables, and/or MODULE variables
without the proper semaphore, monitor, or other mutual
exclusion protocol, then it could be thread-safe. It's
the thread-related parts of the code that aren't portable.
An implementation that permits threads will have to
state which conditions on the nature of the code apply.
You can't talk about it independently of the implementation.

The problem is that you're falsely claiming that you *can*
write portable threaded code in C (you can't) while you
can't write portable treaded codes in Fortran (which can
be *as* portably thread-safe as C - however thread-safe
that is). The requirements to write thread-safe code
are similar to, but not restricted to, the kinds of things
you do to make a code recursive. That's why *some*
implementations may require/permit the recursive
attribute for procedures to be invoked in parallel.
Similarly, an implementation may require other declarations
or conditions (like PURE or ELEMENTAL).

> I know how to write portable thread safe [sub]programs in
> C.
> But I recommend that further discussion on this subject
> be redirected to the comp.lang.c newsgroup.

No you don't. The C standard does not even mention threads.
Whatever you are doing *may* be working on all the C implementations
*you* presently use. That *doesn't* make it portable. Please
post a C code that uses *no* features not explicitly mentioned in
the Standard document if you wish to disprove my statement.
I don't believe you can.

The first thread-safe programs I ever wrote were in Fortran.
The rules of Fortran make threading simpler than those of C.

--
J. Giles

E. Robert Tisdale

unread,
Jun 11, 2003, 2:32:45 PM6/11/03
to
Duane Bozarth wrote:
>
> "E. Robert Tisdale" wrote:
>
>>A colleague has told me that virtually all modern Fortran 77 compilers
>>do, in fact, use automatic storage (the stack) for all local variables
>>unless explicitly SAVE'd so it is indeed possible to write
>>portable thread safe [sub]programs in Fortran 77
>>if we can substitute the de facto standard for the standard de jure
>>(the ANSI/ISO Fortran 77 standard).
>
>
> Well, that is a non sequitor--substituting
> a
> pretty much defines "non-portable" to me.

Who said anything about "substituting a non-standard subset of compilers
for standard-compliant compilers" besides you?

I think that you are confused.
Which of the modern Fortran 77 compilers
(that use automatic storage for local variables)
fail to comply with the ANSI/ISO Fortran 77 standard?
Are there any viable ANSI/ISO compliant Fortran 77 compilers
which *cannot* use automatic storage for local variables?

Duane Bozarth

unread,
Jun 11, 2003, 3:22:09 PM6/11/03
to

"E. Robert Tisdale" wrote:
>
> Duane Bozarth wrote:
> >
> > "E. Robert Tisdale" wrote:
> >
> >>A colleague has told me that virtually all modern Fortran 77 compilers
> >>do, in fact, use automatic storage (the stack) for all local variables
> >>unless explicitly SAVE'd so it is indeed possible to write
> >>portable thread safe [sub]programs in Fortran 77
> >>if we can substitute the de facto standard for the standard de jure
> >>(the ANSI/ISO Fortran 77 standard).
> >
> >
> > Well, that is a non sequitor--substituting
> > a
> > pretty much defines "non-portable" to me.
>
> Who said anything about "substituting a non-standard subset of compilers
> for standard-compliant compilers" besides you?

It's a paraphrase of what you said--using a set (which may or may not be
all inclusive) of compilers having a particular implementation strategy
(your "de facto" standard set) as opposed to the full set of
F77-compliant compilers (which may or may not be a different set, but
I'd presume it to be a larger set than the former).

> I think that you are confused.
> Which of the modern Fortran 77 compilers
> (that use automatic storage for local variables)
> fail to comply with the ANSI/ISO Fortran 77 standard?

Don't know, don't think it matters to the question...

> Are there any viable ANSI/ISO compliant Fortran 77 compilers
> which *cannot* use automatic storage for local variables?

Same response...

Richard Maine

unread,
Jun 11, 2003, 3:57:27 PM6/11/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> writes:

> Are there any viable ANSI/ISO compliant Fortran 77 compilers
> which *cannot* use automatic storage for local variables?

I'm sure that there are some, but I do not find myself motivated
to do the work of checking. I personally have used and could name
many standard-compliant f77 compilers in the past that didn't have
such a capability, but most of them are old enough that they
probably wouldn't meet the "viable" criterion (although they
include most of the widely used compilers of the 80s era).

I have a funny feeling that this undefined "viable" term is
circularly defined in that any compiler that otherwise met the
criteria would be declared as non-viable by definition. The
"game" isn't very fun in the first place, and is made less so
by my suspicion that the "rules" (definition of "viable") are
rigged. Don't think I'll play.

Heck. my personal definition of "viable" would probably exclude
anything that couldn't also do f90, but I somehow doubt that is
part of the definition intended here.

I'm also pretty sure that I have seen documentation of current
compilers that specifically states that they do not produce
thread-safe code (even when local variables are automatic), but
again, I'm not sufficiently motivated to dig up actual citations.
You had a representative of major compiler vendor comment on this.
If his word wasn't good enough, then I'm sure mine wouldn't be.

Greg Lindahl

unread,
Jun 11, 2003, 4:20:53 PM6/11/03
to
In article <MWKFa.1671$3o3.1...@bgtnsc05-news.ops.worldnet.att.net>,
James Giles <james...@worldnet.att.net> wrote:

>Where do you see that? If the program doesn't use SAVEd
>variables, COMMON variables, and/or MODULE variables
>without the proper semaphore, monitor, or other mutual
>exclusion protocol, then it could be thread-safe.

You left off I/O, which is commonly not re-entrant. Other
library routines might be that way, too.

-- greg

E. Robert Tisdale

unread,
Jun 11, 2003, 4:48:29 PM6/11/03
to
Richard Maine wrote:

> E. Robert Tisdale writes:
>
>>Are there any viable ANSI/ISO compliant Fortran 77 compilers
>>which *cannot* use automatic storage for local variables?
>
> I'm sure that there are some,
> but I do not find myself motivated to do the work of checking.
> I personally have used and could name
> many standard-compliant f77 compilers in the past that didn't have
> such a capability, but most of them are old enough that they
> probably wouldn't meet the "viable" criterion (although they
> include most of the widely used compilers of the 80s era).
>
> I have a funny feeling that this undefined "viable" term is
> circularly defined in that any compiler that otherwise met the
> criteria would be declared as non-viable by definition.
> The "game" isn't very fun in the first place

> and is made less so by my suspicion that the "rules"
> (definition of "viable") are rigged. Don't think I'll play.
>
> Heck. my personal definition of "viable"
> would probably exclude anything that couldn't also do f90

> but I somehow doubt that is part of the definition intended here.
>
> I'm also pretty sure that I have seen documentation
> of current compilers that specifically states that
> they do not produce thread-safe code
> (even when local variables are automatic), but again,
> I'm not sufficiently motivated to dig up actual citations.
> You had a representative of major compiler vendor comment on this.

Sorry. I missed this.
Which respondent was a representative of major compiler vendor?

> If his word wasn't good enough, then I'm sure mine wouldn't be.

This subprogram

float dot(const float x[], const float y[], int n) {
float t = (float)0;
int j = 0;
for (j = 0; j < n; ++j)
t += x[j]*y[j];
return t;
}

is thread safe. This subprogram

real function dot(x, y, n)
integer n
real x(n), y(n)
real t
integer j
t = 0.0
do 100 j = 1, n
t = t + x(j)*y(j)
100 continue
dot = t
end

might not be thread safe depending upon whether
the local variables j and t are allocated
from automatic or static storage.

My inclination is to tell our programmers that
they should *not* write code in Fortran
because the code emitted by Fortran compilers
cannot be used in multi-threaded applications.

If, on the other hand, I have convincing evidence
that all of the Fortran compilers that we care about
actually use automatic storage for all local variables
unless explicitly SAVE'd, then I can advise them
that they can safely write their code in Fortran
with a reasonable expectation that it can be used
in portable multi-threaded application programs.


James Giles

unread,
Jun 11, 2003, 5:44:42 PM6/11/03
to

"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> wrote in message
news:3EE7959D...@jpl.nasa.gov...
...

> This subprogram
>
> float dot(const float x[], const float y[], int n) {
> float t = (float)0;
> int j = 0;
> for (j = 0; j < n; ++j)
> t += x[j]*y[j];
> return t;
> }
>
> is thread safe. [...]

What makes you think so? Point to the passage of the C standard
that guarantees it. In any case, I see no multithread operations
here. Where's the portable mechanism for spawning separate
threads?

A Fortran PURE function can be written with the same constraints
on the *semantics* of the procedure itself. Any Fortran
implementation
intended to operate in a multi-threaded manner would not have any
problems with this. Is that simply something you choose to ignore?

--
J. Giles


Richard Edgar

unread,
Jun 11, 2003, 6:04:27 PM6/11/03
to

>If, on the other hand, I have convincing evidence
>that all of the Fortran compilers that we care about
>actually use automatic storage for all local variables
>unless explicitly SAVE'd

Well, since _you_ know which compilers _you_ care about, the obvious thing
to do would surely be to read _your_ documentation, wouldn't it?

Think about things logically: OpenMP is a fairly popular way of writing
parallel code (in both Fortran and C). Therefore, any compiler capable of
processing OpenMP 'enhanced' code is rather likely to be capable (perhaps
with appropriate compiler options) of emitting thread-safe code.

As for RECURSIVE..... if declaring a procedure recursive guarantees that
static storage is not used, you haven't got a thread safe compiler: you've
got one with a poor optimiser. As others have pointed out, just because a
procedure is recursive does not mean that it can't use static storage.

On the thread safety (or otherwise) of C: I don't know the details, but I
would echo the comments of those who suggest paying very close attention
to the standard. Most of the problems I have had in the past have stemmed
from the standard not saying what I thought it did. If the C standard says
nothing about threads, then it's probably possible to write an ISO/ANSI
compliant C compiler which does not produce thread safe code. This would
then eliminate C on the same grounds you are wary of Fortran.

Richard

--
Richard Edgar
Robinson College
All Opinions My Own etc.

Greg Chien

unread,
Jun 11, 2003, 6:08:36 PM6/11/03
to
"James Giles" wrote

> What makes you think so? Point to the passage of the C standard
> that guarantees it.

I suppose Section 5.1.2.3 Program execution in ANSI/ISO 9899-1990 (sorry,
I don't have the latest) has a paragraph that is relevant:
<Quote>
An instance of each object with automatic storage duration is associated
with entry into its block. Such an object exists and retains its
last-stored value during the execution of the block and while the block is
suspended (by a call of a function or receipt of a signal).
</Quota>

Richard Maine

unread,
Jun 11, 2003, 6:14:06 PM6/11/03
to
"E. Robert Tisdale" <E.Robert...@jpl.nasa.gov> writes:

> Richard Maine wrote:
> > You had a representative of major compiler vendor comment on this.

[automatic local variables being insufficient for thread safety]

> Sorry. I missed this.
> Which respondent was a representative of major compiler vendor?

Steve Lionel, who is a representative from probably the single
largest-selling commercial compiler today, and who also had
involvement with some very important historical compilers. I
almost always find Steve worth listening to. He said

> there's more to it than that. The Fortran standard doesn't say
> anything about threads - not even to acknowledge the existence of the
> concept - so whether or not you can write thread-safe Fortran code is
> implementation-dependent. Most implementations do make it possible, but you
> need to consult the vendor documentation for the details.

> Thread safety requires more than just non-static data. First, the code must
> be able to withstand having two (or more) invocations of the same procedure
> executing in parallel. Simple recursion/reentrancy implies a strict
> nesting, which is not as rigorous. Less obvious is that the run-time
> environment (I/O in particular) also has to be thread-safe. In the
> implementations I am familiar with, you need to specify an option when
> compiling to enable thread-safety in the run-time environment. If your
> compiler doesn't offer a thread-safe environment, you need to make sure that
> run-time library calls are not executed in more than one thread at a time.

> Consult your compiler's documentation for further information.

E. Robert Tisdale

unread,
Jun 11, 2003, 6:16:17 PM6/11/03
to
Richard Edgar wrote:

> E. Robert Tisdale wrote:
>
>>If, on the other hand, I have convincing evidence
>>that all of the Fortran compilers that we care about
>>actually use automatic storage for all local variables
>>unless explicitly SAVE'd
>
>
> Well, since _you_ know which compilers _you_ care about, the obvious thing
> to do would surely be to read _your_ documentation, wouldn't it?

What makes you think that I have documentation
for all of the Fortran compilers that we care about?
I don't think that we have all nearly of the Fortran compilers
that we care about -- but we are obliged to write portable code anyway.

>
> Think about things logically: OpenMP is a fairly popular way of writing
> parallel code (in both Fortran and C). Therefore, any compiler capable of
> processing OpenMP 'enhanced' code is rather likely to be capable(perhaps
> with appropriate compiler options) of emitting thread-safe code.
>
> As for RECURSIVE..... if declaring a procedure recursive guarantees that
> static storage is not used, you haven't got a thread safe compiler: you've

> got one with a poor optimizer. As others have pointed out, just because a


> procedure is recursive does not mean that it can't use static storage.

Could you please show an example of a subroutine that is thread safe
with static local variables not protected by mutual exclusion?

>
> On the thread safety (or otherwise) of C: I don't know the details, but I
> would echo the comments of those who suggest paying very close attention
> to the standard. Most of the problems I have had in the past have stemmed
> from the standard not saying what I thought it did. If the C standard says
> nothing about threads, then it's probably possible to write an ISO/ANSI
> compliant C compiler which does not produce thread safe code. This would
> then eliminate C on the same grounds you are wary of Fortran.

I think that you missed the point completely.
The discussion is about "thread safety" and *not* multi-threading.
The ANSI/ISO C standards don't need to say anything about threads.
The standard specifies automatic storage for local variables unless
the `static' qualifier is used to explicitly specify static storage.
Please direct further discussion about the ANSI/ISO C standards
to the comp.std.c newsgroup.

E. Robert Tisdale

unread,
Jun 11, 2003, 7:17:11 PM6/11/03
to
Steve Lionel wrote:

> E. Robert Tisdale wrote:
>
> > My understanding is that all local storage
> > in a Fortran subroutine of function could be static
> > and that this means that they *cannot* be "thread safe".

> This was true in Fortran 77 (emphasis on the "could") but,
> as of Fortran 90, it's possible to have non-static local variables -
> especially automatic arrays. More important,
> Fortran 90 introduced the RECURSIVE procedure attribute
> which specifies that the procedure be reentrant
> (but reentrant is not the same as thread-safe),
> implying non-static storage.
>
> > If one thread is interrupted before completing
> > a function or subroutine and another thread
> > calls that same function or subroutine
> > and modifies the local static storage
> > the result for the previous thread could be corrupted.
>
> True, though there's more to it than that.


> The Fortran standard doesn't say anything about threads -

Nor does it need to.

> not even to acknowledge the existence of the concept -
> so whether or not you can write thread-safe Fortran code
> is implementation-dependent.

The ANSI/ISO Fortran standards
don't need to say anything about thread safety.
It would be sufficient to specify automatic storage
for local variables to allow Fortran programmers
to write portable thread safe programs.

> Most implementations do make it possible

> but you need to consult the vendor documentation for the details.
>
> Thread safety requires more than just non-static data.
> First, the code must be able to withstand having two (or more)

> invocations of the same procedure executing [concurrently].


> Simple recursion/reentrancy implies a strict nesting,
> which is not as rigorous. Less obvious is that the run-time
> environment (I/O in particular) also has to be thread-safe.

> In the implementations that I am familiar with,


> you need to specify an option when compiling
> to enable thread-safety in the run-time environment.
> If your compiler doesn't offer a thread-safe environment,
> you need to make sure that run-time library calls
> are not executed in more than one thread at a time.

I just assumed that everybody contributing to this discussion
was well acquainted with all of the issues concerning
thread safety and multi-threaded programs
but that is *not* the issue at hand.
The issue at hand is whether or not it is *possible*
to write portable thread safe [sub]programs --
subprograms that are reentrant and all I need for that
is reasonable expectation that Fortran compilers
(at least all of the Fortran compilers that I should care about)
can emit code to reserve automatic storage for local variables.
Issues about mutual exclusion for global variables
and thread safe run time libraries can be dealt with.
But the show stops if Fortran compilers emit code
that always reserves static storage for local variables.

> Consult your compiler's documentation for further information.

I know that my Intel Fortran compiler emits code
which *does* reserve static storage for local variables.
If I can't find a way to prevent it from doing this,
I must advise programmers that they can't use it
for multi-threaded applications or thread safe libraries.
The Intel Fortran compiler *is* important to us,
and I must advise programmers *not* to use it
if we can't rely upon it to emit thread safe code.

Gary L. Scott

unread,
Jun 11, 2003, 9:21:13 PM6/11/03
to

You should be utilizing a compiler that provides explicit support for
multithreading in any case and following the directions for your
compiler to produce thread-safe code, not trying to guess at the various
standard-unspecified behaviours.


--

Gary Scott
mailto:gary...@ev1.net

Fortran Library
http://www.fortranlib.com

Support the GNU Fortran G95 Project: http://g95.sourceforge.net

E. Robert Tisdale

unread,
Jun 11, 2003, 9:58:02 PM6/11/03
to
Gary L. Scott wrote:

> You should be utilizing a compiler

> that provides explicit support for multi threading in any case


> and following the directions for your compiler
> to produce thread-safe code,

> not trying to guess at the various standard-unspecified behaviors.

If this is true, then I should tell our programmers
that they should *not* use Fortran to write portable [sub]programs
because there is no way to guarantee that such code is thread safe.

James Giles

unread,
Jun 12, 2003, 2:01:19 AM6/12/03
to
Greg Chien wrote:
> "James Giles" wrote
>> What makes you think so? Point to the passage of the C standard
>> that guarantees it.
>
> I suppose Section 5.1.2.3 Program execution in ANSI/ISO 9899-1990 (sorry,
> I don't have the latest) has a paragraph that is relevant:
> <Quote>
> An instance of each object with automatic storage duration is associated
> with entry into its block. Such an object exists and retains its
> last-stored value during the execution of the block and while the block is
> suspended (by a call of a function or receipt of a signal).
> </Quota>

Well, that *might* be relevant. There is no reason I can think
of that threads must behave differently than, say, signal handling.
Multi-threaded programs tend to have at least some shared data
(otherwise, why not just run independent processes). But, signal
handlers might also share data with the rest of the program.

However, there is nothing in the quoted passage that *requires*
implementations to treat the above safely in multi-threaded programs.
The C standard simply doesn't cover the issue. Semantically,
Fortran's non-SAVEd local variables are pretty much the same
as C's automatic variables. There is no reason that they would
behave any differently. But, there is also no requirement that
implementations work the same. Threading is simply beyond the
scope of either standard.

--
J. Giles


Richard Edgar

unread,
Jun 12, 2003, 3:28:01 AM6/12/03
to

>> Well, since _you_ know which compilers _you_ care about, the obvious thing
>> to do would surely be to read _your_ documentation, wouldn't it?
>
>What makes you think that I have documentation
>for all of the Fortran compilers that we care about?

Becuase that would be logical?

>> As for RECURSIVE..... if declaring a procedure recursive guarantees that
>> static storage is not used, you haven't got a thread safe compiler: you've
>> got one with a poor optimizer. As others have pointed out, just because a
>> procedure is recursive does not mean that it can't use static storage.
>
>Could you please show an example of a subroutine that is thread safe
>with static local variables not protected by mutual exclusion?

I doubt it - but what has that got to do with the fact that (some)
recursive functions can use static storage and still work perfectly?

>The discussion is about "thread safety" and *not* multi-threading.

Could you please explain how the two are not so inimitately related as to
be the same thing?

Richard Edgar

unread,
Jun 12, 2003, 3:44:18 AM6/12/03
to
In article <ELNFa.158129$M01.74412@sccrnsc02>, "Greg Chien"
<gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

>"James Giles" wrote
>> What makes you think so? Point to the passage of the C standard
>> that guarantees it.
>
>I suppose Section 5.1.2.3 Program execution in ANSI/ISO 9899-1990 (sorry,
>I don't have the latest) has a paragraph that is relevant:
><Quote>
>An instance of each object with automatic storage duration is associated
>with entry into its block. Such an object exists and retains its
>last-stored value during the execution of the block and while the block is
>suspended (by a call of a function or receipt of a signal).
></Quota>

I'm not certain that that's the appropriate bit (although I'm not terribly
good at understanding standardese). AIUI, the Fortran standard does not
specify where non-SAVE'd local variables are stored. This means that they
_could_ be statically allocated, and hence the emitted code will not be
thread safe (although I suspect that most modern Fortran compilers will
have something like a -stackvar compiler option, which is the Sun option
for forcing stack allocation). For C programs to _always_ avoid this
particular pitfall (although there are many others beyond the scope of
*either* language) there would have to be a part of the standard which
said that in

void func( void )
{
int i;

// etc.
}

the variable i was _never_ statically allocated (since it is not declared
static). The OP seems curiously reluctant to point to the specific part of
the standard which guarantees this. This makes me wonder if 'normal
practice' and 'standard compliant practice' are being confused.

Gary L. Scott

unread,
Jun 12, 2003, 7:06:52 AM6/12/03
to

You should tell them not to use C also. How about Ada?

Dan Nagle

unread,
Jun 12, 2003, 9:40:22 AM6/12/03
to
Hello,

On Wed, 11 Jun 2003 10:03:02 -0700, "E. Robert Tisdale"
<E.Robert...@jpl.nasa.gov> wrote:

>Richard Maine wrote:
>
>> E. Robert Tisdale writes:
>>
>>>I *can* write portable thread safe programs in Fortran 90
>>>only by declaring every subroutine and function RECURSIVE.
>>
>> I get the feeling that you didn't actually read most of the replies,
>
>I have read and studied them all carefully
>and they appear to me to be communicating some ambiguous
>and even contradictory messages.

Probably because different posters are (IMNSHO, obviously)
posting under different assumptions and with different
definitions of "standard", "portable", etc.


>
>> because you seem to be completely ignoring
>> the main point made in most of them.
>> Avoiding static variables
>> is the least of the difficulties involved.
>
>But it *is* a show stopper.

No, it isn't. I posted how to use static variables
in a thread-safe way (use arrays indexed by thread number).
This is the technique used by the Win32 tls*() calls and
by the pthread_key_*() calls.

>If the Fortan compiler reserves static storage for any local variables,
>they must be protected by mutual exclusion.

Do you mean a mutex ?!?

I don't see how a mutex can change a shared (process scope)
variable into a private (thread scope) variable. Indeed,
single-threading access to a shared variable merely assures
that a whole value, rather than a partial value,
is overwritten by another thread (for example, both parts
of a thread private complex number might be overwritten
by both parts of a different thread private complex number).

You appear to have confused scope with atomicity.

>If the standard [de jure] permits the Fortran compilers
>to reserve static storage for all local variables,
>then, practically speaking, no two threads can execute
>the same subroutine or function concurrently.

... unless they are rewritten to use arrays indexed
by thread number as their local variables, + they have
rtl support, + they have os support. (BTW, I do _not_
endorse doing so, the performance on any cache based
multiprocessor will be terrible due to false sharing).

In order to multithread in C, Fortran,
or any other language *which does
not explicitly support multithreading*, you will need
a compiler switch to select multithreading. That is,
if you are programming in Ada or Java (or some other language
whose standard specifies multithreading), you may portably
(by which I mean, within the standard) write multithreaded
programs. With other languages (C, Fortran, etc.), you
will need compiler + rtl + OS support. Storage of local
variables is the least of it.

>It would be practically impossible to implement
>a high performance threaded application this way.

Parallelization, by any means, *always* introduces some
overhead, communications and synchronization time.
The (performance) question is, Can you "get back" the time
wasted synchronizing by overlapped execution on different
processors? Here, performance issues are understood
to be distinct from correctness issues.


>
>
>> No, you can't write portable thread-safe programs in f90.
>
>James Giles wrote:
>
> > E. Robert Tisdale wrote:
> >
> > > I *can* write portable thread safe programs in Fortran 90
> > > only by declaring every subroutine and function RECURSIVE.
> >
> > Or, PURE or ELEMENTAL. Or, the program may be thread-safe
> > if you just carefully don't use those features that aren't
> > (like referencing global or SAVE'd data without a semaphore).
>
>James Giles seems to imply that
>I *can* write portable thread safe programs in Fortran 90
>only by declaring every subroutine and function
>RECURSIVE, PURE or ELEMENTAL.

Some compilers, which support multithreading, may require
that procedures be declared recursive, or elemental, or pure.
Depending upon your definition of "portably", you may consider
such declarations necessary.


>
>> There exist compilers that do not have thread-safe run-time support.
>> For that matter, there exist operating systems
>> that don't have a concept of threads at all...
>> but I suppose that those don't count because one could say that
>> everything is "thread safe" on such systems
>> in that the threads (which don't exist) won't get you in trouble.
>>
>> I don't think you can write portable thread-safe programs in C either.
>
>I know how to write portable thread safe [sub]programs in C.

But only for those C compilers which have a thread-safe rtl and
which are compiling programs for an os which supports multihtreading.

An example posted earlier in this thread is that MSVC requires
a different rtl for multithreaded programs, so you *must*
select an option in the IDE to multithread (or the corresponding
command line option to the compiler). Is that portable?
I don't know (your definition of portable). Compiler-specific
switches are not part of the C99 standard.

Additionally, the _degree_ to which the os supports multithreading
greatly affects the performance obtained. For example, those
versions of Windows *which support multiprocessors* may give
a speed-up to applications via multithreading, those versions
which support a single processor will have a much more difficult
time doing so. (One could use multithreading to hide the latency
of input/output, which might provide a speed-up on a single processor,
but the "cpu time" will increase for multithreaded programs
due to the synchronization overhead.)

In an earlier post, I confused the point: That a Fortran program
would want to multithread on a single processor system. I was
assuming multithreading to reduce cpu time. I regret any confusion
caused.

>But I recommend that further discussion on this subject
>be redirected to the comp.lang.c newsgroup.
>
>> Others have pointed that out
>> and given more supporting data than I could confidently do
>> (though their data does agree with what I expected to be the case).
>
>A colleague has told me that virtually all modern Fortran 77 compilers
>do, in fact, use automatic storage (the stack) for all local variables
>unless explicitly SAVE'd so it is indeed possible to write
>portable thread safe [sub]programs in Fortran 77
>if we can substitute the de facto standard for the standard de jure
>(the ANSI/ISO Fortran 77 standard).

The same is true of C: There may well be a "usual way" of writing
multithreaded programs, but it presumes compiler + rtl + os
support. And the "usual way" of writing multithreaded programs
in C requires that the program restrict itself to a subset
of standard C.

To clarify another point: Many Fortran 77 compilers (I find
the term "modern Fortran 77 compilers" to be a bit of an oxymoron)
have a switch to select static allocation versus stack allocation
for local variables, if only to support Fortran 66 programs
requiring static allocation. Indeed, many modern (read: "Fortran 95")
compilers have a switch with the same functionality
for the same purpose (that is, to compile the same older programs).

Dan Nagle

unread,
Jun 12, 2003, 9:49:57 AM6/12/03
to
Hello,

The section of C99 quoted below also speaks of "the"
sequence of execution, and describes how sequence points
divide the execution sequence into "shall be complete"
and "shall not have taken place" regimes, which clearly
indicates (to me, at least) a unique before and after
relationship, viz, a single thread.

And why does "retains its last-stored value" imply
that another thread can't overwrite it when the standard
speaks of a single execution sequence (which, after all,
is what may be interrupted)?

--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.

Greg Chien

unread,
Jun 12, 2003, 10:13:58 AM6/12/03
to
"Richard Edgar" wrote

> >The discussion is about "thread safety" and *not* multi-threading.
> Could you please explain how the two are not so intimately related

> as to be the same thing?

Suppose I were to sell a numerical library, I would write it in such a way
that I could advertise it as "thread-safe." It does not mean that there
is any thread creation or synchronization code in my library routines, but
my users can reliably choose to create multi-threaded programs or simple
non-/one-thread programs.

Dan Nagle

unread,
Jun 12, 2003, 10:27:37 AM6/12/03
to
Hello,

On Wed, 11 Jun 2003 16:17:11 -0700, "E. Robert Tisdale"
<E.Robert...@jpl.nasa.gov> wrote:

<snip>


>
>The ANSI/ISO Fortran standards
>don't need to say anything about thread safety.
>It would be sufficient to specify automatic storage
>for local variables to allow Fortran programmers
>to write portable thread safe programs.

No, automatic storage would not be sufficient
to allow thread safe procedures to be written,
in either Fortran or C. The program must restrict
itself to that subset of the language which is
thread safe. This restriction is a lot more
than static local variables versus stack local variables.

<snip requoted>

>I just assumed that everybody contributing to this discussion
>was well acquainted with all of the issues concerning
>thread safety and multi-threaded programs
>but that is *not* the issue at hand.

Okay, the issue is thread safety. Multithreaded
execution is not under discussion.

>The issue at hand is whether or not it is *possible*
>to write portable thread safe [sub]programs --
>subprograms that are reentrant and all I need for that
>is reasonable expectation that Fortran compilers
>(at least all of the Fortran compilers that I should care about)
>can emit code to reserve automatic storage for local variables.

You need more than automatic storage for thread safety.

Depending upon your definition of "portable", the answer
is "yes"; compilers *which exist on systems supporting
multithreading* can write thread safe code.

If you require a specific statement in the standard,
you won't find it in either the Fortran 95 standard or
the C99 standard.

>Issues about mutual exclusion for global variables
>and thread safe run time libraries can be dealt with.

I thought the issue was thread safety, not multithreaded
execution. I must have misread.

>But the show stops if Fortran compilers emit code
>that always reserves static storage for local variables.

Thread safety is a separate issue from static storage
of local variables versus stack storage of local variables.
There is some overlap, but these issues are distinct.

>
> > Consult your compiler's documentation for further information.
>
>I know that my Intel Fortran compiler emits code
>which *does* reserve static storage for local variables.

Which I take to mean: You haven't found the switch
which selects stack storage of local variables.
And you haven't found the switch despite your claims
that its important to you.

>If I can't find a way to prevent it from doing this,
>I must advise programmers that they can't use it
>for multi-threaded applications or thread safe libraries.

So we're back to the confusion of thread-safety
versus multithreaded execution.

>The Intel Fortran compiler *is* important to us,
>and I must advise programmers *not* to use it
>if we can't rely upon it to emit thread safe code.

The Intel Fortran compiler is being merged with the VF
compiler, I'm sure that any VF program will run as expected
when compiled by the merged product. Since VF explicitly
does have a switch to place all local variables on the stack,
one may safely assume that the Intel compiler either does,
or at the very least will shortly when the merged product emerges.

But I should let Steve Lionel do his usual, excellent job
of describing the Intel products.

Also, note that thread safety *is not* guaranteed
merely by selecting the "variables default to automatic"
switch in the VF IDE. There're also "allow recursion" switch
and "use multithreaded libraries" switch and maybe something
else I can't bring to mind right now.

Richard Edgar

unread,
Jun 12, 2003, 11:03:19 AM6/12/03
to
In article <FU%Fa.127190$DV.1...@rwcrnsc52.ops.asp.att.net>, "Greg
Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

>Suppose I were to sell a numerical library, I would write it in such a way
>that I could advertise it as "thread-safe." It does not mean that there
>is any thread creation or synchronization code in my library routines, but
>my users can reliably choose to create multi-threaded programs or simple
>non-/one-thread programs.

Point taken. I tend to assume that libraries are thread safe, unless
obviously otherwise (e.g. initialisation routines). odepack really
_should_ have taught me that this is not necessarily the case....

Richard Edgar

unread,
Jun 12, 2003, 11:23:45 AM6/12/03
to
In article <ke1hev06dvifvc8m9...@4ax.com>, Dan Nagle
<dna...@erols.com> wrote:

>Depending upon your definition of "portable", the answer
>is "yes"; compilers *which exist on systems supporting
>multithreading* can write thread safe code.

It would also be helpful to know if the OP is proposing distributing the
source code, or the object file. I can't work it out myself. The fact that
the preferred compilers are (apparently) not known (see a response to one
of my other posts) suggests that it is the source code which is to be
distributed. In that case, I would have thought that thread safety is more
an issue for the users - finding which switches they need (if any) to make
the compiler emit thread safe code. If the users don't know these, then
they have bigger problems than whether or not the Fortran standard allows
(rather than requires) thread safety. In this case, the answer to the OP's
question is that it is certainly possible to write code that can be thread
safe, given compiler support.

I expect that any procedure which is PURE or ELEMENTAL - but not RECURSIVE
- will always be thread safe. Can anyone enlighten me about this?

Greg Chien

unread,
Jun 12, 2003, 11:15:27 AM6/12/03
to
"James Giles" wrote:

> Greg Chien wrote:
> > <Quote>
> > An instance of each object with automatic storage duration is
> > associated with entry into its block. Such an object exists and
> > retains its last-stored value during the execution of the block
> > and while the block is suspended (by a call of a function or
> > receipt of a signal).
> > </Quote>

>
> Well, that *might* be relevant. There is no reason I can think
> of that threads must behave differently than, say, signal handling.
> Multi-threaded programs tend to have at least some shared data
> (otherwise, why not just run independent processes). But, signal
> handlers might also share data with the rest of the program.

The keyword here are *retains* and *suspended*. I would treat the
parenthesized part as examples, which can be eliminated. I can reliably
use the local storage without worrying about the values being changed by
another thread (or some other gremlin) after my routine is suspended and
then resumed.

> Semantically, Fortran's non-SAVEd local variables are pretty
> much the same as C's automatic variables. There is no reason
> that they would behave any differently. But, there is also no
> requirement that implementations work the same.

I suppose the OP is seeking a way to specify truly local variables in
*standard* Fortran which guarantees the behavior of the quoted C-standard.
We understand that standard Fortran has automatic data objects, but my
Fortran 90 Handbook by Adams, et. al. says:
<Quote>
Note that in Fortran 90 the term "automatic object" does not include
noncharacter scalar local variables. [p. 163]
</Quote>
Has the newer standard expanded the coverage?

Greg Chien

unread,
Jun 12, 2003, 11:40:42 AM6/12/03
to
"Richard Edgar" wrote
> ... there would have to be a part of the standard which

> said that in
>
> void func( void )
> {
> int i;
>
> // etc.
> }
>
> the variable i was _never_ statically allocated (since it is not
declared
> static). The OP seems curiously reluctant to point to the specific part
of
> the standard which guarantees this. This makes me wonder if 'normal
> practice' and 'standard compliant practice' are being confused.

I'll do the homework for the OP. In Section 6.1.2.4 Storage durations of
objects in ANSI/ISO 9899-1990:
<Quote>
An object whose identifier is declared with no linkage [GC note: extern]
and without the storage-class specifier static has automatic storage
duration. Storage is guaranteed to be reserved for a new instance of such
an object on each normal entry into the block with which it is
associated...
</Quote>

Dick Hendrickson

unread,
Jun 12, 2003, 11:46:33 AM6/12/03
to

"E. Robert Tisdale" wrote:
>
> Steve Lionel wrote:
>
> > E. Robert Tisdale wrote:
> >

[snip, lots of other also wrote on this topic]


> >
> > True, though there's more to it than that.
> > The Fortran standard doesn't say anything about threads -
>
> Nor does it need to.
>

[snip]

I think we're arguing two different points here. One side,
including the OP, wants to be able to write an interesting set
of subprograms that are thread-safe with minimal compiler and
OS support. The other side seems to be saying that not ALL
possible subprograms can be made thread safe.

Aren't both sides correct? Sure,
subroutine xxx
print *, "we are in xxx"
stop
end
can't be made thread safe. But who cares?

And just as surely, functions that are essentially PURE and/or
RECURSIVE and only access their arguments as inputs, don't do
any I/O, don't use common, etc., are going to be thread safe
on any reasonable implementation, perhaps with a "-use the
stack" command line option. There are lots of useful functions
that meet those simple restrictions. True, you ned to think a
little bit about how they do their data flow, but that's a
general threading problem.

Dick Hendrickson

Richard Maine

unread,
Jun 12, 2003, 11:47:40 AM6/12/03
to
"Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> writes:

> The keyword here are *retains* and *suspended*. I would treat the
> parenthesized part as examples, which can be eliminated. I can reliably
> use the local storage without worrying about the values being changed by
> another thread (or some other gremlin) after my routine is suspended and
> then resumed.

I disagree. Threads are outside the scope of the standard. Therefore,
the standard does not guarantee anything about what happens when you
use them. I don't see how this part of the C standard relates to
thread safety any more than it relates to safety against, say, hardware
memory failures.

I do not believe that you can use the standard to make guarantees
about things outside of its scope. You can use the standard to guess
at likely implementations and thus guess at the likely behavior of
things not covered by the standard. You might even be able to make
pretty good guesses (if you are enough smarter than I am), but that's
not the same thing as a guarantee.

Same comment applies to Fortran; this seems pretty fundamental to me.

Dan Nagle

unread,
Jun 12, 2003, 11:57:24 AM6/12/03
to
Hello,

On Wed, 11 Jun 2003 15:16:17 -0700, "E. Robert Tisdale"
<E.Robert...@jpl.nasa.gov> wrote:

<snip>
>


>Could you please show an example of a subroutine that is thread safe
>with static local variables not protected by mutual exclusion?
>

Sure, easily done.

subroutine vsqrt( a, b)

use thread_constants, only: max_threads

real, intent( in) :: a
real, intent( out) :: b

integer, dimension( max_threads) :: i

do i( thread_id()) = 1, min( size( a), size( b))
a( i( thread_id()) = sqrt( b( i( thread_id()) )
enddo

return
enddo

BTW, note that

#include <math.h>

void vsqrt( double a[], double b[], n)
{
int i;

for( i=0, i<n, i++)
{
a[i] = sqrt( b[i] );
}

return;
}

is *not* guaranteed to be thread safe!

Can anyone spot why?

<snip>

James Giles

unread,
Jun 12, 2003, 12:55:24 PM6/12/03
to
Greg Chien wrote:
...

>> Well, that *might* be relevant. There is no reason I can think
>> of that threads must behave differently than, say, signal handling.
>> Multi-threaded programs tend to have at least some shared data
>> (otherwise, why not just run independent processes). But, signal
>> handlers might also share data with the rest of the program.
>
> The keyword here are *retains* and *suspended*. I would treat the
> parenthesized part as examples, which can be eliminated. I can reliably
> use the local storage without worrying about the values being changed by
> another thread (or some other gremlin) after my routine is suspended and
> then resumed.

The only multi-rhreaded code I've done doesn't necessarily
suspend or resume anything. It operated on a system with
multiple CPUs, and all threads ran concurrently. Why is
the word "suspended" even relevant to the discussion?

What is nore, a C implementation not designed to work
with multiple threads may work just as specified when
operating in a non-threaded environment (including
signal handling, which may or may not even exist
in the environment - but has only superficial similarities
to threading) and yet it may not operate properly at
all with the threading. Threading is beyond the scope
of the C standard. The C standard says nothing about it.
You can't count on anything it says as being even relevant
if you are using threads. As I said above, I can't think
of any reason that an implementation would *not* handle
threads the way you are assuming, but it's not *required*
to do so.

--
J. Giles


Jan C. Vorbrüggen

unread,
Jun 12, 2003, 12:58:45 PM6/12/03
to
> An object whose identifier is declared with no linkage [GC note: extern]
> and without the storage-class specifier static has automatic storage
> duration. Storage is guaranteed to be reserved for a new instance of such
> an object on each normal entry into the block with which it is
> associated...

So what's the definition of a "normal" entry?

Jan

Richard Maine

unread,
Jun 12, 2003, 1:05:06 PM6/12/03
to
Dick Hendrickson <dick.hen...@att.net> writes:

> And just as surely, functions that are essentially PURE and/or
> RECURSIVE and only access their arguments as inputs, don't do
> any I/O, don't use common, etc., are going to be thread safe
> on any reasonable implementation, perhaps with a "-use the
> stack" command line option.

I wouldn't count on it. I would see nothing unreasonable about
the compiler using statically allocated temporary storage in
places where flow analysis showed it was safe (because there
were no procedure calls during the useful life of the temporary
variable). I wouldn't call that an unreasonable implementation,
even with a "-use the stack" option; it takes a "-be thread safe"
option to be sure. There are also plenty of other possibile ways
to go wrong.

There really is a very big and fundamental difference between a single
thread of execution and multiple threads. With the single thread,
you can tie down the particular places where you have to worry about
things changing. With multiple threads, you can't (unless you do
explicit synchronization so that you really only have a single
thread actively running at the time of interest).

Thread safety is *NOT* trivial. Witness the number of bug reports
that are regularly seen about functions that were supposed to be
thread safe, but blew it. That's even from vendors that are
explicitly providing functions designed to be thread safe and
who supposedly know about the tricks and caveats. They even
test the functions, but thread safety is notoriously difficult
to test because of its timing dependency.

I think it frankly foolish to try to deduce that something is
thread safe by guessing about compiler implementations. Too many
people get it wrong when being much more cautious than that.

Sure, you can do things that will improve your odds by avoiding
known exposures. But if you actually want to be thread safe
instead of just have a lower exposure, then you'd better look
for explicit documentation of thread safety.

James Giles

unread,
Jun 12, 2003, 1:17:27 PM6/12/03
to
Dan Nagle wrote:
> On Wed, 11 Jun 2003 15:16:17 -0700, "E. Robert Tisdale"
> <E.Robert...@jpl.nasa.gov> wrote:
>
> <snip>
>>
>> Could you please show an example of a subroutine that is thread safe
>> with static local variables not protected by mutual exclusion?
>>
>
> Sure, easily done.
>
> subroutine vsqrt( a, b)
>
> use thread_constants, only: max_threads
>
> real, intent( in) :: a
> real, intent( out) :: b
>
> integer, dimension( max_threads) :: i
>
> do i( thread_id()) = 1, min( size( a), size( b))
> a( i( thread_id()) = sqrt( b( i( thread_id()) )
> enddo
>
> return
> enddo

Not very portable. It assumes that thread ID's are integers,
that they are numbered contiguously from one to some maximum,
and that there's an inquiry function to retrieve them.

--
J. Giles


James Giles

unread,
Jun 12, 2003, 1:35:35 PM6/12/03
to
Dick Hendrickson wrote:
...

> Aren't both sides correct? Sure,
> subroutine xxx
> print *, "we are in xxx"
> stop
> end
> can't be made thread safe. But who cares?

Well, I disagree with that. My main experience with multi-
threaded code was a run-time I/O support library for Fortran
which would handle just exactly that kind of thing in a thread-
safe way. The purpose was to permit separate threads to
operate on distinct files, but the library had to be able to
handle the case where several threads referenced the same
file (or I/O unit - it didn't have to be a file). If several
threads did the above, the I/O would go one at a time in
a non-deterministic order.

> And just as surely, functions that are essentially PURE and/or
> RECURSIVE and only access their arguments as inputs, don't do
> any I/O, don't use common, etc., are going to be thread safe
> on any reasonable implementation, perhaps with a "-use the
> stack" command line option. There are lots of useful functions
> that meet those simple restrictions. True, you ned to think a
> little bit about how they do their data flow, but that's a
> general threading problem.

That's pretty much as I've been trying to say. In any given
environment, you have to look at the Fortran documentation
to determine what conditions make the code thread-safe. The
same applies to any C implementation. If the documentation
doesn't say, then you can't be certain of thread-safety, for
*either* language, no matter how you write your code. The
subject is outside the scope of either language's standard (except
for the HPF stuff in Fortran), so you can't count on anything
from the standard(s) to bail you out.

--
J. Giles


Greg Chien

unread,
Jun 12, 2003, 1:51:28 PM6/12/03
to
"Richard Maine" wrote

> I disagree. Threads are outside the scope of the standard. Therefore,
> the standard does not guarantee anything about what happens when you
> use them. I don't see how this part of the C standard relates to
> thread safety any more than it relates to safety against, say, hardware
> memory failures.

The quoted C standard describes what a routine shall expect, regarding its
automatic storage, when it is suspended and resumed. The beauty of the
rule is that it does not describe how and why the routine is suspended.
Reentrant execution from another thread happens to be an application.
BTW, I don't think C (or Fortran) can guarantee anything when there is a
hardware memory failure.

Greg Chien

unread,
Jun 12, 2003, 2:07:19 PM6/12/03
to
"Jan C. Vorbrüggen" wrote

c.f. goto a label that is out of scope. I know I am raising a few flags
here :-)

Richard Maine

unread,
Jun 12, 2003, 2:05:36 PM6/12/03
to
"Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> writes:

> "Richard Maine" wrote
> > I disagree. Threads are outside the scope of the standard. Therefore,
> > the standard does not guarantee anything about what happens when you
> > use them. I don't see how this part of the C standard relates to
> > thread safety any more than it relates to safety against, say, hardware
> > memory failures.
>
> The quoted C standard describes what a routine shall expect, regarding its
> automatic storage, when it is suspended and resumed. The beauty of the
> rule is that it does not describe how and why the routine is suspended.
> Reentrant execution from another thread happens to be an application.

I still disagree, but I have no new points to make other than the same
ones I made before. The statement that "execution from another thread
happens to be an application" is yours; I find no support for it in
the standard. As someone else pointed out, the standard pretty explicitly
establishes a single-threaded execution sequence model. I don't think
you can just ignore that and declare that you think it applies unchanged
to an execution model that does not meet that requirement.

Greg Chien

unread,
Jun 12, 2003, 2:30:37 PM6/12/03
to
"Richard Maine" wrote

> As someone else pointed out, the standard pretty explicitly
> establishes a single-threaded execution sequence model. I don't think
> you can just ignore that and declare that you think it applies unchanged
> to an execution model that does not meet that requirement.

But, it does say, in my succinct terms, that when I am suspended, no
matter what reason, don't anyone (even a copy of me) flirt around with my
own local variables.

Greg Chien

unread,
Jun 12, 2003, 2:30:48 PM6/12/03
to
"James Giles" wrote

> The only multi-rhreaded code I've done doesn't necessarily
> suspend or resume anything. It operated on a system with
> multiple CPUs, and all threads ran concurrently. Why is
> the word "suspended" even relevant to the discussion?

<Sarcasm>
You are lucky to have a multiprocessor system that guarantees each running
thread has its own CPU without interruption. Unfortunate to me (and
perhaps many others in c.l.f.), I have only a single CPU running many
processes, each may contain multiple threads.
</Sarcasm>

Craig Powers

unread,
Jun 12, 2003, 3:18:56 PM6/12/03
to
Dan Nagle wrote:
>
> BTW, note that
>
> #include <math.h>
>
> void vsqrt( double a[], double b[], n)
> {
> int i;
>
> for( i=0, i<n, i++)
> {
> a[i] = sqrt( b[i] );
> }
>
> return;
> }
>
> is *not* guaranteed to be thread safe!
>
> Can anyone spot why?

At the very least, I believe sqrt will set errno on failure.

Richard Maine

unread,
Jun 12, 2003, 3:46:55 PM6/12/03
to
"Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> writes:

> "Richard Maine" wrote
> > As someone else pointed out, the standard pretty explicitly
> > establishes a single-threaded execution sequence model. I don't think
> > you can just ignore that and declare that you think it applies unchanged
> > to an execution model that does not meet that requirement.
>
> But, it does say, in my succinct terms, that when I am suspended, no

> matter what reason,...

No, it does not say that. It most distinctly does not say or imply
"no matter what reason" or anything like that, and that is the whole
point. To the contrary, everything it says applies *ONLY* to a
standard-conforming execution environment.

That does *NOT* include multi-threading any more than it includes the
hardware memory failures that I alluded to earlier. You earlier
commented that the standard does not guarantee anything about hardware
memory failures and I agree with you 100%, but it says exactly as much
about thread safety as it does about hardware memory failures. I
think that your "no matter what reason" is purely a fiction that you
have invented, but if you think it is accurate, then how do you
justify that execution of some other thread would count as a reason,
while hardware memory failure would not? Both sound like reasons
to me. Where is the distinction? I don't see it in the standard
and I don't think your postings on clf count as normative additions
to the standard.

You are reading things into the standard that simply are not there.
No amount of careful reading or sophistry is going to find them.

Besides which, execution of one thread does not necessarily
imply suspension of others, but that is a small point compared to
the above really fundamental one.

The Fortran standard also clearly establishes that in

subroutine sub
integer, save :: i = 0, j
i = i + 1
write (*,*) i
j = i
write (*,*) j
end

the values written for i and j will both be the same. In your words,
I might say that the standard says this happens "no matter what". But
I'm afraid that this is not a guarantee against the possibility of
some other thread messing this up; that would be a non-conforming
environment and just isn't covered.

E. Robert Tisdale

unread,
Jun 12, 2003, 3:17:51 PM6/12/03
to
Greg Chien wrote:

> Richard Edgar wrote
>
>> ... there would have to be a part of the standard
>> which said that in
>>
>> void func(void) {
>> int i;
>>
>> // etc.
>> }
>>

>> the variable I was _never_ statically allocated (since it is not


>
> declared
>
>> static). The OP seems curiously reluctant to point to the specific part
>
> of
>
>> the standard which guarantees this. This makes me wonder if 'normal
>> practice' and 'standard compliant practice' are being confused.
>
>
> I'll do the homework for the OP. In Section 6.1.2.4
> Storage durations of objects in ANSI/ISO 9899-1990:
> <Quote>
> An object whose identifier is declared with no linkage [GC note: extern]
> and without the storage-class specifier static
> has automatic storage duration.
> Storage is guaranteed to be reserved
> for a new instance of such an object
> on each normal entry into the block with which it is associated...
> </Quote>

I have taken the liberty of cross posting to the comp.std.c newsgroup
so that experts on the ANSI/ISO C standards can comment.

The question is whether or not it is possible to write
*portable* thread safe [sub]programs in Fortran 77/90/95/00.
Most modern Fortran compilers use or, at least, can use
automatic storage for local variables unless they are SAVE'd
but this is *not* required by any ANSI/ISO Fortran standard.
Fortran compilers are allowed to reserve static storage
for all local variables which would practically preclude thread safety.
Fortran proponents argue that, since the ANSI/ISO C standards
do *not* explicitly specify thread safety, there is no guarantee that
it is possible to write portable thread safe [sub]programs in C either.

James Giles

unread,
Jun 12, 2003, 4:06:33 PM6/12/03
to
Greg Chien wrote:
> "James Giles" wrote
>> The only multi-rhreaded code I've done doesn't necessarily
>> suspend or resume anything. It operated on a system with
>> multiple CPUs, and all threads ran concurrently. Why is
>> the word "suspended" even relevant to the discussion?
>
> <Sarcasm>
> You are lucky to have a multiprocessor system that guarantees each running
> thread has its own CPU without interruption. Unfortunate to me (and
> perhaps many others in c.l.f.), I have only a single CPU running many
> processes, each may contain multiple threads.
> </Sarcasm>

Thanks for the jokes, now address the issue. Namely that
suspension doesn't necessarily happen during multi-threading.
The specific word "suspended" has nothing to do with this issue.
It is a red herring. In fact, I be surprised to hear that the word
had any defined meaning in the C standard. Well, let's see...
um ... nope, not in the C99 document anyway. It's used twice,
both in contexts where its meaning is used as part of an informal
description.

I repeat, I see nothing in the C standard that prohibits an
implementation from working as you seem to expect. I also
see nothing in the C standard that requires it. The requirements
of C's standard are, like Fortran's, on the semantics of the
language as described. The implementation details are
beyond the scope of either standard. An implementation
that is *not* intended to be used in a multi-threaded environment
need not work correctly if you attempt to do so.

--
J. Giles


James Van Buskirk

unread,
Jun 12, 2003, 4:08:31 PM6/12/03
to
"Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> wrote in message
news:jO0Ga.918346$OV.850857@rwcrnsc54...

> Fortran 90 Handbook by Adams, et. al. says:
> <Quote>
> Note that in Fortran 90 the term "automatic object" does not include
> noncharacter scalar local variables. [p. 163]
> </Quote>
> Has the newer standard expanded the coverage?

This is one point in the standard which seems to get inadequate
coverage in Fortran textbooks, even the good ones.
ISO/IEC 1539-1:1997(E):

"12.5.2.4 Insances of a subprogram

"When a function or subprogram defined by a subprogram is invoked,
an instance of that subprogram is created. When a statement function
is invoked, an instance of that statement function is created.

"Each instance has an independent sequence of execution and an
independent set of dummy arguments and local nonsaved data objects.
If an internal procedure or statement function in the subprogram is
invoked directly from an instance of the subprogram or from an
internal subprogram or statement function that has access to the
entities of that instance, the created instance of the internal
subprogram or statement function also has access to the entities of
that instance of the host subprogram.

"All other entities are shared by all instances of the subprogram.

"NOTE 12.28
"The value of a saved data object apperaing in one instance may have
been defined in a previous instance or by initialization in a DATA
statement ot type declaration statement."

Also there is note 12.12:

"This standard does not allow internal procedures to be used as actual
arguments, in part to simplify the problem of ensuring that internal
procedures with recursive hosts accesses entities from the correct
instance of the host. If, as an extension, a processor allows internal
procedures to be used as actual arguments, the corect instance in this
case is the instance in which the procedure is supplied as an actual
argument, even if the corresponding dummy argument is eventually
invoked from a different instance."

CVF if the only compiler I know of which has the above extension and
generates self-modifying code to implement it.

The definition of instances in section 12.5.2.4 heaps some constraints
on a compiler when compiling a subprogram that can have more than one
active instance, whether because it's RECURSIVE or because it's PURE
or ELEMENTAL on a processor that supports actual parallel execution
of FORALLs.

--
write(*,*) transfer((/17.392111325966148d0,3.6351694777236872d228, &
6.0134700169991705d-154/),(/'x'/)); end


James Kuyper

unread,
Jun 12, 2003, 4:28:30 PM6/12/03
to
"E. Robert Tisdale" wrote:
...

> Fortran proponents argue that, since the ANSI/ISO C standards
> do *not* explicitly specify thread safety, there is no guarantee that
> it is possible to write portable thread safe [sub]programs in C either.

They are correct. The C standard says nothing about threads, period, so
everything connected to them is undefined, unspecified, or
implementation-defined behavior. How could you expect otherwise?

That is, however, an unfair comparison. The C standard isn't the only
one that can apply to a C compiler. It may be possible to write portable
thread-safe [sub]programs, as long as you invoke not just the C
standard, but also some other standard that does describe threaded
behavior, such as POSIX. Such code would only be portable to
implmentations conforming to that other standard, but that's a lot
better than not being portable at all.

Greg Chien

unread,
Jun 12, 2003, 4:53:23 PM6/12/03
to
"Richard Maine" wrote

> "Greg Chien" writes:
> > "Richard Maine" wrote
> > > As someone else pointed out, the standard pretty explicitly
> > > establishes a single-threaded execution sequence model. I don't
think
> > > you can just ignore that and declare that you think it applies
unchanged
> > > to an execution model that does not meet that requirement.
> > But, it does say, in my succinct terms, that when I am suspended, no
> > matter what reason,...
>
> No, it does not say that. It most distinctly does not say or imply
> "no matter what reason" or anything like that, and that is the whole
> point. To the contrary, everything it says applies *ONLY* to a
> standard-conforming execution environment.

Hmm, perhaps, I should have said "for any reason I don't care."

BTW, please give a reference to the C standard that its abstract machine
explicitly establish a "single-threaded execution sequence model."

I would refrain myself from further proposing/interpreting/explaining any
standard. Now, back to coding.

Alexander Terekhov

unread,
Jun 12, 2003, 4:53:26 PM6/12/03
to

James Kuyper wrote:
[...]

> That is, however, an unfair comparison. The C standard isn't the only
> one that can apply to a C compiler. It may be possible to write portable
> thread-safe [sub]programs, as long as you invoke not just the C
> standard, but also some other standard that does describe threaded
> behavior, such as POSIX. Such code would only be portable to
> implmentations conforming to that other standard, but that's a lot
> better than not being portable at all.

http://groups.google.com/groups?threadm=3EB82EA0.F40E66C4%40web.de
(Subject: __attribute__((cleanup(function)) versus try/finally)

http://lists.boost.org/MailArchives/boost/msg47747.php
http://groups.google.com/groups?threadm=3ECFA41C.A3B7A957%40web.de
(Subject: Upcoming ISO/IEC <thread>... and <pthread.h> -> ... )

regards,
alexander.

James Giles

unread,
Jun 12, 2003, 5:00:21 PM6/12/03
to
Greg Chien wrote:
...

> BTW, please give a reference to the C standard that its abstract machine
> explicitly establish a "single-threaded execution sequence model."

Well, according to *you*, C procedures are only required to
be thread safe if each thread is suspended for the operations
of the other. That's a single threaded execution sequence model
(usually called time-share, or some similar term). So, if we
accept *your* definitions, the passage you quoted is the reference
you are now asking for.

--
J. Giles


Greg Chien

unread,
Jun 12, 2003, 5:09:43 PM6/12/03
to
"James Van Buskirk" wrote
> ISO/IEC 1539-1:1997(E):
>
> "12.5.2.4 Instances of a subprogram
[snip]

Thanks for the quotes and comments.

Greg Chien

unread,
Jun 12, 2003, 5:18:35 PM6/12/03
to
"James Giles" wrote

> Well, according to *you*, C procedures are only required to
> be thread safe if each thread is suspended for the operations
> of the other.

Did I say that? I am *very* confused.

Richard Maine

unread,
Jun 12, 2003, 5:56:25 PM6/12/03
to
"Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> writes:

> "James Giles" wrote
> > Well, according to *you*, C procedures are only required to
> > be thread safe if each thread is suspended for the operations
> > of the other.
>
> Did I say that? I am *very* confused.

Well, the citation you used for support is about being suspended
and you refer to "suspended" as a key word in

> The keyword here are *retains* and *suspended*.

You then use the word "suspended" throughout many of your posts on the
subject. It sure sounds to me like you are talking about cases where
it is suspended. Seems like a pretty straightforward reading of your
posts to me. Seems a *LOT* more straightforward than your deduction
that the C standard applies to threads when I can't find the word
"thread" anywhere in that standard (anyway, acroread doesn't find it).

Larry Jones

unread,
Jun 12, 2003, 6:21:09 PM6/12/03
to
E. Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:
>
> The question is whether or not it is possible to write
> *portable* thread safe [sub]programs in Fortran 77/90/95/00.

And what does that have to do with the C standard?

> Fortran proponents argue that, since the ANSI/ISO C standards
> do *not* explicitly specify thread safety, there is no guarantee that
> it is possible to write portable thread safe [sub]programs in C either.

It is true that the C standard does not guarantee thread safety, but
that doesn't mean that it's not possible to write portable thread-safe
code in C. It just means that you have to resort to additional
standards, like Posix.

-Larry Jones

Any game without push-ups, hits, burns or noogies is a sissy game. -- Calvin

E. Robert Tisdale

unread,
Jun 12, 2003, 6:46:59 PM6/12/03
to
Larry Jones wrote:

> E. Robert Tisdale wrote:
>
>>The question is whether or not it is possible to write
>>*portable* thread safe [sub]programs in Fortran 77/90/95/00.
>
> And what does that have to do with the C standard?
>
>>Fortran proponents argue that, since the ANSI/ISO C standards
>>do *not* explicitly specify thread safety, there is no guarantee that
>>it is possible to write portable thread safe [sub]programs in C either.
>
> It is true that the C standard does not guarantee thread safety,
> but that doesn't mean that it's not possible
> to write portable thread-safe code in C.
> It just means that
> you have to resort to additional standards, like Posix.

Apparently, the argument is that it is *not* possible
to write portable thread-safe code in Fortran
even if you resort to additional standards, like Posix.
A distinction has been made between *thread safe code*
and code that is actually used in a multithreaded application
which means, I suppose, that the portable thread safe code
need not actually reference any pthread library functions.

Please note that there does not appear to be any consensus
on this yet among subscribers to the comp.lang.fortran newsgroup.

Barry Margolin

unread,
Jun 12, 2003, 7:11:38 PM6/12/03
to
In article <3EE902E3...@jpl.nasa.gov>,

E. Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:
>Apparently, the argument is that it is *not* possible
>to write portable thread-safe code in Fortran
>even if you resort to additional standards, like Posix.
>A distinction has been made between *thread safe code*
>and code that is actually used in a multithreaded application
>which means, I suppose, that the portable thread safe code
>need not actually reference any pthread library functions.

I believe standards like POSIX place additional restrictions on C
implementations that must be used with them, for instance that automatic
variables must be allocated in thread-local storage. I think POSIX also
requires the user to "warn" that the code could be used in multithreaded
applications, by using -DPTHREAD (or something like that) when compiling;
this allows the implementation to link in the right library functions and
use thead-safe macros (if the implementation is inherently safe then it can
simply ignore the warning).

Presumably POSIX bindings for other languages, like Fortran, should have
similar constraints on their implementations.

--
Barry Margolin, barry.m...@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Brooks Moses

unread,
Jun 12, 2003, 7:24:06 PM6/12/03
to
Larry Jones wrote:
> E. Robert Tisdale <E.Robert...@jpl.nasa.gov> wrote:
>>The question is whether or not it is possible to write
>>*portable* thread safe [sub]programs in Fortran 77/90/95/00.
>
> And what does that have to do with the C standard?

Nothing, directly. There has been debate about the answer, however, and
in particular about the part of the answer that claims that using C
instead (which Robert was proposing to do if he couldn't write portable
thread-safe code in Fortran) is a better solution -- and so, whether he
uses C or Fortran, he can't expect to be able to write portable code
that _any_ standard-conforming compiler will compile in a thread-safe
manner. (And so, since he has to deal with that anyhow, he might as
well deal with it and use Fortran as he prefers to.)

>>Fortran proponents argue that, since the ANSI/ISO C standards
>>do *not* explicitly specify thread safety, there is no guarantee that
>>it is possible to write portable thread safe [sub]programs in C either.
>
> It is true that the C standard does not guarantee thread safety, but
> that doesn't mean that it's not possible to write portable thread-safe
> code in C. It just means that you have to resort to additional
> standards, like Posix.

Hmm. I guess, at this point, the debate should probably move into a
question of how well-supported the various applicable additional
standards are. It was, at one point, mentioned that there are
additional standards for Fortran (e.g., HPF) that specifically provide
for thread support.

The question also probably arises as to whether or not various Fortran
compilers support the relevant parts of the Posix standards, granted
that (in this case) the code is expected to be linked to modules written
in C.

- Brooks

Greg Chien

unread,
Jun 12, 2003, 7:58:58 PM6/12/03
to
"Richard Maine" wrote

> "Greg Chien" <gch...@n.o.S.p.a.m.protodesign-inc.com> writes:
> > "James Giles" wrote
> > > Well, according to *you*, C procedures are only required to
> > > be thread safe if each thread is suspended for the operations
> > > of the other.
> >
> > Did I say that? I am *very* confused.
>
> Well, the citation you used for support is about being suspended
> and you refer to "suspended" as a key word in
>
> > The keyword here are *retains* and *suspended*.
>
> You then use the word "suspended" throughout many of your posts on the
> subject.

But, did I say "C procedures are only required to be thread safe if ..."?
Well, this is the last post from me on this subject. Please waste no more
time.

Dan Nagle

unread,
Jun 12, 2003, 8:47:22 PM6/12/03
to
Hello,

On Thu, 12 Jun 2003 15:40:42 GMT, "Greg Chien"
<gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

<snip requoted>


>
>I'll do the homework for the OP. In Section 6.1.2.4 Storage durations of
>objects in ANSI/ISO 9899-1990:
><Quote>
>An object whose identifier is declared with no linkage [GC note: extern]
>and without the storage-class specifier static has automatic storage
>duration. Storage is guaranteed to be reserved for a new instance of such
>an object on each normal entry into the block with which it is
>associated...
></Quote>

Just note (before, baring egregious unchallenged misstatements,
I drop out of this) that the words "each normal entry", as used here,
mean that there is a unique sequence of normal entries, that is,
a single thread of execution.

Thread safety means more than having a fresh copy of local variables.

BTW, has no one figured out why

#include <math.h>

void vsqrt( double a[], double b[], n)
{
int i;

for( i=0, i<n, i++)
{
a[i] = sqrt( b[i] );
}

return
}

is *not* guaranteed by C99 to be thread-safe?

--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.

Gerald F. Thomas

unread,
Jun 12, 2003, 9:09:53 PM6/12/03
to

"Dan Nagle" <dna...@erols.com> wrote in message
news:a47iev829glsuim0r...@4ax.com...
Hello,

#include <math.h>

void vsqrt( double a[], double b[], n)
{
int i;

for( i=0, i<n, i++)
{
a[i] = sqrt( b[i] );
}

return
}

is *not* guaranteed by C99 to be thread-safe?


For starters, I has a syntax error.

Ciao,
Gerry T.

Dan Nagle

unread,
Jun 13, 2003, 8:20:39 AM6/13/03
to
Hello,

On Thu, 12 Jun 2003 14:18:56 -0500, Craig Powers <eni...@hal-pc.org>
wrote:

>Dan Nagle wrote:
>>
<snip quiz question>


>>
>> is *not* guaranteed to be thread safe!
>>
>> Can anyone spot why?
>
>At the very least, I believe sqrt will set errno on failure.

Yes, the macro errno isn't guaranteed to expand
to a thread safe lhs.
There's freedom to make it thread safe, but it need not be.

You must set a "make it thread safe flag" when compiling.

Dan Nagle

unread,
Jun 13, 2003, 8:17:42 AM6/13/03
to
Hello,

On Thu, 12 Jun 2003 21:09:53 -0400, "Gerald F. Thomas"
<gfth...@sympatico.ca> wrote:

>
>"Dan Nagle" <dna...@erols.com> wrote in message
>news:a47iev829glsuim0r...@4ax.com...

<snip>
>
> return

<snip>


>
>
>For starters, I has a syntax error.

Sorry, my "return" finger isn't hard wired to the ; key :-(

>
>Ciao,
>Gerry T.


#include <math.h>

void vsqrt( double a[], double b[], n)
{
int i;

for( i=0, i<n, i++)
{
a[i] = sqrt( b[i] );
}

return;
}

Now, why isn't this guaranteed to be thread safe by C99?

Thread safety is more than "local variables on the stack" ...

Dan Nagle

unread,
Jun 13, 2003, 8:06:13 AM6/13/03
to
Hello,

On Thu, 12 Jun 2003 20:53:23 GMT, "Greg Chien"
<gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

<snip>
>


>BTW, please give a reference to the C standard that its abstract machine
>explicitly establish a "single-threaded execution sequence model."

Section 5.1.2.3, Paragraph 2, contains
"At certain specified points in the execution sequence called sequence
points, all side effects of previous evaluations shall be complete and
no side effects of subsequent evaluations shall have taken place."

Note "the execution sequence" plainly implying there is only one,
note the definition of sequence points, which plainly divide time
into before and after, plainly inconsistent with any conception
of multithreading.

C99 describes a single threaded language.
Note that this is the second time I've posted this quote
in this thread. :-)


>
>I would refrain myself from further proposing/interpreting/explaining any
>standard. Now, back to coding.

--

Dan Nagle

unread,
Jun 13, 2003, 10:17:16 AM6/13/03
to
Hello,

On Thu, 12 Jun 2003 12:17:51 -0700, "E. Robert Tisdale"
<E.Robert...@jpl.nasa.gov> wrote:

<snip requoted>


>
>I have taken the liberty of cross posting to the comp.std.c newsgroup
>so that experts on the ANSI/ISO C standards can comment.

I've read (at least some of) the replies from comp.std.c,
I'd like to thank those posters for their helpful comments.
This thread is now upwards of 80 posts in c.l.f :-)
I'll try to briefly summarize it so readers in c.s.c need
not read through its entirety. I hope I can do so fairly,
I do have several posts in this thread myself.


>
>The question is whether or not it is possible to write
>*portable* thread safe [sub]programs in Fortran 77/90/95/00.

And the answer which has been given (repeatedly, in different forms,
:-) by several c.l.f regulars) is that most Fortran compilers
supporting computers which allow multithreading have some means
of producing thread safe objects.

In many instances, this will require a compiler option to request
that thread safe code be generated. This situation has been
compared as roughly similar to the situation in C, where
a compiler switch *may* be needed for thread safety.

In C and in Fortran, the program must restrict itself
to a subset of the entire language, and typically at least,
must set a compiler option to "guarantee" a thread safe object.
That is, thread safety is more than storage mechanism
of local variables.

>Most modern Fortran compilers use or, at least, can use
>automatic storage for local variables unless they are SAVE'd
>but this is *not* required by any ANSI/ISO Fortran standard.

A confusion which has appeared in this discussion is
that "automatic storage local variables" is equivalent
to "thread safe objects". A compiler *may*, for example,
use static storage for local variables if it reserves enough
static storage for some anticipated maximum number of threads,
or the program allocates storage for a number determined
during execution. This may be done either by the compiler
or explicitly by the programmer. The same general techniques
may be used either in Fortran or in C. And a compiler option
will surely be needed.

>Fortran compilers are allowed to reserve static storage
>for all local variables which would practically preclude thread safety.

This sort of statement appears to me to be confusing storage
mechanism, on the one hand, with (thread v. process) scope
of variable, on the other. In some posts, the OP (E. Robert Tisdale)
has added the qualifier "without using a mutex" which furthers my
suspicion that he is confusing the storage mechanism of a variable
with the scope of a variable. Of course, if one has a process scope
variable where a thread scope variable is needed, use of a mutex
will simply atomically overwrite the variable. This is
a correctness issue, not a performance issue. The OP has implied
this is a performance issue (it would be a performance issue,
if one had a correct program!).

>Fortran proponents argue that, since the ANSI/ISO C standards
>do *not* explicitly specify thread safety, there is no guarantee that
>it is possible to write portable thread safe [sub]programs in C either.

The second paragraph of C99 5.1.2.3 is becoming notorious. :-)
It is taken as implying that C99 defines single threaded execution.
The conclusion is drawn that multithreaded execution is beyond C99.
Which leads us right back to the "thread safe means more than
storage class" perspective.

At this point, the thread appears to iterate. :-)

In short, the OP appears to be interpreting the Fortran standard
pessimistically and the C standard optimistically, with regards
to producing thread safe objects. Standards beyond C99 and Fortran 95
have not been discussed in the c.l.f thread until today.

Some of the regulars in c.l.f are members of J3, the U.S. Fortran
standards committee, which recently wrote the "Interoperability
with C" section of the in-the-works Fortran 2000 standard.
There is, perhaps, more familiarity with C99 than might be expected
from a typical Fortran programmer. I hope I have understood
C99 accurately. "Interoperability with C" is regarded as one of,
if not the, most important feature(s) of Fortran 2000.

{The latest draft of the Fortran 2000 standard is available
from http://www.j3-fortran.org, click on "Fortran 2000"
with Javascript enabled. It's several MB of PDF.)

Greg Chien

unread,
Jun 13, 2003, 11:12:43 AM6/13/03
to
"Dan Nagle" wrote

> #include <math.h>
>
> void vsqrt( double a[], double b[], n)
> {
> int i;
>
> for( i=0, i<n, i++)
> {
> a[i] = sqrt( b[i] );
> }
>
> return
> }

> Sorry, my "return" finger isn't hard wired to the ; key :-(

Well, it's actually more than that
1) the n in the formal parameter list needs a type.
2) the for loop syntax is wrong. for (i = 0; i < n; i++) is probably what
you want. You can actually do for (i=0,i<n,i++;;), but I don't think you
meant to do that.
3) optionally, return; can be eliminated.

> Now, why isn't this guaranteed to be thread safe by C99?

[Disclaimer: I will not get into any standard issue, nor have I ever
claimed that C89/9x guarantees thread-safe code.] Since your code does
not check/rely on errno, you don't need to worry about that the
implementation of sqrt() in the library makes your code not thread-safe.
Had you checked the errno in your code, it would become not thread-safe.
A thread-safe math library may throw an exception when an error is
encountered. The user of your routine will decide.

However, the reliance on array b and the assignment of array a (both are
by reference) may cause the function unsafe. Your user knows they are by
reference, so he or she can carefully implement a thread-safe use of your
code.

The point in this discussion thread, however, is that the integers i and n
are reliably automatic data objects; we don't need to find a compiler
switch to make them automatic (non-SAVEd local, stack allocated,
whatever). [Please correct me if my impression of the latter being
applicable to Fortran is wrong.]

James Giles

unread,
Jun 13, 2003, 11:40:08 AM6/13/03
to
Greg Chien wrote:
...

>> Now, why isn't this guaranteed to be thread safe by C99?
>
> [Disclaimer: I will not get into any standard issue, nor have I ever
> claimed that C89/9x guarantees thread-safe code.] Since your code does
> not check/rely on errno, you don't need to worry about that the
> implementation of sqrt() in the library makes your code not thread-safe.
> Had you checked the errno in your code, it would become not thread-safe.
> A thread-safe math library may throw an exception when an error is
> encountered. The user of your routine will decide.

This is not true. For a procedure to be thread-safe, it isn't
sufficient that it not suffer side-effects or confusion due
to the execution of other threads, it must also no *cause*
such problems for other threads. Here, the fact that C
intrinsic functions may *set* errno (even if you never
look at it), and errno may be a program wide global,
means that some other thread which was just about to
test errno before this thread called sqrt() would see
the value caused by this thread.

--
J. Giles


Greg Chien

unread,
Jun 13, 2003, 11:59:52 AM6/13/03
to
"James Giles" wrote

You are right (except for the first statement :-). Hence my statements
used negative "not thread-safe", rather than claiming the routine *is*
thread-safe. If needed, your user will link his/her code and your routine
with a thread-safe math library. I had to be careful in posting ;-)

Francis Glassborow

unread,
Jun 13, 2003, 1:41:24 PM6/13/03
to
In message <74ijevo11fao36lis...@4ax.com>, Dan Nagle
<dna...@erols.com> writes

>Some of the regulars in c.l.f are members of J3, the U.S. Fortran
>standards committee, which recently wrote the "Interoperability
>with C" section of the in-the-works Fortran 2000 standard.
>There is, perhaps, more familiarity with C99 than might be expected
>from a typical Fortran programmer. I hope I have understood
>C99 accurately. "Interoperability with C" is regarded as one of,
>if not the, most important feature(s) of Fortran 2000.

Then it is long past time that we improved our liaison with Fortran.


--
ACCU Spring Conference 2003 April 2-5
The Conference you should not have missed
ACCU Spring Conference 2004 Late April
Francis Glassborow ACCU

Alexander Terekhov

unread,
Jun 13, 2003, 2:54:12 PM6/13/03
to

Dan Nagle wrote:
[...]

> to producing thread safe objects. Standards beyond C99 and Fortran 95
> have not been discussed in the c.l.f thread until today.

Save your time. It's impossible to have portable "thread safe objects"
because POSIX's "memory model" sucks -- it doesn't define what "memory
location" is. OG/AG folks are just waiting until the Std. C/C++ will
finally adopt threads, I guess.

regards,
alexander.

Dan Nagle

unread,
Jun 13, 2003, 8:24:12 PM6/13/03
to
Hello,

Please accept my invitation to attend J3 meetings.
See http://www.j3-fortran.org for time & place
(next: Las Vegas, mid-August) details.

--
Cheers!

Dan Nagle
Purple Sage Computing Solutions, Inc.

Dan Nagle

unread,
Jun 13, 2003, 8:28:17 PM6/13/03
to
Hello,

On Fri, 13 Jun 2003 15:12:43 GMT, "Greg Chien"
<gch...@n.o.S.p.a.m.protodesign-inc.com> wrote:

<snip my C bugs>


>
>The point in this discussion thread, however, is that the integers i and n
>are reliably automatic data objects; we don't need to find a compiler
>switch to make them automatic (non-SAVEd local, stack allocated,
>whatever). [Please correct me if my impression of the latter being
>applicable to Fortran is wrong.]

The point is that the "hidden" reference to errno
is not necessarily thread safe. A compiler switch is
needed to guarantee that the errno macro is expanded
in a thread safe way. As was pointed out, this switch,
if it exists for a given compiler, is beyond C99.

Francis Glassborow

unread,
Jun 14, 2003, 7:13:15 AM6/14/03
to
In message <ehqkevo6qdc8l5bbl...@4ax.com>, Dan Nagle
<dna...@erols.com> writes

>Hello,
>
>Please accept my invitation to attend J3 meetings.
>See http://www.j3-fortran.org for time & place
>(next: Las Vegas, mid-August) details.

Thanks, but as a self-financed individual attending both WG14 and WG21
meetings is already stretching my finances.

James Kuyper

unread,
Jun 12, 2003, 6:12:47 PM6/12/03
to

Yes? Cross-references like those are a lot more useful if you indicate
how you think they connect to the current discussion.

There was a lot of stuff in there about the C++ standard, and how it's
exception-throwing model works (or fails to) with POSIX. This is
comp.std.c (and comp.std.fortran), and the question was about the C
standard.

One comment caught my attention, though it's not relevant to this
discussion:

"C and C++ WILL merge, sooner or later. The separation of C and C++
languages is/was the stupidest thing C++ authors ever did (or allowed to
happen)."

C is a different language than C++ because some people wanted to
continue using a C which was NOT C++. There's no point in debating
whether they were correct; the relevant fact is that they existed, and
still exist, and comp.std.c is filled with such people. I would point
out that this doesn't mean that they are all haters of C++, many of them
merely feel that C is a better language to use in certain context, not
that C is superior to C++ in all contexts.

Keeping the two languages seperate was not a decision the C++ authors
made, and it's not one that they had any power to prevent from being
made. You could hold them to blame, I suppose, for failing to convice
all of the C holdouts, but that hardly seems fair. That's not quite
true: if they had defined C++ as a language that was nearly identical to
C90, with a few minor changes, then those changes could have been
incorporated into C99. But somehow I doubt that this is what you were
referring to; that wouldn't really have been C++ in any meaningful
sense.

James Kuyper

unread,
Jun 14, 2003, 4:53:31 PM6/14/03
to
Dan Nagle <dna...@erols.com> wrote in message news:<74ijevo11fao36lis...@4ax.com>...

> Hello,
>
> On Thu, 12 Jun 2003 12:17:51 -0700, "E. Robert Tisdale"
> <E.Robert...@jpl.nasa.gov> wrote:
...

> >Fortran proponents argue that, since the ANSI/ISO C standards
> >do *not* explicitly specify thread safety, there is no guarantee that
> >it is possible to write portable thread safe [sub]programs in C either.
>
> The second paragraph of C99 5.1.2.3 is becoming notorious. :-)
> It is taken as implying that C99 defines single threaded execution.
> The conclusion is drawn that multithreaded execution is beyond C99.
> Which leads us right back to the "thread safe means more than
> storage class" perspective.

It describes an execution environment in which the possibility of
multiple threads has not even been considered, which means that in
some ways it implicitly assumes single-threaded behavior. Therefore, a
conforming implementation of C on a platform which supports multiple
threads, can compile a strictly conforming program to make use of
multiple threads, only by invoking the "as-if" rule. That means,
basically, that the observable results of the multi-threaded behavior
must be essentially the same as if 5.1.2.3 had been followed literally
for some permitted order of evaluation of the statements and
expressions that make up the program. This provides only a very
limited amount of freedom for multi-threaded implementation of the
program. It's not enough to be really useful, in itself.

However, any program that makes real use of threads will have behavior
that is undefined behavior under the C standard. That's because the
thread primitives are necessarily written in non-strictly conforming
C, because strictly-conforming C doesn't have the features neede to
implement those primitives. Therefore, any program that uses them has
behavior that is at best, implementation-defined, as far as the C
standard is concerned. In most cases, it has undefined behavior. That
gives the implementation all the freedom it needs to make those
threading primitives do whatever it needs them to do. If they conform
to some other standard, such as POSIX, then the behavior becomes
defined; but not by the C standard.

0 new messages