PDA

View Full Version : Mutex across multiple source files



Quasar
12-04-2007, 07:22 AM
Hi all!

I'm working on a prog that uses mutexes. Since the code is growing bigger and bigger i decided to split it across multiple C and H files. To my surprise the mutexes stopped working!

I have no idea why this happened.

The general idea of the code is this:

A function that receives the mutex in its argument:


void function(pthread_mutex_t mut) {
pthread_mutex_lock(&mut);
printf("This shows up if function is in the same source file as the calling code.");
pthread_mutex_unlock(&mut);
}


The code that calls the function:


pthread_mutex_t mut;
pthread_mutex_init(&mut, NULL);

pthread_mutex_lock(&mut);
printf("This shows up!");
pthread_mutex_unlock(&mut);

function(mut);

pthread_mutex_destroy(&mut);


Sample Makefile:


CC = gcc
CFLAGS = -Wall -ansi -pedantic -g -D _XOPEN_SOURCE=600
OBJECTS = main.o function.o

all: $(OBJECTS)
$(CC) $(CFLAGS) -lpthread -lrt -lm -o main $(OBJECTS)

main.o: main.c main.h
function.o: function.c function.h

clean:
rm -f *.o main


Does anyone have any idea why this happens, and how to solve it?

Thank you!

Salem
12-04-2007, 07:25 AM
All other things being equal, splitting the source code into several files won't make a bean of difference.

The final executable has no knowledge of the structure of the source code which created it.

Quasar
12-04-2007, 07:28 AM
That's why i think it's a gcc problem, if i move the function to it's original place everything works!

I was wondering if there something lika a -mutex-across-multiple-source-files i should pass to gcc.

matsp
12-04-2007, 07:38 AM
No, it's not gcc's fault - or anyone elses. You are passing a COPY of the mutex to "function" - this mutex is NOT the same one that you were using in the other code.

It's not because you are using multiple files, but simply that you are copying an existing mutex, and making it a different mutex.



void function(pthread_mutex_t *mut) {
pthread_mutex_lock(mut);
printf("This shows up if function is in the same source file as the calling code.");
pthread_mutex_unlock(mut);
}
...
function(&mut);

should work.


--
Mats

Quasar
12-04-2007, 07:53 AM
It's more complicated that that. I simplified the example...

I'm passing this structure:



typedef struct { /* Country mutex structure */
pthread_mutex_t resA, resE, resP, resM;
pthread_mutex_t purchase1, purchase2;
} CountryMutex;


Into this function:


void findDeficit(const Config *config, const CountryStruct *country, CountryDeficit *cdeficit, CountryMutex *cmutex) {
pthread_mutex_lock(&cmutex->resA);
...
pthread_mutex_unlock(&cmutex->resA);
}


Using this call:


CountryMutex cmutex;
pthread_mutex_init(&cmutex.resA, NULL);
pthread_mutex_init(&cmutex.resE, NULL);
pthread_mutex_init(&cmutex.resP, NULL);
pthread_mutex_init(&cmutex.resM, NULL);

findDeficit(config, country, cdeficit, &cmutex); << EDIT


Shouldn't this work? Passing a pointer to a structure of mutexes?

matsp
12-04-2007, 07:55 AM
Your calling code doesn't look like it's passing pointers, so I'm not sure if it's at all working - but yes, passing a structure pointer that contains mutexes should work. The point is that you can't make copies of a mutex and still think that it's the same mutex.

--
Mats

Quasar
12-04-2007, 07:59 AM
Sorry, missing &.

Still the same problem, argh...

Rebooting the server, maybe that works.

matsp
12-04-2007, 08:25 AM
Sorry, missing &.

Still the same problem, argh...

Rebooting the server, maybe that works.

Rebooting the server doesn't sound like the right thing - mutexes should be "infinite" resources [as in, they are only limited by amount of memory, so if you can create the mutex itself, you can use the mutex].

--
Mats