Re: [boost] boost.filesystem on HPUX

Hi Toon, Caleb Epstein, Beman, Thomas Matelich,
Does anybody now any other flag that might influence this? Is it normal (never used readdir_r myself) that it is only defined in multi-threading-mode? From manpage of readdir_r:
"Users of readdir_r() should note that readdir_r() now conforms with the POSIX.1c Threads standard. The old prototype of readdir_r() is supported for compatibility with existing DCE applications only." _r denotes reentrant functions and -mt enables the following (for default -AA mode for aCC/Itanium): * -D_REENTRANT * -D_RW_MULTI_THREAD * -D_RWSTD_MULTI_THREAD * -D_POSIX_C_SOURCE=199506L * -D_HPUX_SOURCE * * -lpthread
Should we instruct bbv1 to compile the boost.filesystem always with the -mt flag on hpux ? Yes.
Yes that seems eminently reasonable (that readdir_r only be prototyped/available if -mt is supplied). Yes, since readdir_r is specifically for multithreaded code.
Well, there is code in libs/filesystem/src/operations_posix_windows.cpp that attempts to detect if it is being compiled with multi-threading enabled:
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) Presumably aCC sets these macros incorrectly, or this code is not correct. Maybe the check should be for >0?
They are defined in <sys/unistd.h> (but the check will fail if the header file is not included).
Perhaps you can check what _POSIX_THREAD_SAFE_FUNCTIONS is defined to on aCC both with and without -mt? On Linux 2.4.21 + gcc 3.3.4, I get 200112 both with -pthread and without.
#include <pthread.h> #include <iostream> int main () { std::cout << _POSIX_THREAD_SAFE_FUNCTIONS << std::endl; }
It will fail in aCC if <unistd.h> is not included since -mt doesn't set these macros.
HP isn't like MS where you need uniform mt or not across all translation units if you want happiness, but I wouldn't think you'd want to enable mt settings behind the users' back.
I'm afraid its not, -mt needs to be defined consistently, otherwise there can be unexpected runtime problems.
Since somebody suggested that _REENTRANT is defined on HP when the '-mt' flag is used, what about only adding adding following to this #if
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) || (defined(__HP_aCC) && defined(_REENTRANT)) I don't use boost build, but I thought the existing ifdef block seemed like it should work. I don't know much about HPUX on Itanium, but I went grepping on my HP 11i box, and found the _POSIX_THREAD_SAFE_FUNCTIONS define in /usr/include/sys/unistd.h. Right,
Then I remembered that to use the new posix friendly APIs on 11i, you need a -D_POSIX_C_SOURCE=199506L. I'd bet that if you added that to your build, things would work a lot more nicely. I think that define is only contra-indicated if you're still trying to use CMA threads (which is not a good idea). Yes, but setting -mt will take care of it. But I don't think its needed for the check we are doing here.
If you do end up needing a modification of the define block above, I'd recommend __hpux rather than __HP_aCC since this is a platform issue rather than a compiler issue. But, the problem is not with using g++ on HP-UX.
|| (defined(__HP_aCC) && defined(_REENTRANT))
I presume no change is needed if it is ensured (with a #ifdef guard?) that <unistd.h> is included before the check.
-Ganesh

S G Ganesh wrote:
Yes that seems eminently reasonable (that readdir_r only be prototyped/available if -mt is supplied).
Yes, since readdir_r is specifically for multithreaded code.
but it is guarded with the code below
Well, there is code in libs/filesystem/src/operations_posix_windows.cpp that
attempts to
detect if it is being compiled with multi-threading enabled:
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) Presumably aCC sets these macros incorrectly, or this code is not correct. Maybe the check should be for >0?
They are defined in <sys/unistd.h> (but the check will fail if the header file is not included).
The problem seems to be that the header unistd.h is included. Apparantly unistd.h always defines the above tokens, even if the '-mt' flag is not passed on to the compiler. I tested this in a small test-program: <tt.cpp> #include <unistd.h> #include <iostream int main() { std::cout << _POSIX_THREAD_SAFE_FUNCTIONS << std::endl ; std::cout << _SC_THREAD_SAFE_FUNCTIONS << std::endl ; std::cout << _POSIX_THREAD_SAFE_FUNCTIONS << std::endl ; return 0 ; } </tt.cpp> And 'aCC -AA tt.cpp ; ./a.out' gives : <cout> 1 441 1 </cout> Next 'aCC -AA -mt tt.cpp ; ./a.out' gives exactly the same output. So it's clear that the current testing of _POSIX_THREAD_SAFE_FUNCTIONS, _SC_THREAD_SAFE_FUNCTIONS and _POSIX_THREAD_SAFE_FUNCTIONS does not suffice. Thus I still think it's best to expand the #if test to: # if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ && ( !defined(__HP_aCC) \ || ( (defined(__HP_aCC) && defined(_REENTRANT) ) to make sure that, in case we're compiling with HP-aCC, we also check that the token _REENTRANT is defined.

