Pthread and gcc compiling issue on OS X - c

I have a script that compiles fine on Linux (Ubuntu 11.04), but not on OS X (Lion).
gcc -pthread -o hw1 hw1.c
hw1.c:22: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘barr’
hw1.c: In function ‘__syncthreads’:
hw1.c:53: error: ‘barr’ undeclared (first use in this function)
hw1.c:53: error: (Each undeclared identifier is reported only once
hw1.c:53: error: for each function it appears in.)
hw1.c:54: error: ‘PTHREAD_BARRIER_SERIAL_THREAD’ undeclared (first use in this function)
hw1.c: In function ‘parallel_psum’:
hw1.c:94: error: ‘barr’ undeclared (first use in this function)
hw1.c:107: warning: assignment from incompatible pointer type
Here's the first 22 lines of the code:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include <math.h>
#include <sys/time.h>
#include <pthread.h>
#include <assert.h>
/* create thread argument struct for thr_func() */
typedef struct _thread_data_t {
int tid;
int* ints;
int* sums;
int num_ints;
int* temp;
} thread_data_t;
const int MIN_RAND_INT = 1;
const int MAX_RAND_INT = 65000;
// pthreads barrier variable
pthread_barrier_t barr;
Any ideas why this is happening?

According to info about pthread_barriers on opengroup.org, barriers are defined in the optional part of POSIX standard; the name of option is "(ADVANCED REALTIME THREADS)", sometimes more exact referred as "BAR, barriers (real-time)".
http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap02.html
The system may support one or more options (see Options) denoted by the following symbolic constants:
_POSIX_BARRIERS
So, only if the _POSIX_BARRIERS macro is defined as positive number, you can use pthread_barrier_t or pthread_barrier_wait.
Mac OS X is POSIX Compliant, but full list of implemented options is not available online. There is a letter in apple mainling list from 2006, which says there is no barriers in Mac OS X.
I know that Solaris had some problems with pthread_barrier too.

Just like osgx mentioned, barriers are not implemented on OS X, but you can always implement it or just use this implementation. Quick note on the previous implementation, you can use the macro that osgx mentioned, _POSIX_BARRIERS, instead of the ones on the blog, like this #if !defined _POSIX_BARRIERS || _POSIX_BARRIERS < 0

Related

Windows.h functions not declared - C

