2

I am newbie to both Fortran and C++, working on a task to couple two programs written in Fortran and C++.

I am trying to create a pthread(detached) wrapper and call it from my Fortran subroutine and pass a cpp function to it. I wrote some code by following this link Calling a subroutine in FORTRAN without blocking the main program.

I get run time error like below, when i execute it.

Program received signal SIGSEGV: Segmentation fault - invalid memory reference.

Backtrace for this error:

I compiled using the following commands

gfortran-mp-4.7 -c pthread_mod.f90 
g++-mp-4.7 -c -std=c++11 pcmodel.cpp 
gfortran-mp-4.7 -c  mainFort.F
gfortran-mp-4.7 pthreads_module.o pcmodel.o mainFort.o -o test -lstdc++

Here is the minimal code where i can reproduce the error.

Pthreads_interface.h

extern "C" void pthread_create_opaque(pthread_t *threadptr, void *(**procptr)(void *), int *comerr){
  //   creates a new thread using an opaque pointer to the pthread_t structure
   pthread_attr_t  attr;
   pthread_attr_init(&attr);
   pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
   *comerr = pthread_create(threadptr, &attr, (*procptr), NULL);
}

pthreads_module.f90

module pthreads_module
implicit none
 interface

   subroutine pthread_create_opaque (threadptr, procptr, comerr) bind(C,name="pthread_create_opaque")
        USE ISO_C_BINDING
        type(c_ptr) :: threadptr
        type(c_funptr),value :: procptr
        integer(c_int),intent(out) :: comerr
   end subroutine

   subroutine PCModel () bind (c,name="PCModel_")
         USE ISO_C_BINDING
   end subroutine PCModel

  end interface
 end module pthreads_module

mainFort.F

program test
 call BCL00
end program test

  SUBROUTINE BCL00
  use pthreads_module
  USE ISO_C_BINDING
  implicit none
  type(c_ptr) :: threadptr
  integer :: comerr
  call pthread_create_opaque(threadptr,
 &          c_funloc(PCModel),comerr)

  END

where PCModelis the C++ function to be executed by pthread.

pcmodel.cpp

 #include <iostream>
 #include "pthreads_interface.h"
 using namespace std;

 void PCModel(){
      cout<<"PCModel is called"<<endl;
 }

 extern "C" void PCModel_(){
  PCModel();
 }

Ideally both my Fortran and C++ code should run in parallel, once the fortran code triggers the thread to start the C++ function(PCModel)

It would be great, if some one could check the code and help me out.

Community
  • 1
  • 1
raghu
  • 83
  • 2
  • 12
  • yeah it is not declared, but i did it in mine. – raghu Apr 17 '17 at 15:53
  • Sounds good, will do it. – raghu Apr 17 '17 at 19:22
  • @Vladimir F tried it. it says `call pthread_create_opaque(c_loc(threadptr), 1 Error: Type mismatch in argument 'threadptr' at (1); passed REAL(4) to TYPE(c_ptr)` – raghu Apr 18 '17 at 13:34
  • @Vladimir F when i try declare `threadptr` as `type(c_ptr) :: threadptr` in `subroutine bcl00` it says `Error: Derived type 'c_ptr' at (1) is being used before it is defined`. – raghu Apr 18 '17 at 13:36
  • @Vladimir F added the code where is the error is reproduced. – raghu Apr 18 '17 at 14:03
  • After implementing them now i get `mainFort.F:18.32: & c_funloc(PCModel),comerr) 1 Error: Symbol 'pcmodel' at (1) has no IMPLICIT type` – raghu Apr 18 '17 at 15:07
  • So I tried to add `type(c_funptr) :: PCModel`, the it compiled but throws a runtime error saying `Program received signal SIGSEGV: Segmentation fault - invalid memory reference` – raghu Apr 18 '17 at 15:09
  • The problem with `pcmodel` is an important one. If you can rephrase the question to focus on that then we can certainly answer. – francescalus Apr 18 '17 at 17:03
  • Now I updated the current code. @francescalus Yes you are right, there seems a problem with pcmodel, where my fortran program is unable to pass it on to the thread properly. – raghu Apr 19 '17 at 03:57
  • You have to different PCmodels there, one in Fortran and one in C++. I am not sure what exactly `extern "C" void PCModel_(){ PCModel(); }` does in C++, but I am worried something fishy happens there. – Vladimir F Героям слава Apr 19 '17 at 06:30
  • Its working now, I am passing the `procptr` wrongly. – raghu Apr 19 '17 at 07:52
  • Can you post the solution as an answer? – Vladimir F Героям слава Apr 19 '17 at 08:13

1 Answers1

0

In Pthreads_interface.h I changed the way procptr is passed from (*procptr) to procptr

extern "C" void pthread_create_opaque(pthread_t *threadptr, void *(*procptr)(void *), int *comerr){
 //   creates a new thread using an opaque pointer to the pthread_t structure
 pthread_attr_t  attr;
 pthread_attr_init(&attr);
 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
 *comerr = pthread_create(threadptr, &attr, procptr, NULL);
}

Now it runs without Segmentation fault and main program continues without waiting for the thread.

raghu
  • 83
  • 2
  • 12