Tricky interface specification for C pthread_create function

Tricky interface specification for C pthread_create function

David Hittner's picture

I'm trying to create a pthread interface in Fortran 90/95 for the C pthread_create( ) function (see below). I can't use Fortran 2003 or OpenMP for portability reasons.

Passing the first two parameters is by reference, which isn't hard. What's tricky is the third parameter, the address of the (sub)routine that you want to run in a thread, and the fourth parameter which is the address of the [arbitrary] data that you want to pass to the (sub)routine as the first (sub)routine parameter. Can anyone help with the tricky interface specification? Or can someone make available the source code for the IBM f_pthread module, which has already solved this problem?

int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);

interface

  integer function pthread_create (thread, attr, start_routine, arg)

  byte, dimension(8), intent(out) :: thread

  byte, dimension(176), intent(in) :: attr

  !dec$ attributes c :: pthread_create

  !dec$ attributes reference :: thread, attr

  !??? how do you declare the 3rd and 4th dummy arguments, and how are they passed?

end interface

 

5 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.
Steve Lionel (Intel)'s picture

You don't want to use Fortran 2003 or OpenMP, despite their wide implementation (at least the parts you're using), but you want to use compiler-specific extensions for changing argument passing, and the nonstandard BYTE type? Oh, and you're using POSIX threads which are really not native to Windows. I don't understand...

The routine argument you could just declare as EXTERNAL, or have a nested interface for it. The last argument can be declared as whatever you want it to be - say, integer. The address of whatever you pass as an argument gets passed on to the thread routine.

Steve
David Hittner's picture

The reason for Fortran 90/95 and no OpenMP requirement is that the code must be portable to three platforms: OpenVMS, Linux, and Windows. Intel is our provider of Fortran for Linux and Windows which allows us to use the compiler-specific extensions, but we have to live with the limitations of HP Fortran on OpenVMS, which is only F90/95 compliant (with no indications of upgrading) and there is no OpenMP port for OpenVMS. So I'm forced to use F90/95 and pthreads as the common implementation basis.

For the third parameter, could you point me to an example of nested interface that you mentioned? As I understand it, using EXTERNAL in the main would only allow the subroutine to call the passed subroutine name, but wouldn't allow it to pass it on to another subroutine - or can I type the dummy parameter as EXTERNAL also?

And for the fourth parameter, since the compiler does type checking against the interface, I was trying to duplicate the (void*)[=generic] datatype, so that I could pass any data type to the function from the fortran main. I'm not aware of a 'generic' data type in Fortran, nor of a way to typecast, as in C. Or do I need to implement this as a generic interface, with overloaded implementations differing in the 4th parameter data types (integer, character, array, etc.)?

Steve Lionel (Intel)'s picture

You would use EXTERNAL in the interface for the dummy argument.

If you are limiting your platforms to VMS and the Intel compilers, add:

!DEC$ ATTRIBUTES NO_ARG_CHECK :: arg

and the compiler will skip checking that argument.

Steve
Repeat Offender's picture

That start_routine is a function, not a subroutine, you know. You could type arg as INTEGER(INT_PTR_KIND()) by value, then set it equal to a cray pointer to a structure that has the stuff you want in it. This would be a little closer to the f2003 way in case you ever wanted to port to f2003.

Login to leave a comment.