When does pthread_t have 0? - pthreads

I created threads using pthread_create() in RHEL 7.2.
pthread_create returns 0, but *thread (1st parameter) is 0.
do you know the reason that thread id is 0?
pthread_t thread[6];
int nArg;
int nThread = pthread_create(&thread[0], NULL, funcA, &nArg);
if(0 > nThread)
printf("failed");
else
printf("thread started: %ld", thread[0]);
Output:
thread started: 0

I created threads using pthread_create() in RHEL 7.2. pthread_create
returns 0, but *thread (1st parameter) is 0.
do you know the reason that thread id is 0?
Assuming for the moment that it really is 0, what of it? That presupposes that pthread_t is an arithmetic type, which is not specified by the current version of POSIX, but if so, then 0 is a valid value for it. There is no documented significance for specific thread identifier values, and in particular, there is no reason to think that a thread shouldn't be assigned 0 as its identifier if that is a valid value of type pthread_t.
Since you also mentioned the return value of pthread_create, I suppose you may think there is some kind of relationship between that and the thread ID. No such relationship is documented, except that the value of the thread ID is defined after pthread_create() returns only if the return value is exactly 0.
But that does point to an issue in your code, which #ErikAlapää first pointed out: pthread_create() is in the group of functions that return an error number directly on failure, not the group that return -1 on failure and expect you to consult errno for the error number. Error numbers are positive, so your condition if(0 > nThread) cannot be relied upon to detect whether pthread_create failed. You should test against exactly 0:
if (0 != nThread) {
printf("failed");
} else {
printf("thread started: %lu", (unsigned long) thread[0]);
}
Note also the format change and cast in the second printf() call. You need the second argument to have exactly the type corresponding to formatting directive (formerly %ld, but now %lu) and that's unsigned long int. The cast is valid is long as pthread_t is an arithmetic or pointer type, and in practice, the compiler can be relied upon to reject the code if it's anything else -- a structure type, say. Given that a cast is necessary (but possibly not sufficient) to obtain a known type, an unsigned type is safer because the conversion then has defined behavior in the event that the original value is out of range for the target type. If you have a type mismatch, as you could have had in your original code, then the behavior is undefined, and among the more likely of the uncountably many possible manifestations of such UB is that "0" is printed despite thread[0] being nonzero.
With all that said, I do not reproduce your issue, even with your original, flawed code. I'm inclined to suspect that your pthread_create call is failing, possibly because you're using a C library built without thread support, or linking dummy pthreads routines instead of functional ones. Be sure when you build to provide the right options for a pthreads program. For example, if you're compiling with gcc then you would want to provide the -pthread option. If you have separate compilation and link steps, then use that option for both.

Try instead checking the return value against exactly zero. Only if return value is 0 did the thread creation succeed.
The errno manpage says 'Valid error numbers are all positive numbers'. For example, on Linux, the errno error numbers seem to be roughly betwen 0 and 200.
Also, print the message corresponding to the errno error number you get, using e.g. perror().

The pthread_t type is opaque according to POSIX. It can be any type. In particular, it is not required to be an arithmetic type (pointer or integer). A conforming implementation of POSIX threads can use a struct for pthread_t.
If pthread_t happens to be an integer type, there is no prohibition against it being zero. It could be the index of a thread in some array, such that the first thread gets position zero.
We are not surprised that the standard input file descriptor is zero, after all.

Related

how to get the available memory on the device

