Exemple #1
0
int init_semaphores(){

    char sem_name[100];

    printf("Initializing semaphores...\n");

    global_sem = sem_open(SIM_GLOBAL_SEM, 0);
    if(global_sem == SEM_FAILED){
        printf("global_sem can not be created\n");
        return -1;
    }

    /* Slurmctld and slurmd main threads are registered during initialization */
    main_thread = pthread_self();

    sem_wait(global_sem);

    main_thread = pthread_self();

    main_thread_id = get_new_thread_id(&main_thread);
    threads_data[main_thread_id].sleep = -1;
    threads_data[main_thread_id].pid  = getpid();

    printf("Getting main_thread_id %d\n", main_thread_id);

    sem_post(global_sem);

    /* and then initializing semaphores for this main thread */
    memset(&sem_name, '\0', 100);
    sprintf(sem_name, "%s%d", SIM_LOCAL_SEM_PREFIX, main_thread_id);
    printf("Opening semaphore %s\n", sem_name);

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

    memset(&sem_name, '\0', 100);
    sprintf(sem_name, "%s%d", SIM_LOCAL_SEM_BACK_PREFIX, main_thread_id);
    printf("Opening semaphore %s\n", sem_name);

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

    return 0;
}
Exemple #2
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;
}
Exemple #3
0
void xloop(sock_t sock, sock_t ctl_sock)
{
	fd_set sock_set;
	int retcode;
	pthread_attr_t pattr;
	int tid;
	sock_t conn;
	sigset_t curmask, oldmask;
	sock_t ctl_cli_sock = -1;

	/* prepare threads  */
	proxenet_xzero(threads, sizeof(pthread_t) * MAX_THREADS);
	
	if (pthread_attr_init(&pattr)) {
		xlog(LOG_ERROR, "%s\n", "Failed to pthread_attr_init");
		return;
	}
	
	pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_JOINABLE);

	/* block useful signal */
	sigemptyset(&curmask);
	sigaddset(&curmask, SIGTERM);
	sigaddset(&curmask, SIGINT);
	sigaddset(&curmask, SIGCHLD);
	if (pthread_sigmask(SIG_BLOCK, &curmask, &oldmask) < 0) {
		xlog(LOG_ERROR, "sigprocmask failed : %s\n", strerror(errno));
		return;
	}

	/* proxenet is now running :) */
	proxy_state = ACTIVE;
	
	/* big loop  */
	while (proxy_state != INACTIVE) {
		conn = -1;
		retcode = -1;	
		
		FD_ZERO(&sock_set);

		FD_SET(sock, &sock_set);
		FD_SET(ctl_sock, &sock_set);
		if (ctl_cli_sock > 0)
			FD_SET(ctl_cli_sock, &sock_set);

		purge_zombies();
		
		/* set asynchronous listener */
		struct timespec timeout = {
			.tv_sec = 5,
			.tv_nsec = 0
		};
		
		retcode = pselect(FD_SETSIZE, &sock_set, NULL, NULL, &timeout, &oldmask);
		
		if (retcode < 0) {
			if (errno != EINTR) {
				xlog(LOG_ERROR, "[main] pselect() returned %d: %s\n", retcode, strerror(errno));
				proxy_state = INACTIVE;
				break;
			} else {
				continue;
			}
		}
		
		if (retcode == 0)
			continue;

		if (proxy_state == INACTIVE)
			break;
		
		/* event on the listening socket -> new request */
		if( FD_ISSET(sock, &sock_set) && proxy_state != SLEEPING) {
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "Incoming listening event");
#endif

			tid = get_new_thread_id();
			if(tid < 0) {
				continue;
			}
			
			struct sockaddr addr;
			socklen_t addrlen = 0;

			proxenet_xzero(&addr, sizeof(struct sockaddr));

			conn = accept(sock, &addr, &addrlen); 
			if (conn < 0) {
				if(errno != EINTR)
					xlog(LOG_ERROR, "[main] accept() failed: %s\n", strerror(errno));
				continue;
			}
			
			retcode = proxenet_start_new_thread(conn, tid, &threads[tid], &pattr);
			if (retcode < 0) {
				xlog(LOG_ERROR, "[main] %s\n", "Error while spawn new thread");
				continue;
			}
			
		} /* end if _socket_event */
		
		
		/* event on control listening socket */
		if( FD_ISSET(ctl_sock, &sock_set) ) {
#ifdef DEBUG
			xlog(LOG_DEBUG, "%s\n", "Incoming control event");
#endif
			struct sockaddr_un sun_cli;
			socklen_t sun_cli_len = 0;
			int new_conn = -1;
			
			proxenet_xzero(&sun_cli, sizeof(struct sockaddr_un));

			new_conn = accept(ctl_sock, (struct sockaddr *)&sun_cli, &sun_cli_len);
			if (new_conn < 0) {
				xlog(LOG_ERROR, "[main] control accept() failed: %s\n", strerror(errno));
				continue;
			}
			
			if (ctl_cli_sock < 0) {
				ctl_cli_sock = new_conn;
				xlog(LOG_INFO, "%s\n", "New connection on Control socket");
				proxenet_write(ctl_cli_sock, CONTROL_MOTD, strlen(CONTROL_MOTD));
				proxenet_write(ctl_cli_sock, CONTROL_PROMPT, strlen(CONTROL_PROMPT));
				
			} else {
				if(new_conn > 0) {
					xlog(LOG_ERROR, "%s\n", "Denied control connection: already established");
					if(close_socket(new_conn) < 0) {
						xlog(LOG_ERROR, "Failed to close socket: %s\n", strerror(errno));
					}
				}
			}
			
		}/* end if _control_listening_event */

		
		/* event on control socket */
		if( ctl_cli_sock > 0 && FD_ISSET(ctl_cli_sock, &sock_set) ) {
			
			if (proxenet_handle_control_event(&ctl_cli_sock) < 0) {
				close_socket(ctl_cli_sock);
				ctl_cli_sock = -1;
			}
			
		} /* end if _control_event */
		
	}  /* endof while(!INACTIVE) */
	
	
	kill_zombies();
	proxenet_destroy_plugins_vm();
	pthread_attr_destroy(&pattr);
	
	return;
}


/**
 *
 * @param signum
 */
void sighandler(int signum)
{
#ifdef DEBUG
	xlog(LOG_DEBUG, "Received signal %s [%d]\n", strsignal(signum), signum);
#endif
	
	switch(signum) {
		
		case SIGTERM: 
		case SIGINT:
			if (proxy_state != INACTIVE)
				proxy_state = INACTIVE;
			
			cfg->try_exit++;
			xlog(LOG_INFO, "%s, %d/%d\n", "Trying to leave", cfg->try_exit, cfg->try_exit_max);
			
			if (cfg->try_exit == cfg->try_exit_max) {
				xlog(LOG_CRITICAL, "%s\n", "Failed to exit properly");
				abort();
			}
			
			break;

		case SIGCHLD:
			purge_zombies();
			break;
	}
}