Exemplo n.º 1
0
int pthread_create ( pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg ) {
	int (*real_pthread_create) (pthread_t*, const pthread_attr_t*, void *(*routine)(void *), void*) = dlsym (RTLD_NEXT, "pthread_create");
	int (*real_pthread_setaffinity_np) (pthread_t thread, size_t cpusetsize, const cpu_set_t *cpuset) = dlsym (RTLD_NEXT, "pthread_setaffinity_np");
	int res;
	cpu_set_t cpuset;
	int nbProcessors = getNbProcessorsAvailable ();
	
	assert (real_pthread_create != NULL);
	assert (real_pthread_setaffinity_np != NULL);
	res = real_pthread_create (thread, attr, start_routine, arg);
	
	/* Pinning stuff */
	CPU_ZERO(&cpuset);
	CPU_SET(core, &cpuset);
	
	if (real_pthread_setaffinity_np (*thread, sizeof (cpu_set_t), &cpuset) != 0) {
		fprintf (stderr, "Error: Cannot pin thread %p on core %d\n", thread, core);
		perror ("");
	}
	
	core++;
	core %= nbProcessors;
	
	return res;
}
Exemplo n.º 2
0
/* 
 * pthread_create hook 
 */
int reeact_policy_pthread_create(void *thread, void *attr, 
				void *(*start_routine) (void *), void *arg)
{
#ifdef _REEACT_DEFAULT_POLICY_
	return real_pthread_create((pthread_t*)thread, (pthread_attr_t*)attr,
				   start_routine, arg);
#else
	// TODO: add user-policy here
	return 0;
#endif
}
Exemplo n.º 3
0
//Initialize
void myth_init_body(int worker_num,size_t def_stack_size)
{
	myth_init_ex_body(worker_num,def_stack_size);
	//Create worker threads
	intptr_t i;
	for (i=1;i<g_worker_thread_num;i++){
		real_pthread_create(&g_envs[i].worker,NULL,myth_worker_thread_fn,(void*)i);
	}
	g_envs[0].worker=real_pthread_self();
	//Initialize each worker threads
	myth_worker_thread_fn((void*)(intptr_t)0);
}
Exemplo n.º 4
0
Arquivo: preload.c Projeto: passimm/rr
/**
 * Interpose |pthread_create()| so that we can use a custom trampoline
 * function (see above) that initializes rr thread-local data for new
 * threads.
 *
 * This is a wrapper of |pthread_create()|, but not like the ones
 * below: we don't wrap |pthread_create()| in order to buffer its
 * syscalls, rather in order to initialize rr thread data.
 */