I'm trying to obtain how much free memory I have on the device. To do this I call the cuda function cuMemGetInfo from a fortran code, but it returns negative values for the free amount of memory, so there's clearly something wrong.
Does anyone know how I can do that?
Thanks
EDIT:
Sorry, in fact my question was not very clear. I'm using OpenACC in Fortran and I call the C++ cuda function cudaMemGetInfo. Finally I could fix the code, the problem was effectively the kind of variables that I was using. Switching to size_ fixed everything. This is the interface in fortran that I'm using:
interface
subroutine get_dev_mem(total,free) bind(C,name="get_dev_mem")
use iso_c_binding
integer(kind=c_size_t)::total,free
end subroutine get_dev_mem
end interface
and this the cuda code
#include <cuda.h>
#include <cuda_runtime.h>
extern "C" {
void get_dev_mem(size_t& total, size_t& free)
{
cuMemGetInfo(&free, &total);
}
}
There's one last question: I pushed an array on the gpu and I checked its size using cuMemGetInfo, then I computed it's size counting the number of bytes, but I don't have the same answer, why? In the first case it is 3052mb large, in the latter 3051mb. This difference of 1mb could be the size of the array descriptor? Here there's the code that I used:
integer, parameter:: long = selected_int_kind(12)
integer(kind=c_size_t) :: total, free1,free2
real(8), dimension(:),allocatable::a
integer(kind=long)::N, eight, four
allocate(a(four*N))
!some OpenACC stuff in order to init the gpu
call get_dev_mem(total,free1)
!$acc data copy(a)
call get_dev_mem(total,free2)
print *,"size a in the gpu = ",(free1-free2)/1024/1024, " mb"
print *,"size a in theory = ", (eight*four*N)/1024/1024, " mb"
!$acc end data
deallocate(a)
Right, so, like commenters have suggested, we're not sure exactly what you're running, but filling in the missing details by guessing, here's a shot:
Most CUDA API calls return a status code (or error code if you will); this is true both in C/C++ and in Fortran, as we can see in the Portland Group's CUDA Fortran Manual:
Most of the runtime API routines are integer functions that return an error code; they return a value of zero if the call was successful, and a nonzero value if there was an error. To interpret the error codes, refer to “Error Handling,” on page 48.
This is the case for cudaMemGetInfo() specifically:
integer function cudaMemGetInfo( free, total )
integer(kind=cuda_count_kind) :: free, total
The two integers for free and total are cuda_count_kind, which if I am not mistaken are effectively unsigned... anyway, I would guess that what you're getting is an error code. Have a look at the Error Handling section on page 48 of the manual.

MAX / MIN function in Objective C that avoid casting issues

