I have a project that consists of several processes running in different computers. It is similar to a "OS Simulator", mainly task scheduling and resource allocation.
There's a main process, "Platform" or "Server", that planifies/schedules the different processes that connect to it, by using a queue with the available processes that are ready to execute.
As time passes however, the pointers lose the memory address of some of them, or the reference to it, or the memory to which it points is either freed or just used for some other variable. This then leads to the process that's supposed to run just halting and waiting for the Platform to schedule it, which never happens because the element from the queue no longer references the process(which we handle with file descriptors). Is there anyway to prevent this from happening??
Here's the portion of the code where we think the problem is:
response = string_substring_from(response, sizeof(FREERESC));
char** data = string_split(response, COMA);
t_queue *temporaryQueue = queue_create();
t_scheduler_queue *queues = dictionary_get(levels_queues, data[0]);
pthread_mutex_lock(queues->mutex);
t_queue *anotherQueue = queue_create();
long o = 0;
if (queue_size(queues->character_queue) > 0)
{
log_info(log, "Mas de un personaje listo");
for (o = 0; o < queue_size(queues->character_queue); o++)
{
personaje_planificador *personajeEnLista = queue_pop(
queues->character_queue);
personaje_planificador *nuevoPersonaje = (personaje_planificador*) malloc(sizeof(personaje_planificador));
// long *hola = (long*) malloc(sizeof(long));
// memcpy(hola, &(personajeEnLista->fd), sizeof(long));
// nuevoPersonaje->fd = hola;
nuevoPersonaje->fd = personajeEnLista->fd;
nuevoPersonaje->nombre = string_from_format("%s", personajeEnLista->nombre);
queue_push(anotherQueue, nuevoPersonaje);
}
}
char** simbolos;
long j = 2;
t_dictionary *recursosDisponibles = dictionary_create();
for (j = 2; j < list_size(queues->simbolos) + 2; j++)
{
simbolos = string_split(data[j], DOSPUNTOS);
long *temporary = (long*) malloc(sizeof(long));
*temporary = atoi(simbolos[1]);
dictionary_put(recursosDisponibles, simbolos[0], temporary);
}
if (queue_size(queues->blocked_queue) > 0)
{
log_info(log, "Mas de un personaje bloqueado");
long i = 0;
long k = 0;
for (i = 0; i < queue_size(queues->blocked_queue); i++)
{
blocked_character *blockedCharacter = queue_pop(queues->blocked_queue);
for (k = 0; k < list_size(queues->simbolos); k++)
{
if (blockedCharacter->recurso == ((char*) list_get(queues->simbolos, k))[0])
{
if (giveResource(queues, dictionary_get(recursosDisponibles, list_get(queues->simbolos, k)), blockedCharacter) == 1)
{
personaje_planificador *nuevoPersonajeAgain = (personaje_planificador*) malloc(sizeof(personaje_planificador));
nuevoPersonajeAgain->fd =
blockedCharacter->personaje->fd;
nuevoPersonajeAgain->nombre = blockedCharacter->personaje->nombre;
queue_push(temporaryQueue, nuevoPersonajeAgain);
//TODO log
}
else
{
queue_push(queues->blocked_queue, blockedCharacter);
}
}
}
k = 0;
}
}
o = 0;
for (o = 0; o < queue_size(temporaryQueue); o++)
{
queue_push(anotherQueue, queue_pop(temporaryQueue));
}
queues->character_queue = anotherQueue;
pthread_mutex_unlock(queues->mutex);
t_level_address *addresses = (t_level_address*) dictionary_get(levelsMap, data[0]);
char **levelSocket = string_split(addresses->nivel, DOSPUNTOS);
long fdNivel = openSocketClient(levelSocket[1], levelSocket[0]);
sendMessage(fdNivel, stringRecursos(queues->simbolos, recursosDisponibles, atoi(data[1])));
free(recursosDisponibles);
log_info(log, "Liberar recursos.");
if (flagTerminoUnPersonaje == TRUE)
{
executeKoopa(niveles, levels_queues, orquestador_config);
}
Let me know if a portion of the code is unclear (it has some things written in Spanish), or if you need another part where you think the problem may be in.
Somebody mentioned "ValGrind" in one of the comments.
Try one of the products mentioned here: http://en.wikipedia.org/wiki/BoundsChecker
You should be able to find a free trial if not an outright free version. (it's been about 10 years since I regularly maintained other people's C and had to use Purify and Insure to hunt down this kind of aliasing and leaking)
Related
I have this function which is using calloc to create an array of structure proposition. Whenever I try to free the resulting array from another fuction, it crashes.
proposition* get_matching_propositions(char *pcde, proposition *propositions, int *match_count)
{
proposition *matches;
int count = get_count_from_stream(ptf_proposition, sizeof(proposition)),
cptr_match = 0;
for (int i = 0; i < count; i++)
{
if (strcmp(propositions[i].cde, pcde) == NULL)
{
cptr_match++;
}
}
matches = (proposition*) calloc (cptr_match, sizeof(propositions));
assert(matches != NULL);
cptr_match = 0;
for (int i = 0; i < count; i++)
{
if (strcmp(propositions[i].cde, pcde) == NULL)
{
matches[cptr_match] = propositions[i];
cptr_match++;
}
}
*match_count = cptr_match;
return matches;
}
Inside some other function I have:
proposition *matches =
get_matching_propositions(current_question.cde, propositions, &match_count);
free(matches);
Then the program crashes with this message :
Process returned -1073740940 (0xC0000374) execution time : 1.370 s.
I'm here asking for your help, not because I have an error, but simply because of this solution that in my head seemed quite credible despite not working.
I basically have a structure to make an appointment and I created a variable of this temporary structure to change the values so that they are in ascending order, however when I show the query table in this case, but the queries appear in the order I registered them in the program.
My Struct:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
My function that should order the values:
void organizarAgenda(int membroEscolhido, consulta agenda[][50][50], int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i, j;
boolean substituir;
consulta temp;
for (i = 0; i < nAgendas[membroEscolhido]; i++)
{
for (j = 0; j < nAgendas[membroEscolhido]; j++)
if (agenda[j][membroEscolhido][clinicaSelecionada].ano > agenda[i][membroEscolhido][clinicaSelecionada].ano)
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes > agenda[i][membroEscolhido][clinicaSelecionada].mes))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia > agenda[i][membroEscolhido][clinicaSelecionada].dia))
substituir = true;
if (agenda[j][membroEscolhido][clinicaSelecionada].ano == agenda[i][membroEscolhido][clinicaSelecionada].ano
&& (agenda[j][membroEscolhido][clinicaSelecionada].mes == agenda[i][membroEscolhido][clinicaSelecionada].mes)
&& (agenda[j][membroEscolhido][clinicaSelecionada].dia == agenda[i][membroEscolhido][clinicaSelecionada].dia
&& agenda[j][membroEscolhido][clinicaSelecionada].horasInicio >= agenda[i][membroEscolhido][clinicaSelecionada].horasInicio))
substituir = true;
if (substituir == true)
{
//Igualar a variavel temporario á variável agenda em i
temp.ano = agenda[i][membroEscolhido][clinicaSelecionada].ano;
temp.mes = agenda[i][membroEscolhido][clinicaSelecionada].mes;
temp.dia = agenda[i][membroEscolhido][clinicaSelecionada].dia;
temp.horasInicio = agenda[i][membroEscolhido][clinicaSelecionada].horasInicio;
temp.minutosInicio = agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio;
temp.horasFim = agenda[i][membroEscolhido][clinicaSelecionada].horasFim;
temp.minutosFim = agenda[i][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em i á variável agenda em j
agenda[i][membroEscolhido][clinicaSelecionada].ano = agenda[j][membroEscolhido][clinicaSelecionada].ano;
agenda[i][membroEscolhido][clinicaSelecionada].mes = agenda[j][membroEscolhido][clinicaSelecionada].mes;
agenda[i][membroEscolhido][clinicaSelecionada].dia = agenda[j][membroEscolhido][clinicaSelecionada].dia;
agenda[i][membroEscolhido][clinicaSelecionada].horasInicio = agenda[j][membroEscolhido][clinicaSelecionada].horasInicio;
agenda[i][membroEscolhido][clinicaSelecionada].minutosInicio = agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio;
agenda[i][membroEscolhido][clinicaSelecionada].horasFim = agenda[j][membroEscolhido][clinicaSelecionada].horasFim;
agenda[i][membroEscolhido][clinicaSelecionada].minutosFim = agenda[j][membroEscolhido][clinicaSelecionada].minutosFim;
//Igualar a variável agenda em j á variavel temporaria
agenda[j][membroEscolhido][clinicaSelecionada].ano = temp.ano;
agenda[j][membroEscolhido][clinicaSelecionada].mes = temp.mes;
agenda[j][membroEscolhido][clinicaSelecionada].dia = temp.dia;
agenda[j][membroEscolhido][clinicaSelecionada].horasInicio = temp.horasInicio;
agenda[j][membroEscolhido][clinicaSelecionada].minutosInicio = temp.minutosInicio;
agenda[j][membroEscolhido][clinicaSelecionada].horasFim = temp.horasFim;
agenda[j][membroEscolhido][clinicaSelecionada].minutosFim = temp.minutosFim;
}
}
Thank you all in advance!
substituir is unitialized. You need to set it to false immediately after the for statement for j.
Your for loop for j is missing a trailing { so it will only iterate over the first if and not the others [as you would probably like]
As I mentioned in my comment, simplify [please ;-)]. Use pointers to simplify the code.
Your indexing is quite complex, so I can only guess at things.
I changed the comparison logic to something I understand.
Here's a simplified version. I just coded it, so it may not compile. But, it should give you some ideas how to proceed:
typedef struct Consulta {
char nomeUtente[70];
int numSNS;
int dia;
int mes;
int ano;
int horasInicio;
int minutosInicio;
int horasFim;
int minutosFim;
} consulta;
void
organizarAgenda(int membroEscolhido, consulta agenda[][50][50],
int clinicaSelecionada, int *nFuncionarios, int *nAgendas)
{
int i;
int j;
int lim = nAgendas[membroEscolhido];
int dif;
consulta temp;
for (i = 0; i < lim; i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = 0; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
do {
dif = iptr->ano - jptr->ano;
if (dif)
break;
dif = iptr->mes - jptr->mes;
if (dif)
break;
dif = iptr->dia - jptr->dia;
if (dif)
break;
} while (0);
if (dif <= 0)
continue;
temp = *iptr;
*iptr = *jptr;
*jptr = temp;
}
}
}
I'm [still] guessing but I think you can get a [significant] speedup by changing the for loop for j.
And, I think the for loop for i goes one too far.
So, consider:
for (i = 0; i < (lim - 1); i++) {
consulta *iptr = &agenda[i][membroEscolhido][clinicaSelecionada];
for (j = i + 1; j < lim; j++) {
consulta *jptr = &agenda[j][membroEscolhido][clinicaSelecionada];
UPDATE:
I didn't understand how a 3d array with only a 2d array assignment works int lim = nAgendas[membroEscolhido];
The value of nAgendas[membroEscolhido] is invariant across the function, so it can be "cached". I did this to simplify the code [mostly] but it also can help the compiler generate more efficient code.
I didn't notice the (-) in the middle of this line, and the -> works because it is a pointer pointing to the struct, right?
Right. The arrow operator (->) is a very powerful way to access individual struct members if you have a pointer to the given struct instance.
Note that the compiler's optimizer might be able to see that all the variables of the form: array[x][y][z].whatever could be reduced.
But, when we use intermediate pointers we're giving it a [better] clue as to what we want. And, the code is more readable by humans, so it has two good reasons to do it.
I don't understand why you put while (0)
This is a bit of a trick [of mine] to replace an if/else ladder with something that is cleaner.
It forms a "once through" loop. It would be the equivalent of:
while (1) {
if (something)
break;
if (something_else)
break;
break; // make the loop execute _only_ once
}
For a more detailed explanation, see my answer: About the exclusiveness of the cases of an if block
I´m trying to create a dynamic matrix with an user introduzed number of lines and 6 columns.
I only want to create the matrix so I can get its values when I want to.
I have tried this but the program crashes when it gets here.
matriz = (int **)malloc(n_lines * 6 * sizeof(int *));
for (i = 0; i < n_lines; ++i)
{
for (j = 0; j < 6; ++j)
{
current_year = starting_year + i;
if (current_year % 400 == 0)
{
february = 29;
days = 366;
hours = 8784;
minutes = 527040;
seconds = 31622400;
}
else
{
february = 28;
days = 365;
hours = 8760;
minutes = 525600;
seconds = 31536000;
}
matriz[i][0] = { current_year };
matriz[i][1] = { february };
matriz[i][2] = { days };
matriz[i][3] = { hours };
matriz[i][4] = { minutes };
matriz[i][5] = { seconds };
}
}
Program crashed because you were accessing chunk of memory as if you have jagged allocated array which is not, resulting in invalid memory access in turn making your program crash.
Well from what I see - you messed up type. Two ways to go about this.
int **matriz;
matriz = malloc(sizeof *matriz*nlines);
// error check
for(size_t i=0; i<nlines; i++){
matriz[i]= malloc(sizeof *matriz[i] * 6);
// error check
}
int *matriz = malloc(6*nlines*sizeof *matriz);
// error check
matriz[r*6+c] = ... // accessing r-th row c-th column.
And based on case-1 it will be
matriz[i][j] = current_year ;
And in case-2 similarly
matriz[i*6+j] = current_year;
General code structure would be
if (current_year % 400 == 0)
{
...
seconds = 31622400;
}
else
{
...
seconds = 31536000;
}
for (j = 0; j < 6; ++j)
{
matriz[i][j] = current_year ;
...
}
To explain a bit - the first case is allocating a jagged array. First an array of pointers and then each of them are pointing to an array of 6 elements.
Second case is basically allocating a chunk of memory which has 6*nlines int and matriz is pointing to beginning of it. Now that's why you will have to access the elements first calculating the right index for it.
Hello guys i have threefunctions for which i get 4 warnings...!!
The first one is this
void evaluatearxikos(void)
{
int mem;
int i;
double x[NVARS+1];
FILE *controlpointsarxika;
controlpointsarxika = fopen("controlpointsarxika.txt","r");
remove("save.txt");
for(mem = 0; mem < POPSIZE; mem++)
{
for(i = 0; i < NVARS; i++)
{
x[i+1] = population[mem].gene[i];
}
rbsplinearxiki();
XfoilCall();
population[mem].fitness = FileRead();
remove("save.txt");
}
fclose(controlpointsarxika);
}
For this one the compiler warns me tha variable x is set but not used...!! But actually i am using the variable x...!!!
The second function is this one...
void elitist(void)
{
int i;
double best,worst;
int best_mem,worst_mem;
best = population[0].fitness;
worst = population[0].fitness;
for(i = 0; i < POPSIZE - 1; i++)
{
if(population[i].fitness > population[i+1].fitness)
{
if(population[i].fitness >= best)
{
best = population[i].fitness;
best_mem = i;
}
if(population[i+1].fitness <= worst)
{
worst = population[i+1].fitness;
worst_mem = i+1;
}
}
else
{
if(population[i].fitness <= worst)
{
worst = population[i].fitness;
worst_mem = i;
}
if(population[i+1].fitness >= best)
{
best = population[i+1].fitness;
best_mem = i+1;
}
}
}
if(best >= population[POPSIZE].fitness)
{
for(i = 0; i < NVARS; i++)
{
population[POPSIZE].gene[i] = population[best_mem].gene[i];
}
population[POPSIZE].fitness = population[best_mem].fitness;
}
else
{
for(i = 0; i < NVARS; i++)
{
population[worst_mem].gene[i] = population[POPSIZE].gene[i];
}
population[worst_mem].fitness = population[POPSIZE].fitness;
}
}
For this one i get two warnings that the variables worst_mem and best_mem may be used uninitialized in this function..!! But i initialize values to both of them..!!
And the third function is this...
void crossover(void)
{
int mem,one;
int first = 0;
double x;
for(mem =0; mem < POPSIZE; mem++)
{
x = rand()%1000/1000;
if(x < PXOVER)
{
first++;
if(first%2 == 0)
{
random_Xover(one,mem);
}
else
{
one = mem;
}
}
}
}
For which i get that the variable one may be used unitialized..!! But it is initialized..!
Can you please tell me what is wrong with these functions...??
Thank you in advance
In your first function, you set (assign) x, but you never read it, hence you are not using it... you're only wasting CPU cycles by writing to it. (Note also that because you index it as i+1 you write beyond the space you've allocated for it).
In the second function, your initializations to those variables are in conditional blocks. You can see that (perhaps? I didn't verify) in all conditions they are initialized but your compiler isn't that smart.
In your third function, it does appear that one could be refered to without having first been initialized.
First: You set x but do not use it. It's a local variable that gets set but it's dropped as soon as the function returns.
Second: There might be values that makes it so that your best_mem/worst_mem never gets set in your if/else, but you are using them later on. If they haven't been set, they contain garbage if not initialized.
Third: While it shouldn't happen that you try to use an uninitialized variable in your code, it still looks weird and compiler doesn't see that it won't happen first time.
When you get compiler warnings, treat is as you are doing something wrong or rather not recommended and that it could be done in a better way.
The x variable is only used on the left hand side (i.e. assigned a value). You are not using that value on the right hand side or pass it to a function.
It may be possible to get to the end of the loop for(i = 0; i < POPSIZE - 1; i++) without those variables given a value. Why not set them in the declaration.
The call to random_Xover(one,mem); could be called when one is not set. Change the line int mem,one; to int mem,one = <some value>;
I'm new to CUDA C and I'm trying to parallelize the following piece of code of the slave_sort function, which you will realize that is already parallel to work with posix threads..
I have the following structs:
typedef struct{
long densities[MAX_RADIX];
long ranks[MAX_RADIX];
char pad[PAGE_SIZE];
}prefix_node;
struct global_memory {
long Index; /* process ID */
struct prefix_node prefix_tree[2 * MAX_PROCESSORS];
} *global;
void slave_sort(){
.
.
.
long *rank_me_mynum;
struct prefix_node* n;
struct prefix_node* r;
struct prefix_node* l;
.
.
MyNum = global->Index;
global->Index++;
n = &(global->prefix_tree[MyNum]);
for (i = 0; i < radix; i++) {
n->densities[i] = key_density[i];
n->ranks[i] = rank_me_mynum[i];
}
offset = MyNum;
level = number_of_processors >> 1;
base = number_of_processors;
while ((offset & 0x1) != 0) {
offset >>= 1;
r = n;
l = n - 1;
index = base + offset;
n = &(global->prefix_tree[index]);
if (offset != (level - 1)) {
for (i = 0; i < radix; i++) {
n->densities[i] = r->densities[i] + l->densities[i];
n->ranks[i] = r->ranks[i] + l->ranks[i];
}
} else {
for (i = 0; i < radix; i++) {
n->densities[i] = r->densities[i] + l->densities[i];
}
}
base += level;
level >>= 1;
}
Mynum is the number of processors. I want after passing the code to kernel, Mynum to berepresented by blockIdx.x.The problem is that i get confused with the structs. I don't know how to pass them in the kernel. Can anyone help me?
Is the following code right?
__global__ void testkernel(prefix_node *prefix_tree, long *dev_rank_me_mynum, long *key_density,long radix)
int i = threadIdx.x + blockIdx.x*blockDimx.x;
prefix_node *n;
prefix_node *l;
prefix_node *r;
long offset;
.
.
.
n = &prefix_tree[blockIdx.x];
if((i%numthreads) == 0){
for(int j=0; j<radix; j++){
n->densities[j] = key_density[j + radix*blockIdx.x];
n->ranks[i] = dev_rank_me_mynum[j + radix*blockIdx.x];
}
.
.
.
}
int main(...){
long *dev_rank_me_mynum;
long *key_density;
prefix_node *prefix_tree;
long radix = 1024;
cudaMalloc((void**)&dev_rank_me_mynum, radix*numblocks*sizeof(long));
cudaMalloc((void**)&key_density, radix*numblocks*sizeof(long));
cudaMalloc((void**)&prefix_tree, numblocks*sizeof(prefix_node));
testkernel<<<numblocks,numthreads>>>(prefix_tree,dev_runk_me_mynum,key_density,radix);
}
The host API code you have posted in your edit looks fine. The prefix_node structure only contains statically declared arrays, so all that is needed is a single cudaMalloc call to allocate memory for the kernel to work on. Your method of passing prefix_tree to the kernel is also fine.
The kernel code, although incomplete and containing a couple of obvious typos, is another story. It seems that your intention is to only have a single thread per block operate on one "node" of the prefix_tree. That will be terribly inefficient and utilise only a small portion of the GPU's total capacity. For example why do this:
prefix_node *n = &prefix_tree[blockIdx.x];
if((i%numthreads) == 0){
for(int j=0; j<radix; j++){
n->densities[j] = key_density[j + radix*blockIdx.x];
n->ranks[j] = dev_rank_me_mynum[j + radix*blockIdx.x];
}
.
.
.
}
when you could to this:
prefix_node *n = &prefix_tree[blockIdx.x];
for(int j=threadIdx.x; j<radix; j+=blockDim.x){
n->densities[j] = key_density[j + radix*blockIdx.x];
n->ranks[j] = dev_rank_me_mynum[j + radix*blockIdx.x];
}
which coalesces the memory reads and uses as many threads in the block as you choose to run, rather than just one and should be many times faster as a result. So perhaps you should rethink your strategy of directly trying to translate the serial C code you posted into a kernel....