int pthread_create(pthread_t* thread, const pthread_attr_t* attr,
		   void* (*start_routine) (void*), void* arg)
{
	struct thread_func_data* data = malloc(sizeof(*data));
	void* saved_buffer = buffer;
	int ret;

	data->start_routine = start_routine;
	data->arg = arg;
	/* Don't let the new thread use our TLS pointer. */
	buffer = NULL;
	ret = real_pthread_create(thread, attr, thread_trampoline, data);
	buffer = saved_buffer;
	return ret;
}
Exemplo n.º 5
0
/* we are implementing these functions only to know when to turn tsafe
 * on and off.
 */
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg)
{
	static int (*real_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
                   void *(*start_routine) (void *), void *arg) = NULL;

	if (tsafe_inited && tsafe_disabled) {
		tsafe_on ();
	}

	if (real_pthread_create == NULL) {
		real_pthread_create = _get_real_func_ ("pthread_create");
	}
	return real_pthread_create (thread, attr, start_routine, arg);
}
Exemplo n.º 6
0
int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start) (void *), void *arg){

    int ret;
    char sem_name[100];
    int s_id;
    int sval;
    int err = 0;
    int proto = 0;


    /* This wrapper executes the full code with global lock, even call to real pthread_create */
    sem_wait(global_sem);

    pthread_create_counter[0]++;

    /* First of all, we need a simulation thread id. Under thread creation bursts could it be no
     * * free slot is available. This is what we call a proto-thread. It should be enough to wait 
     * * some time till one slot is available. If the wait takes more than 10 seconds, something is
     * * wrong about the simulation */
    while(1){
        struct timespec waiting;

        s_id = get_new_thread_id();
        if(s_id < 0){
            if(proto == 0){
                proto = 1;
                proto_threads[0]++;
                printf("WAITING FOR AN SLOT proto_threads: %d\n", proto_threads[0]);
            }
            sem_post(global_sem);
        }
        else
            break;
        err++;
        pthread_yield();
        if(err == 1000){
            printf("WARNING: pthread_create wrapper returning EAGAIN!!!\n");
            proto_threads[0]--;
            return -EAGAIN;
        }
        waiting.tv_sec = 0;
        waiting.tv_nsec = 10000000;
        nanosleep(&waiting, 0);
        sem_wait(global_sem);
    }

    /* Once we got here the simulation thread is not a proto-thread any more */
    if(proto)
        proto_threads[0]--;

    sim_lib_printf(0, "I GOT AN SLOT: proto_threads: %d\n", proto_threads[0]);

    /* simulation thread initialization */
    /* Most of it is just for debugging except sleep field */
    threads_data[s_id].sleep = -1;
    threads_data[s_id].creation = *current_sim;
    threads_data[s_id].deletion = 0;
    threads_data[s_id].last_sleep = 0;
    threads_data[s_id].never_ending = 0;
    threads_data[s_id].last_wakeup = 0;
    threads_data[s_id].wait_time = 0;
    threads_data[s_id].wait_count = 0;
    threads_data[s_id].func_addr = (unsigned long)start;
    threads_data[s_id].pid = getpid();

    set_new_thread(s_id);

    /* Calling real pthread_create is needed at this point. We need pthread_id for linking 
     * * a simulation thread id with a pthread_id. It could happen a fast thread trying to use
     * * this linking table before an entry has been created for it, but we are aware of this.
     * * The link is done as one of the last steps because we need to work for leaving all
     * * stable before the thread starts working with simulation structures.
     * */
    ret = real_pthread_create(thread, attr, start, arg);

    /* Opening semaphores using simulation thread id */
    memset(&sem_name, '\0', 100);
    sprintf(sem_name, "%s%d", SIM_LOCAL_SEM_PREFIX, s_id);

    sim_lib_printf(0, "Opening semaphore %s\n", sem_name);
    thread_sem[s_id] = sem_open(sem_name, 0);
    if(thread_sem[s_id] == SEM_FAILED){
        printf("Error opening semaphore number %d\n", s_id);
        return -1;
    }

    sem_getvalue(thread_sem[s_id], &sval);

    sim_lib_printf(0, "pthread_create: sval for %s = %d\n", sem_name, sval);

    memset(&sem_name, '\0', 100);
    sprintf(sem_name, "%s%d", SIM_LOCAL_SEM_BACK_PREFIX, s_id);

    sim_lib_printf(0, "Opening semaphore %s\n", sem_name);

    thread_sem_back[s_id] = sem_open(sem_name, 0);
    if(thread_sem_back[s_id] == SEM_FAILED){
        printf("Error opening semaphore number %d\n", s_id);
        return -1;
    }

    sem_getvalue(thread_sem_back[s_id], &sval);

    sim_lib_printf(0, "pthread_create: sval for %s = %d\n", sem_name, sval);

    /* Sometimes previous thread using this semaphore left the wrong value */
    while(sval > 1){
        sem_wait(thread_sem_back[s_id]);
        sem_getvalue(thread_sem_back[s_id], &sval);
    }

    if(sval == 0)
        sem_post(thread_sem_back[s_id]);

    sim_lib_printf(0, "pthread_create: sval for %s = %d\n", sem_name, sval);

    /* Is this really needed??? */
    thread_info_list[s_id].id = s_id;

    sim_lib_printf(0, "Dentro de wrapper para pthread_create, getting sleep id %d [%lu]\n", thread_info_list[s_id].id , *(thread));

    /* This is the important step. After this a thread can work with simulation wrappers */
    thread_info_list[s_id].p = *thread;

    threads_data[s_id].is_new = 1;
    threads_data[s_id].ptid = *thread;

    sem_post(global_sem);

    return ret;
}