mercredi 7 septembre 2016

Why does srand(time(NULL)) gives me segmentation fault on main?

Need some help here.

I want to understand what's happening in this code.

I'm trying to generate random numbers as tickets to the TCP_t struct created inside ccreate function.

The problem is, everytime I executed this code WITHOUT the srand(time(NULL)) it returned the same sequence of "random" numbers over and over, for example:

TID: 0 | TICKET : 103
TID: 1 | TICKET : 198

So I seeded it with time, to generate really random numbers.

When I put the seed inside the newTicket function, it brings different numbers in every execution, but the same numbers for every thread. Here is an example of output:

Execution 1:

TID: 0 | TICKET : 148
TID: 1 | TICKET : 148

Execution 2:

TID: 0 | TICKET : 96
TID: 1 | TICKET : 96

So, after some research, I found out I shouldn't seed it everytime I call rand but only once, in the beginning of the program. Now, after putting the seed inside the main function, it gives me segmentation fault, and I have NO IDEA why.

This might be a stupid question, but I really want to understand what's happening.

Is the seed screwing anything, somehow? Am I missing something? Should I generate random number in another way?

#include <ucontext.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

#define MAX_TICKET 255
#define STACK_SIZE 32000

typedef struct s_TCB {
  int threadId;
  int ticket;
  ucontext_t context;
} TCB_t;

void test();
int newTicket();
int newThreadId();
int ccreate (void* (*start)(void*), void *arg);
int threadId = 0;

int main(){
  srand(time(NULL)); //<<<============== HERE = SEGMENTATION FAULT
  ccreate((void*)&test, 0);
  ccreate((void*)&test, 0);
}

int ccreate (void* (*start)(void*), void *arg){
    if(start == NULL) return -1;

    ucontext_t threadContext;
    getcontext(&threadContext);
    makecontext(&threadContext, (void*)start, 0);
    threadContext.uc_stack.ss_sp = malloc(STACK_SIZE);
    threadContext.uc_stack.ss_size = STACK_SIZE;

    TCB_t * newThread = malloc(sizeof(TCB_t));
    if (newThread == NULL) return -1;

    int threadThreadId = newThreadId();
    newThread->threadId = threadThreadId;
    newThread->ticket = newTicket();

    printf("TID: %d | TICKET : %d\n", newThread->threadId, newThread->ticket);

    return threadThreadId;
}

int newThreadId(){
  int newThreadId = threadId;
  threadId++;
  return newThreadId;
}

int newTicket(){
  //srand(time(NULL)); //<<<============== HERE = IT PARTIALLY WORKS
  return (rand() % (MAX_TICKET+1));
}

void test(){
  printf("this is a test function");
}

Thanks to everyone who lends me a hand here.

And sorry if the code is too ugly to read. Tried to simplify it as much as I could.




Aucun commentaire:

Enregistrer un commentaire