I have created multiple threads in my application. I want to assign a name to each pthread so I used pthread_setname_np which worked on Ubuntu but is not working on SUSE Linux.
I googled it and came to know '_np' means 'non portable' and this api is not available on all OS flavors of Linux.
So now I want to do it only if the API is available. How to determine whether the api is available or not ? I need something like this.
#ifdef SOME_MACRO
pthread_setname_np(tid, "someName");
#endif
You can use the feature_test_macro _GNU_SOURCE to check if this function might be available:
#ifdef _GNU_SOURCE
pthread_setname_np(tid, "someName");
#endif
But the manual states that the pthread_setname_np and pthread_getname_np are introduced in glibc 2.12. So if you are using an older glibc (say 2.5) then defining _GNU_SOURCE will not help.
So it's best to avoid these non portable function and you can easily name the threads yourself as part of your thread creation, for example, using a map between thread ID and a array such as:
pthread_t tid[128];
char thr_names[128][256]; //each name corresponds to on thread in 'tid'
You can check the glibc version using:
getconf GNU_LIBC_VERSION
Since this function was introduced in glibc 2.12, you could use:
#if ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 12)))
pthread_setname_np(tid, "someName");
#endif
This kind of thing - finding out if a particular function exists in your compilation environment - is what people use GNU Autoconf scripts for.
If your project is already using autoconf, you can add this to your configure source, after the point where you have checked for the pthreads compiler and linker flags:
AC_CHECK_FUNCS(pthread_setname_np)
...and it will define a macro HAVE_PTHREAD_SETNAME_NP if the function exists.
Related
https://linux.die.net/man/3/crypto_num_locks says that CRYPTO_num_locks() returns required number of locks. Previously I used CRYPTO_NUM_LOCKS which was a macro with value 41 to construct a mutex array till openssl 1.0.2s. Now (OPENSSL 1.1.1d) they have introduced
# define CRYPTO_num_locks() (1).
Hence from my understanding, the macro will have value 1, hence i surely can't use this macro for declaring a runtime array.
I can go with changing the value of macro inside crypto.h, but just wanted to know the reason why did OPENSSL changed the value they were returning for the number of locks. I went through their gitlink https://github.com/openssl/openssl and changes https://www.openssl.org/news/changelog.html#x13.
These things made me a bit clear about the use of function instead of macro, but can't understand two questions:
Why the value of CRYPTO_num_locks() set to only (1). And will it be safe for me to change it to say 41, or something else
If this was supposed to be macro only, what's the point in removing earlier macro(CRYPTO_NUM_LOCKS).
It is useful to look at the 1.1.1d definition of CRYPTO_num_locks in include/openssl/crypto.h and its vicinity:
* On the other hand, the locking callbacks are no longer used. Consequently,
* the callback management functions can be safely replaced with no-op macros.
*/
# define CRYPTO_num_locks() (1)
# define CRYPTO_set_locking_callback(func)
# define CRYPTO_get_locking_callback() (NULL)
# define CRYPTO_set_add_lock_callback(func)
# define CRYPTO_get_add_lock_callback() (NULL)
So whatever your code does with that macro and the ones related to it, it is no longer relevant.
Looking even further up in that file, it turns out that this is all conditionally defined under the value of a macro called OPENSSL_API_COMPAT:
# if OPENSSL_API_COMPAT < 0x10100000L
This macro is intended to indicate whether application code is allowed to use older OpenSSL constructs. In stead of changing any OpenSSL header files, it would be better to actually set this macro to 0x1010000L (or even higher) when compiling the application and then work through any constructs that are no longer available. That would ensure that the code no longer uses any deprecated 1.0.2 stuff.
For a very brief confirmation of what happened to the OpenSSL thread-safety model between 1.0.2 and 1.1.0, see the answer to the OpenSSL FAQ question Is OpenSSL thread-safe?:
Yes but with some limitations; for example, an SSL connection cannot
be used concurrently by multiple threads. This is true for most
OpenSSL objects.
For version 1.1.0 and later, there is nothing further
you need do.
For earlier versions than 1.1.0, it is necessary for your
application to set up the thread callback functions. To do this, your
application must call CRYPTO_set_locking_callback(3) and one of the
CRYPTO_THREADID_set... API's. See the OpenSSL threads manpage for
details and "note on multi-threading" in the INSTALL file in the
source distribution.
I have a C++ application which runs using Wine for mac OS and Wine for Linux. I'm looking for a way to detect what's the host OS using C++.
The only thing I found is a way to detect if it's Wine or not (using wine_get_version), but I still need to separate mac OS and Linux runs.
Any ideas how to do it?
Thank you!
As #NathanOliver mentioned in the comments, you should use wine_get_host_version() for this. As with wine_get_version(), you need to use GetProcAddress() to get the function pointer from NTDLL. The C function signature for the function pointer would be:
void (CDECL *)( const char **sysname, const char **release )
You provide the address of two const char* variables and wine_get_host_version() sets them to point to two strings. The strings are those output by the uname() system library function. (If you're not interested in an output, it's safe to pass NULL for that parameter.)
For macOS, *sysname will be set to point to "Darwin". For Linux, it will point to "Linux", I believe. (It did on a couple of systems I tested, but I don't know how consistent that is.)
we need to check the macros defined by the compiler (GNU GCC or G++)
for checking os on which our c/c++ script is executing.
#include <stdio.h>
int main()
{
#if __APPLE__
// apple specific code
#elif _WIN32
// windows specific code
#elif __LINUX__
// linux specific code
#else
// general code or warning
#endif
// general code
return 0;
}
some more macros
I've built OpenCV using Intel IPP, so I suppose that whenever possible it's used (e.g. matrix multiplication).
I want to test the scalability of my parallel application by comparing it with a serial version. In order to do so, when it I do:
omp_set_num_threads(1);
cv::setNumThreads(1);
However, by monitoring the CPU usage I see that multiple CPUs are still used. Why is that? And how can I force the program execution by using just one CPU?
Re-building OpenCV from source with following CMake parameters should works:
cmake .. -DWITH_IPP=OFF -DWITH_TBB=OFF -DWITH_OPENMP=OFF -DWITH_PTHREADS_PF=OFF
and you will find the macro CV_PARALLEL_FRAMEWORK is not defined to something in modules/core/src/parallel.cpp any more:
#if defined HAVE_TBB
# define CV_PARALLEL_FRAMEWORK "tbb"
#elif defined HAVE_HPX
# define CV_PARALLEL_FRAMEWORK "hpx"
#elif defined HAVE_OPENMP
# define CV_PARALLEL_FRAMEWORK "openmp"
#elif defined HAVE_GCD
# define CV_PARALLEL_FRAMEWORK "gcd"
#elif defined WINRT
# define CV_PARALLEL_FRAMEWORK "winrt-concurrency"
#elif defined HAVE_CONCURRENCY
# define CV_PARALLEL_FRAMEWORK "ms-concurrency"
#elif defined HAVE_PTHREADS_PF
# define CV_PARALLEL_FRAMEWORK "pthreads"
#endif
You can disable it with:
cv::setNumThreads(0);
OpenCV will try to set the number of threads for the next parallel region.If threads == 0, OpenCV will disable threading optimizations and run all it's
functions sequentially. Passing threads < 0 will reset threads number to system
default. This function must be called outside of parallel region.
https://docs.opencv.org/4.5.1/db/de0/group__core__utils.html
add ippSetNumThreads(1); before the first IPP call in your code. This should set number of OpenMP threads in IPP to 1. More info can be found here in the "Controlling OpenMP Threading in the Intel IPP Primitives" section
Are you using opencv from multi threads ? You have to disable opencv's multi threading from each thread, atleast in my experience with it.
Opencv' parallel_for functions creates multiple threads to distribute the work across.
How do I declare in C/C++ that the code that is written is to be built in either HP-UX or Solaris or AIX?
I found that, a good way to figure this king of question, is, at least with gcc, to have this makefile:
defs:
g++ -E -dM - < /dev/null
then, :
$ make defs
should output all the definitions you have available.
So:
$ make defs | grep -i AIX
$ make defs | grep -i HP
should give you the answer. Example for Linux:
$ make defs | grep -i LINUX
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
#define linux 1
Once you found the define you are looking for, you type at the beginning of your code:
#if !(defined(HP_DEFINE) || defined(AIX_DEFINE) || defined(SOLARIS_DEFINE))
# error This file cannot be compiled for your plateform
#endif
How about a macro passed to the compiler ?
i.e. gcc -Dmacro[=defn]
Then test for the macro in your code with a simple #ifdef of #if (if you've given it a value). There may already be a predefined macro for your target platform as well.
[EDIT: Put some of my comments here in my answer that explain how -D works]
-Dmacro[=defn] on the command line for the compiler is the same as having #define macro defn in the code. You expand it out like this: -Dfoo=bar is equivalent to #define foo bar. Also, the definition is optional so -Dfoo is equivalent to #define foo.
Be careful about how you handle this. You should identify the features of the O/S that you want to use by feature, not by O/S, and write your code accordingly. Then, in one header, you can identify which of the features are available on the O/S that you are compiling on. This is the technique used by autoconf, and even if you do not use autoconf itself, the technique it espouses is better than the platform-based technique. Remember, the features found on one O/S often migrate and become available on others too, so if you work by features, you can adapt to the future more easily than if you work solely on the O/S.
You also have to write your code appropriately, and portably. Isolate the O/S dependencies in separate files whenever possible, and code to an abstract O/S interface that does what you need. Taken to an extreme, you end up with a Java JVM; you don't need to go that far, but you can obviate most of the problems.
Take a look at portable libraries like the Apache Portable Runtime (APR) library.
And write your code along the lines of:
#ifdef HAVE_PWRITE
...code using pread() and pwrite()...
#else
...code using plain old read() and write()...
#endif
This is a grossly over-simplified example - there could be a number of fallbacks before you use plain read() and write(). Nevertheless, this is the concept used in the most portable code - things like GCC and Apache and so on.
Perhaps a less convoluted solution that some of those suggested is to consult Pre-defined C/C++ Compiler Macros. This site provides an extensive list of compiler macros for a large number of compiler/OS/Architecture combinations.
Original Question
What I'd like is not a standard C pre-processor, but a variation on it which would accept from somewhere - probably the command line via -DNAME1 and -UNAME2 options - a specification of which macros are defined, and would then eliminate dead code.
It may be easier to understand what I'm after with some examples:
#ifdef NAME1
#define ALBUQUERQUE "ambidextrous"
#else
#define PHANTASMAGORIA "ghostly"
#endif
If the command were run with '-DNAME1', the output would be:
#define ALBUQUERQUE "ambidextrous"
If the command were run with '-UNAME1', the output would be:
#define PHANTASMAGORIA "ghostly"
If the command were run with neither option, the output would be the same as the input.
This is a simple case - I'd be hoping that the code could handle more complex cases too.
To illustrate with a real-world but still simple example:
#ifdef USE_VOID
#ifdef PLATFORM1
#define VOID void
#else
#undef VOID
typedef void VOID;
#endif /* PLATFORM1 */
typedef void * VOIDPTR;
#else
typedef mint VOID;
typedef char * VOIDPTR;
#endif /* USE_VOID */
I'd like to run the command with -DUSE_VOID -UPLATFORM1 and get the output:
#undef VOID
typedef void VOID;
typedef void * VOIDPTR;
Another example:
#ifndef DOUBLEPAD
#if (defined NT) || (defined OLDUNIX)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
Ideally, I'd like to run with -UOLDUNIX and get the output:
#ifndef DOUBLEPAD
#if (defined NT)
#define DOUBLEPAD 8
#else
#define DOUBLEPAD 0
#endif /* NT */
#endif /* !DOUBLEPAD */
This may be pushing my luck!
Motivation: large, ancient code base with lots of conditional code. Many of the conditions no longer apply - the OLDUNIX platform, for example, is no longer made and no longer supported, so there is no need to have references to it in the code. Other conditions are always true. For example, features are added with conditional compilation so that a single version of the code can be used for both older versions of the software where the feature is not available and newer versions where it is available (more or less). Eventually, the old versions without the feature are no longer supported - everything uses the feature - so the condition on whether the feature is present or not should be removed, and the 'when feature is absent' code should be removed too. I'd like to have a tool to do the job automatically because it will be faster and more reliable than doing it manually (which is rather critical when the code base includes 21,500 source files).
(A really clever version of the tool might read #include'd files to determine whether the control macros - those specified by -D or -U on the command line - are defined in those files. I'm not sure whether that's truly helpful except as a backup diagnostic. Whatever else it does, though, the pseudo-pre-processor must not expand macros or include files verbatim. The output must be source similar to, but usually simpler than, the input code.)
Status Report (one year later)
After a year of use, I am very happy with 'sunifdef' recommended by the selected answer. It hasn't made a mistake yet, and I don't expect it to. The only quibble I have with it is stylistic. Given an input such as:
#if (defined(A) && defined(B)) || defined(C) || (defined(D) && defined(E))
and run with '-UC' (C is never defined), the output is:
#if defined(A) && defined(B) || defined(D) && defined(E)
This is technically correct because '&&' binds tighter than '||', but it is an open invitation to confusion. I would much prefer it to include parentheses around the sets of '&&' conditions, as in the original:
#if (defined(A) && defined(B)) || (defined(D) && defined(E))
However, given the obscurity of some of the code I have to work with, for that to be the biggest nit-pick is a strong compliment; it is valuable tool to me.
The New Kid on the Block
Having checked the URL for inclusion in the information above, I see that (as predicted) there is an new program called Coan that is the successor to 'sunifdef'. It is available on SourceForge and has been since January 2010. I'll be checking it out...further reports later this year, or maybe next year, or sometime, or never.
I know absolutely nothing about C, but it sounds like you are looking for something like unifdef. Note that it hasn't been updated since 2000, but there is a successor called "Son of unifdef" (sunifdef).
Also you can try this tool http://coan2.sourceforge.net/
something like this will remove ifdef blocks:
coan source -UYOUR_FLAG --filter c,h --recurse YourSourceTree
I used unifdef years ago for just the sort of problem you describe, and it worked fine. Even if it hasn't been updated since 2000, the syntax of preprocessor ifdefs hasn't changed materially since then, so I expect it will still do what you want. I suppose there might be some compile problems, although the packages appear recent.
I've never used sunifdef, so I can't comment on it directly.
Around 2004 I wrote a tool that did exactly what you are looking for. I never got around to distributing the tool, but the code can be found here:
http://casey.dnsalias.org/exifdef-0.2.zip (that's a dsl link)
It's about 1.7k lines and implements enough of the C grammar to parse preprocessor statements, comments, and strings using bison and flex.
If you need something similar to a preprocessor, the flexible solution is Wave (from boost). It's a library designed to build C-preprocessor-like tools (including such things as C++03 and C++0x preprocessors). As it's a library, you can hook into its input and output code.