I had code in my app that looks like the following. I got some feedback around a bug, when to my horror, I put a debugger on it and found that the MAX between -5 and 0 is -5!
NSString *test = #"short";
int calFailed = MAX(test.length - 10, 0); // returns -5
After looking at the MAX macro, I see that it requires both parameters to be of the same type. In my case, "test.length" is an unsigned int and 0 is a signed int. So a simple cast (for either parameter) fixes the problem.
NSString *test = #"short";
int calExpected = MAX((int)test.length - 10, 0); // returns 0
This seems like a nasty and unexpected side effect of this macro. Is there another built-in method to iOS for performing MIN/MAX where the compiler would have warned about mismatching types? Seems like this SHOULD have been a compile time issue and not something that required a debugger to figure out. I can always write my own, but wanted to see if anybody else had similar issues.
Enabling -Wsign-compare, as suggested by FDinoff's answer is a good idea, but I thought it might be worth explaining the reason behind this in some more detail, as it's a quite common pitfall.
The problem isn't really with the MAX macro in particular, but with a) subtracting from an unsigned integer in a way that leads to an overflow, and b) (as the warning suggests) with how the compiler handles the comparison of signed and unsigned values in general.
The first issue is pretty easy to explain: When you subtract from an unsigned integer and the result would be negative, the result "overflows" to a very large positive value, because an unsigned integer cannot represent negative values. So [#"short" length] - 10 will evaluate to 4294967291.
What might be more surprising is that even without the subtraction, something like MAX([#"short" length], -10) will not yield the correct result (it would evaluate to -10, even though [#"short" length] would be 5, which is obviously larger). This has nothing to do with the macro, something like if ([#"short" length] > -10) { ... } would lead to the same problem (the code in the if-block would not execute).
So the general question is: What happens exactly when you compare an unsigned integer with a signed one (and why is there a warning for that in the first place)? The compiler will convert both values to a common type, according to certain rules that can lead to surprising results.
Quoting from Understand integer conversion rules [cert.org]:
If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, the operand with unsigned integer type is converted to the type of the operand with signed integer type.
Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.
(emphasis mine)
Consider this example:
int s = -1;
unsigned int u = 1;
NSLog(#"%i", s < u);
// -> 0
The result will be 0 (false), even though s (-1) is clearly less then u (1). This happens because both values are converted to unsigned int, as int cannot represent all values that can be contained in an unsigned int.
It gets even more confusing if you change the type of s to long. Then, you'd get the same (incorrect) result on a 32 bit platform (iOS), but in a 64 bit Mac app it would work just fine! (explanation: long is a 64 bit type there, so it can represent all 32 bit unsigned int values.)
So, long story short: Don't compare unsigned and signed integers, especially if the signed value is potentially negative.
You probably don't have enough compiler warnings turned on. If you turn on -Wsign-compare (which can be turned on with -Wextra) you will generate a warning that looks like the following
warning: signed and unsigned type in conditional expression [-Wsign-compare]
This allows you to place the casts in the right places if necessary and you shouldn't need to rewrite the MAX or MIN macros

What are primitive types default-initialized to in C?

I just had Apple's C/C++ compiler initialize a float to a non-zero value (approx "-0.1").
That was a big surprise - and only happened occasionally (but 100% repeatably, if you ran through the same function calls / args beforehand). It took a long time to track down (using assertions).
I'd thought floats were zero-initialized. Googling suggests that I was thinking of C++ (which of course is much more precise about this stuff - c.f. SO: What are primitive types default-initialized to in C++? ).
But maybe Apple's excuse here is that their compiler was running in C mode ... so: what about C? What should happen, and (more importantly) what's typical?
(OF COURSE I should have initialized it manually - I normally do - but in this one case I failed. I didn't expect it to blow up, though!)
(Google is proving worse than useless for any discussion of this - their current search refuses to show "C" without "C++". Keeps deciding I'm too stupid, and ignoring even my input even when running in advanced mode)
Here's the actual source example where it happened. At first I thought there might be a problem with definitions of MAX and ABS (maybe MAX(ABS,ABS) doesnt always do what you'd expect?) ... but digging with assertions and debugger, I eventually found it was the missing initialization - that float was getting init'd to non-zero value VERY occasionally):
float crossedVectorX = ... // generates a float
float crossedVectorY = ... // generates a float
float infitesimal; // no manual init
float smallPositiveFloat = 2.0 / MAX( ABS(crossedVectorX), ABS(crossedVectorY));
// NB: confirmed with debugger + assertions that smallPositiveFloat was always positive
infitesimal += smallPositiveFloat;
NSAssert( infitesimal >= 0.0, #"This is sometimes NOT TRUE" );
Only objects with static storage duration are initialized to 0 if there is no explicit initializer.
#include <stdio.h>
float f; // initialized to 0, file scope variables have static storage
static float g; // initialized to 0
int main(void)
{
float h; // not initialized to 0, automatic storage duration
static float i; // initialized to 0
return 0;
}
Objects with automatic storage duration (like h in the example above) that are not explicitly initialized have an indeterminate value. Reading their value is undefined behavior.
EDIT: for the sake of completeness, since C11 objects with thread storage duration are also initialized to 0 if there is no explicit initializer.
The relevant part of the standard is §6.7.9 paragraph 10:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
If your variable had thread or static storage duration instead, then the next part of the paragraph would take effect:
If an object that has static or thread storage duration is not initialized explicitly, then:
-- if it has pointer type, it is initialized to a null pointer;
-- if it has arithmetic type, it is initialized to (positive or unsigned) zero;
...
I would also note that you should turn on your compiler's warnings (specifically the warning for uninitialized variables), as that should have identified the problem for you immediately.
Static variable would be initialized to zero, but I'm guessing you are talking about a local variable (i.e. stack, or automatic) - these are not initialized for you, but get whatever value is at that memory on the stack.
I had to pull out my K&R for this answer:
In the absence of explicit initialization, external and static variables are guaranteed to be initialized to zero; automatic and register variables have undefined (i.e., garbage) initial values.
I don't believe that any of the standards for C define initial values for variables in general. This would be in accord with the general philosophy of and application domain for C -- programming for grown-ups who may, one day, have reason to want their compiler to not initialise a variable for them and who know that it is their responsibility to initialise their own variables.

Using read() system call of UNIX to find the user given pattern

I am trying to emulate grep pattern of UNIX using a C program( just for learning ). The code that i have written is giving me a run time error..
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#define MAXLENGTH 1000
char userBuf[MAXLENGTH];
int main ( int argc, char *argv[])
{
int numOfBytes,fd,i;
if (argc != 2)
printf("Supply correct number of arguments.\n");
//exit(1);
fd =open("pattern.txt",O_RDWR);
if ( fd == -1 )
printf("File does not exist.\n");
//exit(1);
while ( (numOfBytes = read(fd,userBuf,MAXLENGTH)) > 0 )
;
printf("NumOfBytes = %d\n",numOfBytes);
for(i=0;userBuf[i] != '\0'; ++i)
{
if ( strstr(userBuf,argv[1]) )
printf("%s\n",userBuf);
}
}
The program is printing infinitely, the lines containing the pattern . I tried debugging , but couldn't figure out the error. Please let me know where am i wrong.,
Thanks
Say the string is "fooPATTERN". Your first time through the loop, you check for the pattern in "fooPATTERN" and find it. Then your second time through the loop, you check for the pattern in "ooPATTERN" and find it again. Then your third time, you check for the pattern in "oPATTERN" and find it again.
Since you're doing this to learn, I won't tell you much more. You can decide how best to solve it. There are at least two fundamentally different ways you could solve it. One is to do less on each pass of the loop to ensure you only find it once. The other is to make sure your next pass of the loop is past any pattern that was found.
One thing to think about: If the pattern is 'oo' and the string is 'ooo', how many patterns should be found? 1 or 2?
The 'read' does not delimit the data with a null character.
The while loop should encompase the for loop - it doesn't
First, you shouldn't be using raw Unix i/o with open and read if you're just learning C. Start with standard C i/o with fopen and fread/fscanf/fgets and so forth.
Second, you're reading in successive pieces of the file into the same buffer, overwriting the buffer each time, and only ever processing the last contents of the buffer.
Third, nothing guarantees that your buffer will be zero-terminated when you read into it with read(). In fact, it usually won't be.
Fourth, you're not using the i variable in the body of your loop. I can't tell exactly what you were shooting for here, but doing the same thing on the same data umpteen thousand times surely wasn't it.
Fifth, always compile with the fullest warning settings you can abide -- at lest -Wall with GCC. It should have complained that you call read() without including <unistd.h>.

How to get gfortran to do INTEGER - LOGICAL conversion

According to this, gfortran can do integer-logical conversion, but I'm getting this error:
if (.not.bDropped.and.(zz_unif01() .lt. (1 - (Test_Dru
1
Error: Operand of .not. operator at (1) is INTEGER(4)
I know it would be better to change the code from .not.bDropped to (bDropped.eq.0), but that would not be simple because it's generated code.
I tried various -std=xxx flags but they made no difference.
The last line on the page you linked to reads
However, there is no implicit conversion of INTEGER values in if-statements, [...].
I'd guess that has something to do with it.
Edit: This seems not to be the entire truth. Simply doing l1 = .not. 0 (when l1 is a logical variable) gives the same error you received. So there is no implicit conversion in this case either.

Resources