Toon Knapen wrote:
The problem seems to be that the header unistd.h is included. Apparantly unistd.h always defines the above tokens, even if the '-mt' flag is not passed on to the compiler.
What does sysconf(_SC_THREAD_SAFE_FUNCTIONS) return? Markus

Markus Schöpflin wrote:
Toon Knapen wrote:
The problem seems to be that the header unistd.h is included. Apparantly unistd.h always defines the above tokens, even if the '-mt' flag is not passed on to the compiler.
What does sysconf(_SC_THREAD_SAFE_FUNCTIONS) return?
It returns '1' wethere '-mt' is used or not. But this is a runtime-if. We need a compile-time if to avoid calling readdir_r when '-mt' is not used on the command-line.

Toon Knapen wrote:
Markus Schöpflin wrote:
What does sysconf(_SC_THREAD_SAFE_FUNCTIONS) return?
It returns '1' wethere '-mt' is used or not.
But this is a runtime-if. We need a compile-time if to avoid calling readdir_r when '-mt' is not used on the command-line.
In your specific case, yes. But generally, you can't rely on that. The standard says: <quote> If a symbolic constant is defined with the value -1, the option is not supported. Headers, data types, and function interfaces required only for the option need not be supplied. An application that attempts to use anything associated only with the option is considered to be requiring an extension. If a symbolic constant is defined with a value greater than zero, the option shall always be supported when the application is executed. All headers, data types, and functions shall be present and shall operate as specified. If a symbolic constant is defined with the value zero, all headers, data types, and functions shall be present. The application can check at runtime to see whether the option is supported by calling fpathconf(), pathconf(), or sysconf() with the indicated name parameter. </quote> So in general you have to check with sysconf(_SC_THREAD_SAFE_FUNCTIONS) during runtime whenever _POSIX_THREAD_SAFE_FUNCTIONS == 0. But unfortunately this won't help you much. :-( Markus

Toon Knapen wrote:
But this is a runtime-if. We need a compile-time if to avoid calling readdir_r when '-mt' is not used on the command-line.
Oh, and one more thing I forgot. This was pointed out in another reply already but I don't know if you tried it. Try defining _POSIX_C_SOURCE or _XOPEN_SOURCE to the maximum value supported on your system _before_ you include any header. There should be a standards man page for you to check this. HTH, Markus

"Toon Knapen" <toon.knapen@fft.be> wrote in message news:42B80444.3050609@fft.be...
... So it's clear that the current testing of _POSIX_THREAD_SAFE_FUNCTIONS, _SC_THREAD_SAFE_FUNCTIONS and _POSIX_THREAD_SAFE_FUNCTIONS does not suffice. Thus I still think it's best to expand the #if test to:
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ && ( !defined(__HP_aCC) \ || ( (defined(__HP_aCC) && defined(_REENTRANT) )
to make sure that, in case we're compiling with HP-aCC, we also check that the token _REENTRANT is defined.
Toon, go ahead and commit the above if it tests OK. But do test it first; I think it needs two additional closing )'s. --Beman

Beman Dawes wrote:
... So it's clear that the current testing of _POSIX_THREAD_SAFE_FUNCTIONS, _SC_THREAD_SAFE_FUNCTIONS and _POSIX_THREAD_SAFE_FUNCTIONS does not suffice. Thus I still think it's best to expand the #if test to:
# if defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ && ( !defined(__HP_aCC) \ || ( (defined(__HP_aCC) && defined(_REENTRANT) )
to make sure that, in case we're compiling with HP-aCC, we also check that the token _REENTRANT is defined.
Toon, go ahead and commit the above if it tests OK.
Done, tested if it compiles fine on gcc and aCC.
But do test it first; I think it needs two additional closing )'s.
Partially right, I indeed forgot 1 closing ')'
participants (4)
-
Beman Dawes
-
Markus Schöpflin
-
S G Ganesh
-
Toon Knapen