I'm trying to write a test program using windows.h. I have a simple main function with a function in it and doesn't work when I compile it:
#include <windows.h>
#include <stdio.h>
int main(){
COORD coords;
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, &coords);
return 0;
}
But when I compile it using "mingw32-gcc main.c" i get:
main.c: In function 'main':
main.c:107:5: warning: implicit declaration of function 'SetConsoleDisplayMode' [-Wimplicit-function-declaration]
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, &coords);
^~~~~~~~~~~~~~~~~~~~~
main.c:107:60: error: 'CONSOLE_FULLSCREEN_MODE' undeclared (first use in this function)
SetConsoleDisplayMode(GetStdHandle(STD_OUTPUT_HANDLE), CONSOLE_FULLSCREEN_MODE, &coords);
^~~~~~~~~~~~~~~~~~~~~~~
main.c:107:60: note: each undeclared identifier is reported only once for each function
(It says it's in line 107 because I wrote additional functions that does not need windows.h and don't cause trouble as I don't use them, also they are commented)

cannot compile the CUDA code when splitted into several files

I'm writing this simple cuda code and I'm unable to compile it. The code contains part of code written in C. This is the structure of the program:
read_data.c file contains a function called read_data
add.cu file contains a function called add (this is the part that should run in the GPGPU)
optimize.h file contains the necessary headers.
master.c file contains the main function.
The optimize.h file looks like follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <ctype.h>
#include <time.h>
__global__ void add(int, float*, float*);
void read_data(char*, float**, float**, int**);
master.c file looks like follows:
#include "optimize.h"
int main(){
char* path = "./data/0";
float* base_load;
float* comfortable_temperatures;
int* comfort_index;
read_data(path, &base_load, &comfortable_temperatures, &comfort_index);
int N = 1<<20;
float *x, *y;
int i;
cudaMallocManaged(&x, N*sizeof(float));
cudaMallocManaged(&y, N*sizeof(float));
for (i = 0; i < N; i++) {
x[i] = 1.0f;
y[i] = 2.0f;
}
add<<<1, 256>>>(N, x, y);
cudaDeviceSynchronize();
// still need to read the result back.
cudaFree(x);
cudaFree(y);
}
I compiled this using the following line:
nvcc -o master master.c read_data.c add.cu
and I'm getting this error:
In file included from master.c:1:0:
optimize.h:9:12: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘void’
__global__ void add(int, float*, float*);
^
master.c: In function ‘main’:
master.c:51:26: error: ‘add’ undeclared (first use in this function)
add<<<1, 256>>>(N, x, y);
^
master.c:51:26: note: each undeclared identifier is reported only once for each function it appears in
master.c:51:31: error: expected expression before ‘<’ token
add<<<1, 256>>>(N, x, y);
I think the whatever the error is, it should be a very small one. But I cannot find it.
nvcc by default treats filenames ending in .c or .cpp as having no CUDA-specific syntax, and sends those to the host compiler. The host compiler cannot handle CUDA-specific syntax, which is why you are getting the errors.
The usual recommendations are to place your CUDA code in files ending with .cu. You can alternatively pass -x cu as a compile switch to do this.
Note that nvcc uses c++ style linkage, so you will need to arrange for correct c-style linkage if you are trying to link code in a .cu file with code in a .c file. If you have no C-specific usage, again, a simple solution may be to rename your .c file to .cpp or .cu.
There are many questions here on the cuda tag explaining how to do C++/C linkage, otherwise.

error in errno.h (and more) when compiling lex generated files

I am currently getting the error message:
In file included from /usr/include/errno.h:35:0,
from lex.yy.c:21:
/usr/include/x86_64-linux-gnu/bits/errno.h:50:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘extern’
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
^
(along with many others) when attempting a to compile a file generated by lex using the command:
gcc lex.yy.c
lex.l (file passed to lex to generate lex.yy.c) source:
%%
"hello world" printf("goodbye");
. ;
%%
This problem occurs when I try to compile any file which has been generated by lex or flex (I've tried both)
As I mentioned there are also many more errors but maybe fixing this one will solve some of the others. After looking for some common errors with errno.h and finding nothing of any use, I'm asking here.
I am using Ubuntu 16.04 LTS. Let me know if you would like/need more information regarding the problem and I'll do my best to help.
Thanks for any advice :)
Edit for 'rici':
The first 21 lines of my lex.yy.c file are as follows:
#line 3 "lex.yy.c"
#define YY_INT_ALIGNED short int
/* A lexical scanner generated by flex */
#define FLEX_SCANNER
#define YY_FLEX_MAJOR_VERSION 2
#define YY_FLEX_MINOR_VERSION 6
#define YY_FLEX_SUBMINOR_VERSION 0
#if YY_FLEX_SUBMINOR_VERSION > 0
#define FLEX_BETA
#endif
/* First, we deal with platform-specific or compiler-specific issues. */
/* begin standard C headers. */
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
/* end standard C headers. */
Edit for #sepp2k:
I used vimdiff to compare the 2 files.
Things that are in my file but aren't in yours:
#ifdef __cplusplus
/* The "const" storage-class-modifier is valid. */
#define YY_USE_CONST
#else /* ! __cplusplus */
/* C99 requires __STDC__ to be defined as 1. */
#if defined (__STDC__)
#define YY_USE_CONST
#endif /* defined (__STDC__) */
#endif /* ! __cplusplus */
#ifdef YY_USE_CONST
===============================================================
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#line 476 "lex.yy.c"
There is nothing really which is in your file that is not in mine
Any other differences seem to just be differences of formatting.
I also tested the four header files in a standard C program (see what you mean now) and I can confirm it is errno.h which is causing the error.
A hello world in C with errno.h included threw up the following error:
In file included from /usr/include/errno.h:35:0,
from test.c:2:
/usr/include/x86_64-linux-gnu/bits/errno.h:50:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘extern’
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
^
In file included from test.c:4:0:
/usr/include/stdio.h:13:1: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘int’
int printf(const char* __restrict, ...);
^
edit for #rici:
Here is the full dump of errors thrown when i run "gcc lex.yy.c":
https://gist.github.com/raygarner/0601e57f5be21e16e0ae4ee34643b121
edit for #sepp2k:
earlier on, i tested this exact same compilation process on a fresh install of debian 9 in a VM and I got the exact same error I am doing here, on Ubuntu after fixing errno.h
Here is what it looks like:
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
As we've found out in the comments, the original error was due to a messed up errno.h on your system and you fixed that by reinstalling the file.
With that solved, your code will compile fine, but won't link as a standalone application because of missing yywrap and main functions. You can fix the former by defining yywrap or using %option noyywrap. The latter can be fixed by defining a main function or linking against an object file that defines main (if the lexer is part of a larger project that already defines its own main function).
You can also fix both problems by linking -lfl, which defines the yywrap and main functions to read either from stdin or the file names from argv and then prints the resulting tokens to stdout. Of course that's only useful for testing purposes as you'll want to do more than that in your main in real projects.

why am i not able to declare sigset_t with std=c99?

If i compile the below program with std=c99, i get an error, but the program compiles fine without the c99 flag. Why?
#include <signal.h>
void x()
{
sigset_t dd;
}
int main(void)
{
x();
return 0;
}
jim#cola temp]$ gcc -std=c99 blah.c -o blah
blah.c: In function ‘x’:
blah.c:9: error: ‘sigset_t’ undeclared (first use in this function)
blah.c:9: error: (Each undeclared identifier is reported only once
blah.c:9: error: for each function it appears in.)
blah.c:9: error: expected ‘;’ before ‘dd’
Because sigset_t is not part of <signal.h> in standard C and you requested strict standards compatibility with -std=c99. That is, a strictly standard C program can do:
#include <signal.h>
int sigset_t;
int main(void) { return 0; }
and expect it to work.
sigset_t is not in C99 standard, but it is available in POSIX. You can define _POSIX_SOURCE or _POSIX_C_SOURCE to make sigset_t available.
Here is the definition:
#define _NSIG 64
#define _NSIG_BPW 32
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
typedef unsigned long old_sigset_t; /* at least 32 bits */
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
Also see What does #define _POSIX_SOURCE mean?

Cannot found any data type used by SendInput() function

I'm trying to use SendInput() function. I wrote this code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winuser.h>
#define WIN32_LEAN_AND_MEAN
//...
KEYBDINPUT kbi;
kbi.wVk = 0x31;
kbi.wScan = 0;
kbi.dwFlags = 0;
kbi.time = 0;
INPUT input;
input.type = INPUT_KEYBOARD;
input.ki = kbi;
SendInput(1, &input, sizeof input);
Compiling:
gcc -Wall -o window.exe win32.c -lWs2_32
I get:
win32.c: In function ‘main’:
win32.c:13:2: error: ‘KEYBDINPUT’ undeclared (first use in this function)
win32.c:13:2: note: each undeclared identifier is reported only once for each function it appears in
win32.c:13:13: error: expected ‘;’ before ‘kbi’
win32.c:14:2: error: ‘kbi’ undeclared (first use in this function)
win32.c:20:2: error: ‘INPUT’ undeclared (first use in this function)
win32.c:20:8: error: expected ‘;’ before ‘input’
win32.c:21:2: error: ‘input’ undeclared (first use in this function)
win32.c:21:15: error: ‘INPUT_KEYBOARD’ undeclared (first use in this function)
I have no idea how to fix tihis. According the documentation it's declared in Winuser.h header. But don't works for me.
#define _WIN32_WINNT 0x0403
#include <windows.h>
Seems this is the magic #define you need somewhere in your project (either explicitly in code, or via compiler command line param -D).
Note that windows.h includes winuser.h, so there's no need to include that, as it's included already for you. Also, the WIN32_LEAN_AND_MEAN define only has any effect if it's included before windows. Details about what it does here; it's not needed or particularly useful these days.
--
So what's going on here? Looking for the definition of KBDINPUT in winuser.h (C:\Cygwin\usr\include\w32api\winuser.h), we see:
#if (_WIN32_WINNT >= 0x0403)
typedef struct tagMOUSEINPUT {
...
} MOUSEINPUT,*PMOUSEINPUT;
typedef struct tagKEYBDINPUT {
...
That's the problem; these only get defined if _WIN32_WINNT is greater than 0x0403.
Those are the files from the cygwin package. Interestingly, the winuser.h from the Microsoft SDK (usually installed in C:\Program Files\Microsoft SDKs\Windows\v7.1\Include\WinUser.h) uses a different condition:
#if (_WIN32_WINNT > 0x0400)
...which explains Jay's suggestion - he's likely looking at the MS files, where 0x0401 would be sufficient here; and also explains why it's not working for you - you're likely using the cygwin ones with a higher version requirement. As to why these two files are different - I've no idea there...
I guess you need to add
#define _WIN32_WINNT 0x0401
#include <windows.h>
#include <winuser.h>
before including windowsh and winuser.h in your source.
This is an issue with older IDEs like VC6, I tried the above and it didn't work. I had to supply the flag on project settings.
Go to Setting >> C/C++ tab >> select 'General' from Catagory combo box
add /D _WIN32_WINNT=0x401 to Project settings edit box. That's for VC6.
/d is how you supply the flag and the actual flag is _WIN32_WINNT=0x401. I do had to set it to 0x401, other values like 0x0500 were causing more errors.

Resources