Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

ExitThread link failure

sfaludi
Beginner
1,497 Views
I am trying to call ExitThread from a Compaq Visual Fortran 6.6 DLL. The linker complains about "unresolved external symbol _EXITTHREAD@4".

What is the solution? [Many thanks for any help.]
0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,497 Views
You need to add USE KERNEL32 to define the routine.

Steve
0 Kudos
sfaludi
Beginner
1,497 Views
Hello Steve,

Followup question: According to the docs "A thread that uses functions from the C run-time libraries should use the _beginthread and _endthread C run-time functions..." My Fortran DLL is called from a thread created via CreateThread. Should it be using ExitThread or _endthread to stop?

Thank you for your incredibly quick responses!

Regards,

-Steven Faludi
0 Kudos
Jugoslav_Dujic
Valued Contributor II
1,497 Views
I'd advise you to do neither -- plain old RETURN is the best way to end the thread. _beginthread[ex]/_endthread have everything to do with initialization of C runtime library (RTL) to be able to operate with multiple thread calls (if you have VC++ you can even take a look of sources of _beginthread and _threadstart in C:...VC98CRTSRCTHREAD.C). I may be wrong, but I don't think Fortran RTL has anything to do with C RTL in this regard, and that a call to _beginthread from Fortran code is at best useless, and at worst will crash.

The problem with ExitThread is that it doesn't reset Fortran RTL properly. For example, the following code causes a memory leak:
INTEGER FUNCTION MyThreadFunc(lParam)
!DEC$ATTRIBUTES STDCALL:: MyThreadFunc
USE KERNEL32
INTEGER, ALLOCATABLE:: n(:)
ALLOCATE(n(1000))
CALL ExitThread(0)
RETURN
END
In normal conditions, n will be automatically deallocated on return. However, RETURN and associated cleanup of n is never executed in this context and the memory remains allocated. There are possibly other bad interactions with Fortran RTL; I think that avoing ExitThread altogether is the best way. Even if you have to return from a depth of the calling stack, it's best to develop an error-handling mechanism which will assure that the thread is exited via a RETURN in thread's entry-point routine.

Jugoslav
0 Kudos
gfthomas8
Novice
1,497 Views
Steven:

This contentious issue was discussed in comp.lang.fortran in a thread titled 'Multithread in Compaq Fortran for windows2K' around the end of June, 2002. I advise you to read through the apropos postings.

HTH,
Gerry T.
0 Kudos
pcurtis
Beginner
1,497 Views
Here are the F90 interfaces to the correct runtime thread management routines:

! Interfaces to Microsoft Visual C library thread routines
! Must link against multithreaded libraries
interface
function $beginthreadex (security, stack_size, start_address, arglist, &
initflag, thrdaddr)
use dfwinty
integer(UINT) :: $beginthreadex
!DEC$ ATTRIBUTES C, alias:"__beginthreadex" :: $beginthreadex
type(T_SECURITY_DESCRIPTOR), intent(IN) :: security
!DEC$ ATTRIBUTES REFERENCE, ALLOW_NULL :: security
integer(UINT), intent(IN) :: stack_size
integer(PVOID), intent(IN) :: start_address ! Must be STDCALL calling
! mechanism, 1 arg
integer(PVOID), intent(IN) :: arglist
integer(UINT), intent(IN) :: initflag
integer(UINT), intent(OUT):: thrdaddr
!DEC$ ATTRIBUTES REFERENCE,IGNORE_LOC :: thrdaddr
end function $beginthreadex
end interface

interface
subroutine $endthreadex (retval)
use dfwinty
!DEC$ ATTRIBUTES C, alias:"__endthreadex" :: $endthreadex
integer(UINT), intent(IN) :: retval
end subroutine $endthreadex
end interface


The regular Win32 CreateThread routine has a memory leak which renders it useless. This is well-known to Microsoft and has been documented on the MSDN website for years. The most thorough analysis of this issue (and all other aspects of multithreaded programming) can be found in Jeffrey Richter's "Advanced Windows" book (highly recommended!).
0 Kudos
gfthomas8
Novice
1,497 Views
Further to Paul's post:

1. Give your CVF DLL a DllMain.c, ie, in C not Fortran.
2. The O'Reilly book 'Win32 Multithreaded Programming' by Cohen (an Intel guy) and Woodring is worth looking at for more on this issue.
3. Use Intel's VTune to snoop at the behavior of your CVF DLL with CreateThread or BeginThreadEx.

Ciao,
Gerry T.
0 Kudos
Reply