Пример #1
0
void main(int argc, char *argv[])
{
   
   int i, rc;
   pthread_attr_t attr;
   str_studente studente[N];

   pthread_mutex_init(&distributori[0], NULL);
   pthread_mutex_init(&distributori[1], NULL);
       // inizializzo i semafori
    sem_init(&coca, 0, 50);
    sem_init(&chino, 0, 10);
    sem_init(&fanta, 0, 20);
    sem_init(&sprite, 0, 20);
    
    //inizializzo thread per il gestore
    pthread_create(&gestore, NULL, gestore_routine, NULL);
    
    //inizializzo gli attributi per i thread studenti e li setto joinable
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

    //inizializzo i thread studente
    for (i=0; i<N; i++) {
        studente[i].nome = i;
        studente[i].ccoca = 0;
        studente[i].csprite = 0;
        studente[i].cfanta = 0;
        studente[i].cchino = 0;
        rc = pthread_create(&studente[i].tid, &attr, studente_routine, (void *) &studente[i]);
        if (rc) {
            printf("si è verificato un errore\n");
            exit(EXIT_FAILURE);
        }
    }

    pthread_attr_destroy(&attr);
 

 sleep(30);            //dopo 30 secondi si attiva la terminazione del programma!
finito= 1;

    for(i=0; i<N; i++) {
    pthread_join(studente[i].tid, NULL);
    }

    for (i=0; i<N; i++) {
          printf("Sono lo studente %d! Ho bevuto %d coca cole, %d sprite, %d fanta, %d chinotti!\n", studente[i].nome, studente[i].ccoca, studente[i].csprite, studente[i].cfanta, studente[i].cchino);
    }



    sem_destroy(&coca);
    sem_destroy(&sprite);
    sem_destroy(&fanta);
    sem_destroy(&chino);

    pthread_mutex_destroy(&distributori[0]);
    pthread_mutex_destroy(&distributori[1]);

   pthread_exit(NULL);    


}
Пример #2
0
int ta_process_loop(int man_sockfd, struct com_msg_open_session *open_msg)
{
	int ret;
	pthread_t ta_logic_thread;
	pthread_attr_t attr;
	struct epoll_event cur_events[MAX_CURR_EVENTS];
	int event_count, i;
	char proc_name[MAX_PR_NAME]; /* For now */
	sigset_t sig_empty_set;

	/* Set new ta process name */
	strncpy(proc_name, open_msg->ta_so_name, MAX_PR_NAME);
	prctl(PR_SET_NAME, (unsigned long)proc_name);
	strncpy(argv0, proc_name, argv0_len);

	/* Load TA to this process */
	ret = load_ta(open_msg->ta_so_name, &interface);
	if (ret != TEE_SUCCESS || interface == NULL) {
		OT_LOG(LOG_ERR, "Failed to load the TA");
		exit(EXIT_FAILURE);
	}

	/* Note: All signal are blocked. Prepare allow set when we can accept signals */
	if (sigemptyset(&sig_empty_set)) {
		OT_LOG(LOG_ERR, "Sigempty set failed: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* create an eventfd, that will allow the writer to increment the count by 1
	 * for each new event, and the reader to decrement by 1 each time, this will allow the
	 * reader to be notified for each new event, as opposed to being notified just once that
	 * there are "event(s)" pending*/
	event_fd = eventfd(0, EFD_SEMAPHORE);
	if (event_fd == -1) {
		OT_LOG(LOG_ERR, "Failed to initialize eventfd");
		exit(EXIT_FAILURE);
	}

	/* Initializations of TODO and DONE queues*/
	INIT_LIST(&tasks_todo.list);
	INIT_LIST(&tasks_done.list);

	/* Init epoll and register FD/data */
	if (init_epoll())
		exit(EXIT_FAILURE);

	/* listen to inbound connections from the manager */
	if (epoll_reg_fd(man_sockfd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* listen for communications from the TA thread process */
	if (epoll_reg_fd(event_fd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* Signal handling */
	if (epoll_reg_fd(self_pipe_fd, EPOLLIN))
		exit(EXIT_FAILURE);

	/* Init worker thread */
	ret = pthread_attr_init(&attr);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed to create attr for thread: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* TODO: Should we reserver space for thread stack? */

	ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed set DETACHED: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* Known error: CA can not determ if TA is launched or not, because framework is calling
	 * create entry point and open session function. Those functions return values is mapped
	 * into one return value. */
	if (interface->create() != TEE_SUCCESS) {
		OT_LOG(LOG_ERR, "TA create entry point failed");
		exit(EXIT_SUCCESS);
	}

	/* Launch worker thread and pass open session message as a parameter */
	ret = pthread_create(&ta_logic_thread, &attr, ta_internal_thread, open_msg);
	if (ret) {
		OT_LOG(LOG_ERR, "Failed launch thread: %s", strerror(errno))
		interface->destroy();
		exit(EXIT_FAILURE);
	}

	pthread_attr_destroy(&attr); /* Not needed any more */

	/* Allow signal delivery */
	if (pthread_sigmask(SIG_SETMASK, &sig_empty_set, NULL)) {
		OT_LOG(LOG_ERR, "failed to allow signals: %s", strerror(errno))
		exit(EXIT_FAILURE);
	}

	/* Enter into the main part of this io_thread */
	for (;;) {
		event_count = wrap_epoll_wait(cur_events, MAX_CURR_EVENTS);
		if (event_count == -1) {
			if (errno == EINTR) {

				continue;
			}

			/* Log error and hope the error clears itself */
			OT_LOG(LOG_ERR, "Failed return from epoll_wait");
			continue;
		}

		for (i = 0; i < event_count; i++) {

			if (cur_events[i].data.fd == man_sockfd) {
				receive_from_manager(&cur_events[i], man_sockfd);

			} else if (cur_events[i].data.fd == event_fd) {
				reply_to_manager(&cur_events[i], man_sockfd);

			} else if (cur_events[i].data.fd == self_pipe_fd) {


			} else {
				OT_LOG(LOG_ERR, "unknown event source");
			}
		}
	}

	/* Should never reach here */
	exit(EXIT_FAILURE);
}
Пример #3
0
/**
 *  This function implements a 2nd version of counters.
 *
 *  @param fpout                file out
 *  @param n_counter            number of counters
 *  @param i_ni                 iteration index
 *  @param kmer_size            kmer size
 *  @param memory_available     memory
 *  @param sizeInbuffer         input buffer size
 *  @param n_ni                 iterations
 *  @param n_np                 partitions
 *  @param n_nh                 hash table size
 *  @param totalfilesize        total file size
 *  @param n_byte               return number of bytes
 *  @param n_hash               return number of kmers
 *  @param progress_flag        progress
 *  @param progressToError_flag progress to std err
 *  @param nopack_flag          no pack
 *  @param infile               NULL when counting
 *  @param outdir               output directory
 *  @param outfile              output file name
 *
 *  @return SUCCESS or FAIL
 */
int alder_kmer_thread7(FILE *fpout,
                       int n_counter,
                       int i_ni,
                       int kmer_size,
                       long memory_available,
                       long sizeInbuffer,
                       long sizeOutbuffer,
                       uint64_t n_ni,
                       uint64_t n_np,
                       size_t n_nh,
                       int lower_count,
                       int upper_count,
                       size_t *n_byte,
                       size_t *n_kmer,
                       size_t *n_hash,
                       size_t n_total_kmer,
                       size_t *n_current_kmer,
                       int progress_flag,
                       int progressToError_flag,
                       int nopack_flag,
                       uint8_t *inbuf,
                       size_t size_data,
                       struct bstrList *infile,
                       const char *outdir,
                       const char *outfile)
{
    alder_log5("preparing counting Kmers with version 2...");
    counter_id_counter = 0;
    counter_full_counter = 0;
    int s = 0;
    if (n_counter > 1 && kmer_size > 31) {
        mcas_init(n_counter);
    }
    
    alder_kmer_thread7_t *data =
    alder_kmer_thread7_create(fpout,
                              n_counter,
                              i_ni,
                              kmer_size,
                              memory_available,
                              sizeInbuffer,
                              sizeOutbuffer,
                              n_ni,
                              n_np,
                              n_nh,
                              lower_count,
                              *n_byte,
                              n_total_kmer,
                              *n_current_kmer,
                              progress_flag,
                              progressToError_flag,
                              nopack_flag,
                              infile,
                              outdir,
                              outfile);
    if (data == NULL) {
        alder_loge(ALDER_ERR_MEMORY, "failed to creat counter threads.");
        return ALDER_STATUS_ERROR;
    }
    alder_log5("creating %d threads: one for reader, and one for writer",
               n_counter);
    
    pthread_t *threads = malloc(sizeof(*threads)*n_counter);
    if (data == NULL || threads == NULL) {
        alder_loge(ALDER_ERR_MEMORY, "cannot create threads for counting");
        XFREE(threads);
        alder_kmer_thread7_destroy(data);
        return ALDER_STATUS_ERROR;
    }
    memset(threads,0,sizeof(*threads)*n_counter);
    
    pthread_attr_t attr;
    s += pthread_attr_init(&attr);
    s += pthread_mutex_init(&mutex_read, NULL);
    s += pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    for (int i = 0; i < n_counter; i++) {
        s += pthread_create(&threads[i], &attr, counter, (void *)data);
    }
    if (s != 0) {
        alder_loge(ALDER_ERR_THREAD, "cannot create threads - %s",
                   strerror(errno));
        goto cleanup;
    }
    
    /* Wait for all threads to complete */
    alder_log3("main(): waiting for all threads to complete...");
    for (int i = 0; i < n_counter; i++) {
        s += pthread_join(threads[i], NULL);
        if (s != 0) {
            alder_loge(ALDER_ERR_THREAD, "cannot join threads - %s",
                       strerror(errno));
            goto cleanup;
        }
    }
    
cleanup:
    /* Cleanup */
    pthread_attr_destroy(&attr);
    pthread_mutex_destroy(&mutex_read);
    XFREE(threads);
    
    data->n_byte = 0;
    for (int i = 0; i < n_counter; i++) {
        data->n_byte += data->n_i_byte[i];
    }
    data->n_kmer = 0;
    for (int i = 0; i < n_counter; i++) {
        data->n_kmer += data->n_i_kmer[i];
    }
    alder_log2("counter()[%d] Kmers: %zu", i_ni, data->n_kmer);
    alder_log2("counter()[%d) Bytes: %zu", i_ni, data->n_byte);
    *n_byte += data->n_byte;
    *n_kmer += data->n_kmer;
    *n_hash += data->n_hash;
    *n_current_kmer += data->n_kmer;
    
    alder_kmer_thread7_destroy(data);
    alder_log5("Counting Kmers has been finished with %d threads.", n_counter);
    return 0;
}
Пример #4
0
static int
do_test (void)
{
  int n;
  pthread_t th[N];
  ucontext_t mctx;

  puts ("making contexts");
  if (getcontext (&mctx) != 0)
    {
      if (errno == ENOSYS)
	{
	  puts ("context handling not supported");
	  exit (0);
	}

      printf ("%s: getcontext: %m\n", __FUNCTION__);
      exit (1);
    }

  /* Play some tricks with this context.  */
  if (++global == 1)
    if (setcontext (&mctx) != 0)
      {
	puts ("setcontext failed");
	exit (1);
      }
  if (global != 2)
    {
      puts ("global not incremented twice");
      exit (1);
    }
  puts ("global OK");

  pthread_attr_t at;

  if (pthread_attr_init (&at) != 0)
    {
      puts ("attr_init failed");
      return 1;
    }

  if (pthread_attr_setstacksize (&at, 1 * 1024 * 1024) != 0)
    {
      puts ("attr_setstacksize failed");
      return 1;
    }

  for (n = 0; n < N; ++n)
    if (pthread_create (&th[n], &at, tf, (void *) (long int) n) != 0)
      {
	puts ("create failed");
	exit (1);
      }

  if (pthread_attr_destroy (&at) != 0)
    {
      puts ("attr_destroy failed");
      return 1;
    }

  for (n = 0; n < N; ++n)
    if (pthread_join (th[n], NULL) != 0)
      {
	puts ("join failed");
	exit (1);
      }

  return failures;
}
Пример #5
0
int main(int argc, char *argv[]) {
	int server_socket, client_socket, on = 1;
	
	struct sockaddr_in server_addr, client_addr;
	socklen_t client_length;
	pthread_t pthread_id;
	pthread_attr_t pthread_attr;

	/**
	 * Creating new lists, l is supposed to contain the connected users.
	 */
	l = list_new();

	/**
	 * Listens for CTRL-C and Segmentation faults.
	 */ 
	(void) signal(SIGINT, &sigint_handler);
	(void) signal(SIGSEGV, &sigint_handler);
	(void) signal(SIGPIPE, &sigint_handler);


	printf("Server: \t\tStarted\n");
	fflush(stdout);

	/**
	 * Assigning port value.
	 */
	if (argc == 2) {
		port = strtol(argv[1], (char **) NULL, 10);
		
		if (port <= 1024 || port >= 65565) {
			port = PORT;
		}

	} else {
		port = PORT;	
	}

	printf("Port: \t\t\t%d\n", port);
	fflush(stdout);

	/**
	 * Opening server socket.
	 */
	if ( (server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
		server_error(strerror(errno), server_socket, l);
	}

	printf("Socket: \t\tInitialized\n");
	fflush(stdout);

	/**
	 * Allow reuse of address, when the server shuts down.
	 */
	if ( (setsockopt(server_socket, SOL_SOCKET, SO_REUSEADDR, &on, 
					sizeof(on))) < 0 ){
		server_error(strerror(errno), server_socket, l);
	}

	printf("Reuse Port %d: \tEnabled\n", port);
	fflush(stdout);

	memset((char *) &server_addr, '\0', sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(port);

	printf("Ip Address: \t\t%s\n", inet_ntoa(server_addr.sin_addr));
	fflush(stdout);

	/**
	 * Bind address.
	 */
	if ( (bind(server_socket, (struct sockaddr *) &server_addr, 
			sizeof(server_addr))) < 0 ) {
		server_error(strerror(errno), server_socket, l);
	}

	printf("Binding: \t\tSuccess\n");
	fflush(stdout);

	/**
	 * Listen on the server socket for connections
	 */
	if ( (listen(server_socket, 10)) < 0) {
		server_error(strerror(errno), server_socket, l);
	}

	printf("Listen: \t\tSuccess\n\n");
	fflush(stdout);

	/**
	 * Attributes for the threads we will create when a new client connects.
	 */
	pthread_attr_init(&pthread_attr);
	pthread_attr_setdetachstate(&pthread_attr, PTHREAD_CREATE_DETACHED);
	pthread_attr_setstacksize(&pthread_attr, 524288);

	printf("Server is now waiting for clients to connect ...\n\n");
	fflush(stdout);

	/**
	 * Create commandline, such that we can do simple commands on the server.
	 */
	if ( (pthread_create(&pthread_id, &pthread_attr, cmdline, NULL)) < 0 ){
		server_error(strerror(errno), server_socket, l);
	}

	/**
	 * Do not wait for the thread to terminate.
	 */
	pthread_detach(pthread_id);

	while (1) {
		client_length = sizeof(client_addr);
		
		/**
		 * If a client connects, we observe it here.
		 */
		if ( (client_socket = accept(server_socket, 
				(struct sockaddr *) &client_addr,
				&client_length)) < 0) {
			server_error(strerror(errno), server_socket, l);
		}

		/**
		 * Save some information about the client, which we will
		 * later use to identify him with.
		 */
		char *temp = (char *) inet_ntoa(client_addr.sin_addr);
		char *addr = (char *) malloc( sizeof(char)*(strlen(temp)+1) );
		if (addr == NULL) {
			server_error(strerror(errno), server_socket, l);
			break;
		}
		memset(addr, '\0', strlen(temp)+1);
	    memcpy(addr, temp, strlen(temp));	

		ws_client *n = client_new(client_socket, addr);

		/**
		 * Create client thread, which will take care of handshake and all
		 * communication with the client.
		 */
		if ( (pthread_create(&pthread_id, &pthread_attr, handleClient, 
						(void *) n)) < 0 ){
			server_error(strerror(errno), server_socket, l);
		}

		pthread_detach(pthread_id);
	}

	list_free(l);
	l = NULL;
	close(server_socket);
	pthread_attr_destroy(&pthread_attr);
	return EXIT_SUCCESS;
}
Пример #6
0
int main(int argc, char **argv)
{
  struct option long_options[] = {
    // These options don't set a flag
    {"help",                      no_argument,       NULL, 'h'},
    {"contention-manager",        required_argument, NULL, 'c'},
    {"duration",                  required_argument, NULL, 'd'},
    {"irrevocable-percent",       required_argument, NULL, 'i'},
    {"num-threads",               required_argument, NULL, 'n'},
    {NULL, 0, NULL, 0}
  };

  int i, c;
  unsigned long aborts, aborts_1, aborts_2,
    aborts_locked_read, aborts_locked_write,
    aborts_validate_read, aborts_validate_write, aborts_validate_commit,
    aborts_invalid_memory, aborts_killed,
    locked_reads_ok, locked_reads_failed, max_retries;
  thread_data_t *td;
  pthread_t *threads;
  pthread_attr_t attr;
  struct timespec timeout;
  int duration = DEFAULT_DURATION;
  int irrevocable_percent = DEFAULT_IRREVOCABLE_PERCENT;
  int nb_threads = DEFAULT_NB_THREADS;
  char *cm = NULL;

  while(1) {
    i = 0;
    c = getopt_long(argc, argv, "hc:d:i:n:", long_options, &i);

    if(c == -1)
      break;

    if(c == 0 && long_options[i].flag == 0)
      c = long_options[i].val;

    switch(c) {
     case 0:
       /* Flag is automatically set */
       break;
     case 'h':
       printf("irrevocability -- STM stress test "
              "\n"
              "Usage:\n"
              "  irrevocability [options...]\n"
              "\n"
              "Options:\n"
              "  -h, --help\n"
              "        Print this message\n"
              "  -c, --contention-manager <string>\n"
              "        Contention manager for resolving conflicts (default=suicide)\n"
              "  -d, --duration <int>\n"
              "        Test duration in milliseconds (0=infinite, default=" XSTR(DEFAULT_DURATION) ")\n"
              "  -i, --irrevocable-percent <int>\n"
              "         (default=" XSTR(DEFAULT_IRREVOCABLE_PERCENT) ")\n"
              "  -n, --num-threads <int>\n"
              "        Number of threads (default=" XSTR(DEFAULT_NB_THREADS) ")\n"
         );
       exit(0);
     case 'c':
       cm = optarg;
       break;
     case 'd':
       duration = atoi(optarg);
       break;
     case 'n':
       nb_threads = atoi(optarg);
       break;
     case 'i':
       irrevocable_percent = atoi(optarg);
       break;
     case '?':
       printf("Use -h or --help for help\n");
       exit(0);
     default:
       exit(1);
    }
  }

  assert(duration >= 0);
  assert(nb_threads > 0);
  assert(irrevocable_percent >= 0 && irrevocable_percent <= 100);

  printf("CM           : %s\n", (cm == NULL ? "DEFAULT" : cm));
  printf("Duration     : %d\n", duration);
  printf("Irrevocable  : %d%%\n", irrevocable_percent);
  printf("Nb threads   : %d\n", nb_threads);

  for (i = 0; i < NB_ELEMENTS; i++)
    data[i] = 0;

  /* Init STM */
  printf("Initializing STM\n");
  stm_init();

  /* Set contention manager */
  if (cm != NULL) {
    if (stm_set_parameter("cm_policy", cm) == 0)
      printf("WARNING: cannot set contention manager \"%s\"\n", cm);
  }

  printf("int/long/ptr/word size: %d/%d/%d/%d\n",
         (int)sizeof(int),
         (int)sizeof(long),
         (int)sizeof(void *),
         (int)sizeof(stm_word_t));

  stop = 0;

  printf("TESTING CONCURRENT UPDATES...\n");

  timeout.tv_sec = duration / 1000;
  timeout.tv_nsec = (duration % 1000) * 1000000;

  if ((td = (thread_data_t *)malloc(nb_threads * sizeof(thread_data_t))) == NULL) {
    perror("malloc");
    exit(1);
  }
  if ((threads = (pthread_t *)malloc(nb_threads * sizeof(pthread_t))) == NULL) {
    perror("malloc");
    exit(1);
  }
  pthread_attr_init(&attr);
  pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
  for (i = 0; i < nb_threads; i++) {
    td[i].nb_aborts = 0;
    td[i].nb_aborts_1 = 0;
    td[i].nb_aborts_2 = 0;
    td[i].nb_aborts_locked_read = 0;
    td[i].nb_aborts_locked_write = 0;
    td[i].nb_aborts_validate_read = 0;
    td[i].nb_aborts_validate_write = 0;
    td[i].nb_aborts_validate_commit = 0;
    td[i].nb_aborts_invalid_memory = 0;
    td[i].nb_aborts_killed = 0;
    td[i].locked_reads_ok = 0;
    td[i].locked_reads_failed = 0;
    td[i].max_retries = 0;
    td[i].irrevocable_percent = irrevocable_percent;
    if (pthread_create(&threads[i], &attr, test, (void *)(&td[i])) != 0) {
      fprintf(stderr, "Error creating thread\n");
      exit(1);
    }
  }
  pthread_attr_destroy(&attr);
  nanosleep(&timeout, NULL);
  printf("STOPPING...\n");
  stop = 1;
  for (i = 0; i < nb_threads; i++) {
    if (pthread_join(threads[i], NULL) != 0) {
      fprintf(stderr, "Error waiting for thread completion\n");
      exit(1);
    }
  }

  printf("PASSED\n");
  printf("Number of successful irrevocable-serial executions   : %ld\n", nb_irrevocable_serial);
  printf("Number of successful irrevocable-parallel executions : %ld\n", nb_irrevocable_parallel);

  aborts = 0;
  aborts_1 = 0;
  aborts_2 = 0;
  aborts_locked_read = 0;
  aborts_locked_write = 0;
  aborts_validate_read = 0;
  aborts_validate_write = 0;
  aborts_validate_commit = 0;
  aborts_invalid_memory = 0;
  aborts_killed = 0;
  locked_reads_ok = 0;
  locked_reads_failed = 0;
  max_retries = 0;
  for (i = 0; i < nb_threads; i++) {
    printf("Thread %d\n", i);
    printf("  #aborts     : %lu\n", td[i].nb_aborts);
    printf("    #lock-r   : %lu\n", td[i].nb_aborts_locked_read);
    printf("    #lock-w   : %lu\n", td[i].nb_aborts_locked_write);
    printf("    #val-r    : %lu\n", td[i].nb_aborts_validate_read);
    printf("    #val-w    : %lu\n", td[i].nb_aborts_validate_write);
    printf("    #val-c    : %lu\n", td[i].nb_aborts_validate_commit);
    printf("    #inv-mem  : %lu\n", td[i].nb_aborts_invalid_memory);
    printf("    #killed   : %lu\n", td[i].nb_aborts_killed);
    printf("  #aborts>=1  : %lu\n", td[i].nb_aborts_1);
    printf("  #aborts>=2  : %lu\n", td[i].nb_aborts_2);
    printf("  #lr-ok      : %lu\n", td[i].locked_reads_ok);
    printf("  #lr-failed  : %lu\n", td[i].locked_reads_failed);
    printf("  Max retries : %lu\n", td[i].max_retries);
    aborts += td[i].nb_aborts;
    aborts_1 += td[i].nb_aborts_1;
    aborts_2 += td[i].nb_aborts_2;
    aborts_locked_read += td[i].nb_aborts_locked_read;
    aborts_locked_write += td[i].nb_aborts_locked_write;
    aborts_validate_read += td[i].nb_aborts_validate_read;
    aborts_validate_write += td[i].nb_aborts_validate_write;
    aborts_validate_commit += td[i].nb_aborts_validate_commit;
    aborts_invalid_memory += td[i].nb_aborts_invalid_memory;
    aborts_killed += td[i].nb_aborts_killed;
    locked_reads_ok += td[i].locked_reads_ok;
    locked_reads_failed += td[i].locked_reads_failed;
    if (max_retries < td[i].max_retries)
      max_retries = td[i].max_retries;
  }
  printf("Duration      : %d (ms)\n", duration);
  printf("#aborts       : %lu (%f / s)\n", aborts, aborts * 1000.0 / duration);
  printf("  #lock-r     : %lu (%f / s)\n", aborts_locked_read, aborts_locked_read * 1000.0 / duration);
  printf("  #lock-w     : %lu (%f / s)\n", aborts_locked_write, aborts_locked_write * 1000.0 / duration);
  printf("  #val-r      : %lu (%f / s)\n", aborts_validate_read, aborts_validate_read * 1000.0 / duration);
  printf("  #val-w      : %lu (%f / s)\n", aborts_validate_write, aborts_validate_write * 1000.0 / duration);
  printf("  #val-c      : %lu (%f / s)\n", aborts_validate_commit, aborts_validate_commit * 1000.0 / duration);
  printf("  #inv-mem    : %lu (%f / s)\n", aborts_invalid_memory, aborts_invalid_memory * 1000.0 / duration);
  printf("  #killed     : %lu (%f / s)\n", aborts_killed, aborts_killed * 1000.0 / duration);
  printf("#aborts>=1    : %lu (%f / s)\n", aborts_1, aborts_1 * 1000.0 / duration);
  printf("#aborts>=2    : %lu (%f / s)\n", aborts_2, aborts_2 * 1000.0 / duration);
  printf("#lr-ok        : %lu (%f / s)\n", locked_reads_ok, locked_reads_ok * 1000.0 / duration);
  printf("#lr-failed    : %lu (%f / s)\n", locked_reads_failed, locked_reads_failed * 1000.0 / duration);
  printf("Max retries   : %lu\n", max_retries);

  /* Cleanup STM */
  stm_exit();

  return 0;
}
Пример #7
0
/******* web服务器程序入口函数 *******/
int main(int argc, char const *argv[])
{
	int    			   conn_sock;
	struct epoll_event ev;
	struct epoll_event events[MAXEVENTS];
	struct sockaddr_in server_addr;
	struct sockaddr_in client_addr;
	socklen_t          addrlen;
	pthread_attr_t     pthread_attr_detach;
	_epollfd_connfd    epollfd_connfd;
	pthread_t          tid;

	if(argc != 2){
		printf("Usage: %s <config_path>\n", argv[0]);
		exit(-1);
	}
	//Is configure existed?
	if(-1 == going_is_file_existed(argv[1])){
		perror("going_is_file_existed.");
		exit(-1);
	}
	//parse configure
	if(-1 == going_parse_config(argv[1])){
		printf("going_parse_config error!\n");
		exit(-1);
	}

	//创建监听套接字
	int listen_fd = going_socket(AF_INET, SOCK_STREAM, 0);
	//设置监听套接字为非阻塞模式
	going_set_nonblocking(listen_fd);
	//对套接字设置SO_REUSEADDR选项
	going_set_reuse_addr(listen_fd);


	//通过服务名和协议名获得相应的知名端口
	//struct servent* pservent = going_getservbyname("http", "tcp");
	//uint16_t listen_port = pservent->s_port;
	
	uint16_t listen_port = 80;

	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_port = (listen_port);
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);

	going_bind(listen_fd, (struct sockaddr*)&server_addr, sizeof(server_addr));
	going_listen(listen_fd, MAX_BACKLOG);

	// 创建epoll文件描述符
	int epollfd = going_epoll_create(MAXEVENTS);

	// 设置要处理的事件类型
	ev.events = EPOLLIN;
	// 设置与要处理的事件相关的文件描述符
	ev.data.fd = listen_fd;
	// 将监听事件加入epoll中
	going_epoll_add(epollfd, listen_fd, &ev);

	//设置线程属性为detach
	pthread_attr_init(&pthread_attr_detach);
	pthread_attr_setdetachstate(&pthread_attr_detach, PTHREAD_CREATE_DETACHED);

	for(;;){
		// 无限等待直到有描述符就绪
		int nfds = going_epoll_wait(epollfd, events, MAXEVENTS, -1);
		// 若going_epoll_wait被中断则重新调用该函数
		if(nfds == -1 && errno == EINTR)
			continue;

		for(int n = 0; n != nfds; ++n){
			// 处理监听套接字触发的事件
			if(events[n].data.fd == listen_fd){
				conn_sock = going_accept(listen_fd, (struct sockaddr *)&client_addr, &addrlen);
				// 设置新连接上的套接字为非阻塞模式
				going_set_nonblocking(conn_sock);
				// 设置读事件和ET模式
				ev.events = EPOLLIN | EPOLLET;
				ev.data.fd = conn_sock;
				// 将监听事件添加到epoll
				going_epoll_add(epollfd, conn_sock, &ev);
			}else{
				epollfd_connfd.epollfd = epollfd;
				epollfd_connfd.connfd = events[n].data.fd;
				ev.data.fd = conn_sock;
				// epoll不再监听这个事件
				going_epoll_del(epollfd, conn_sock, &ev);
				// 处理连接
				pthread_create(&tid, &pthread_attr_detach, &going_thread_func, (void *)&epollfd_connfd);
			}
		}
	}

	pthread_attr_destroy(&pthread_attr_detach);

	// 关闭监听描述符
	close(listen_fd);
	return 0;
}
Пример #8
0
gboolean
mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid)
{
	pthread_attr_t attr;
	pthread_t thread;
	gint res;
	gsize set_stack_size;

	res = pthread_attr_init (&attr);
	if (res != 0)
		g_error ("%s: pthread_attr_init failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);

	if (stack_size)
		set_stack_size = *stack_size;
	else
		set_stack_size = 0;

#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
	if (set_stack_size == 0) {
#if HAVE_VALGRIND_MEMCHECK_H
		if (RUNNING_ON_VALGRIND)
			set_stack_size = 1 << 20;
		else
			set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
#else
		set_stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
#endif
	}

#ifdef PTHREAD_STACK_MIN
	if (set_stack_size < PTHREAD_STACK_MIN)
		set_stack_size = PTHREAD_STACK_MIN;
#endif

	res = pthread_attr_setstacksize (&attr, set_stack_size);
	if (res != 0)
		g_error ("%s: pthread_attr_setstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */

	/* Actually start the thread */
	res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
	if (res) {
		res = pthread_attr_destroy (&attr);
		if (res != 0)
			g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);

		return FALSE;
	}

	if (tid)
		*tid = thread;

	if (stack_size) {
		res = pthread_attr_getstacksize (&attr, stack_size);
		if (res != 0)
			g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
	}

	res = pthread_attr_destroy (&attr);
	if (res != 0)
		g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);

	return TRUE;
}
Пример #9
0
/*
 *	Spawn a new thread, and place it in the thread pool.
 *
 *	The thread is started initially in the blocked state, waiting
 *	for the semaphore.
 */
static THREAD_HANDLE *spawn_thread(time_t now)
{
	int rcode;
	THREAD_HANDLE *handle;
	pthread_attr_t attr;

	/*
	 *	Ensure that we don't spawn too many threads.
	 */
	if (thread_pool.total_threads >= thread_pool.max_threads) {
		DEBUG2("Thread spawn failed.  Maximum number of threads (%d) already running.", thread_pool.max_threads);
		return NULL;
	}

	/*
	 *	Allocate a new thread handle.
	 */
	handle = (THREAD_HANDLE *) rad_malloc(sizeof(THREAD_HANDLE));
	memset(handle, 0, sizeof(THREAD_HANDLE));
	handle->prev = NULL;
	handle->next = NULL;
	handle->thread_num = thread_pool.max_thread_num++;
	handle->request_count = 0;
	handle->status = THREAD_RUNNING;
	handle->timestamp = time(NULL);

	/*
	 *	Initialize the thread's attributes to detached.
	 *
	 *	We could call pthread_detach() later, but if the thread
	 *	exits between the create & detach calls, it will need to
	 *	be joined, which will never happen.
	 */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	/*
	 *	Create the thread detached, so that it cleans up it's
	 *	own memory when it exits.
	 *
	 *	Note that the function returns non-zero on error, NOT
	 *	-1.  The return code is the error, and errno isn't set.
	 */
	rcode = pthread_create(&handle->pthread_id, &attr,
			request_handler_thread, handle);
	if (rcode != 0) {
		radlog(L_ERR, "Thread create failed: %s",
		       strerror(rcode));
		return NULL;
	}
	pthread_attr_destroy(&attr);

	/*
	 *	One more thread to go into the list.
	 */
	thread_pool.total_threads++;
	DEBUG2("Thread spawned new child %d. Total threads in pool: %d",
			handle->thread_num, thread_pool.total_threads);

	/*
	 *	Add the thread handle to the tail of the thread pool list.
	 */
	if (thread_pool.tail) {
		thread_pool.tail->next = handle;
		handle->prev = thread_pool.tail;
		thread_pool.tail = handle;
	} else {
		rad_assert(thread_pool.head == NULL);
		thread_pool.head = thread_pool.tail = handle;
	}

	/*
	 *	Update the time we last spawned a thread.
	 */
	thread_pool.time_last_spawned = now;

	/*
	 *	And return the new handle to the caller.
	 */
	return handle;
}
Пример #10
0
/*!
	\brief 'true' main of the program.

	It must be in a separate function because:
	- if we're in 'console' mode, we have to put the main thread waiting for a Ctrl+C
	(in order to be able to stop everything)
	- if we're in daemon mode, the main program must terminate and a new child must be 
	created in order to create the daemon

	\param ptr: it keeps the main socket handler (what's called 'sockmain' in the main() ), that
	represents the socket used in the main connection. It is a 'void *' just because pthreads
	want this format.
*/
void main_passive(void *ptr)
{
char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
SOCKET sockctrl;				// keeps the socket ID for this control connection
struct sockaddr_storage from;	// generic sockaddr_storage variable
socklen_t fromlen;				// keeps the length of the sockaddr_storage variable
SOCKET sockmain;

#ifndef WIN32
	pid_t pid;
#endif

	sockmain= *((SOCKET *) ptr);

	// Delete the pointer (which has been allocated in the main)
	free(ptr);

	// Initialize errbuf
	memset(errbuf, 0, sizeof(errbuf) );

	// main thread loop
	while (1)
	{
#ifdef WIN32
	pthread_t threadId;					// Pthread variable that keeps the thread structures
	pthread_attr_t detachedAttribute;
#endif
	struct daemon_slpars *pars;			// parameters needed by the daemon_serviceloop()

		// Connection creation
		fromlen = sizeof(struct sockaddr_storage);

		sockctrl= accept(sockmain, (struct sockaddr *) &from, &fromlen);
		
		if (sockctrl == -1)
		{
			// The accept() call can return this error when a signal is catched
			// In this case, we have simply to ignore this error code
			// Stevens, pg 124
#ifdef WIN32
			if (WSAGetLastError() == WSAEINTR)
#else
			if (errno == EINTR)
#endif
				continue;

			// Don't check for errors here, since the error can be due to the fact that the thread 
			// has been killed
			sock_geterror("accept(): ", errbuf, PCAP_ERRBUF_SIZE);
			SOCK_ASSERT(errbuf, 1);
			continue;
		}

		// checks if the connecting host is among the ones allowed
		if (sock_check_hostlist(hostlist, RPCAP_HOSTLIST_SEP, &from, errbuf, PCAP_ERRBUF_SIZE) < 0 )
		{
			rpcap_senderror(sockctrl, errbuf, PCAP_ERR_HOSTNOAUTH, NULL);
			sock_close(sockctrl, NULL, 0);
			continue;
		}


#ifdef WIN32
		// in case of passive mode, this variable is deallocated by the daemon_serviceloop()
		pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) );
		if (pars == NULL)
		{
			snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
			continue;
		}

		pars->sockctrl= sockctrl;
		pars->activeclose= 0;		// useless in passive mode
		pars->isactive= 0;
		pars->nullAuthAllowed= nullAuthAllowed;

		/* GV we need this to create the thread as detached. */
		/* GV otherwise, the thread handle is not destroyed  */
		pthread_attr_init(&detachedAttribute); 
		pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);
		if ( pthread_create( &threadId, &detachedAttribute, (void *) &daemon_serviceloop, (void *) pars) )
		{
			SOCK_ASSERT("Error creating the child thread", 1);
			pthread_attr_destroy(&detachedAttribute);
			continue;
		}
		pthread_attr_destroy(&detachedAttribute);

#else
		if ( (pid= fork() ) == 0)	// I am the child
		{
			// in case of passive mode, this variable is deallocated by the daemon_serviceloop()
			pars= (struct daemon_slpars *) malloc ( sizeof(struct daemon_slpars) );
			if (pars == NULL)
			{
				snprintf(errbuf, PCAP_ERRBUF_SIZE, "malloc() failed: %s", pcap_strerror(errno));
				exit(0);
			}

			pars->sockctrl= sockctrl;
			pars->activeclose= 0;		// useless in passive mode
			pars->isactive= 0;
			pars->nullAuthAllowed= nullAuthAllowed;

			// Close the main socket (must be open only in the parent)
			closesocket(sockmain);

			daemon_serviceloop( (void *) pars);
			exit(0);
		}

		// I am the parent
		// Close the childsocket (must be open only in the child)
		closesocket(sockctrl);
#endif

		// loop forever, until interrupted
	}
}
Пример #11
0
int
OverlapDriver(void) {

  fprintf(stderr, "OverlapDriver()--\n");

  pthread_t      *thread_id = new pthread_t   [G.Num_PThreads];
  fprintf(stderr, "OverlapDriver()--  WA\n");
  Work_Area_t    *thread_wa = new Work_Area_t [G.Num_PThreads];

  fprintf(stderr, "OverlapDriver()--  gkpStore\n");
  gkStore        *gkpStore  = gkStore::gkStore_open(G.Frag_Store_Path);

  pthread_attr_t  attr;

  pthread_attr_init(&attr);
  pthread_attr_setstacksize(&attr, THREAD_STACKSIZE);
  pthread_mutex_init(&Write_Proto_Mutex, NULL);

  for (uint32 i=0;  i<G.Num_PThreads;  i++) {
    fprintf(stderr, "OverlapDriver()--  Initialize_Work_Area %u\n", i);
    Initialize_Work_Area(thread_wa+i, i, gkpStore);
  }

  fprintf(stderr, "OverlapDriver()--  Initialized\n");

  //  Command line options are Lo_Hash_Frag and Hi_Hash_Frag
  //  Command line options are Lo_Old_Frag and Hi_Old_Frag

  if (G.bgnHashID < 1)
    G.bgnHashID = 1;

  if (gkpStore->gkStore_getNumReads() < G.endHashID)
    G.endHashID = gkpStore->gkStore_getNumReads();


  //  Note distinction between the local bgn/end and the global G.bgn/G.end.

  uint32  bgnHashID = G.bgnHashID;
  uint32  endHashID = G.bgnHashID + G.Max_Hash_Strings - 1;  //  Inclusive!

  //  Iterate over read blocks, build a hash table, then search in threads.

  //fprintf(stderr, "OverlapDriver()--  Loop top\n");

  while (bgnHashID < G.endHashID) {
    if (endHashID > G.endHashID)
      endHashID = G.endHashID;

    assert(0          <  bgnHashID);
    assert(bgnHashID  <= endHashID);
    assert(endHashID  <= gkpStore->gkStore_getNumReads());

    //  Load as much as we can.  If we load less than expected, the endHashID is updated to reflect
    //  the last read loaded.

    //fprintf(stderr, "OverlapDriver()--  Build_Hash_Index\n");

    endHashID = Build_Hash_Index(gkpStore, bgnHashID, endHashID);

    //fprintf(stderr, "Index built.\n");

    //  Decide the range of reads to process.  No more than what is loaded in the table.

    if (G.bgnRefID < 1)
      G.bgnRefID = 1;

    if (G.endRefID > gkpStore->gkStore_getNumReads())
      G.endRefID = gkpStore->gkStore_getNumReads();

    G.curRefID = G.bgnRefID;

    //  The old version used to further divide the ref range into blocks of at most
    //  Max_Reads_Per_Batch so that those reads could be loaded into core.  We don't
    //  need to do that anymore.

    G.perThread = 1 + (G.endRefID - G.bgnRefID) / G.Num_PThreads / 8;

    fprintf(stderr, "\n");
    fprintf(stderr, "Range: %u-%u.  Store has %u reads.\n",
            G.bgnRefID, G.endRefID, gkpStore->gkStore_getNumReads());
    fprintf(stderr, "Chunk: "F_U32" reads/thread -- (G.endRefID="F_U32" - G.bgnRefID="F_U32") / G.Num_PThreads="F_U32" / 8\n",
            G.perThread, G.endRefID, G.bgnRefID, G.Num_PThreads);

    fprintf(stderr, "\n");
    fprintf(stderr, "Starting "F_U32"-"F_U32" with "F_U32" per thread\n", G.bgnRefID, G.endRefID, G.perThread);
    fprintf(stderr, "\n");

    for (uint32 i=0; i<G.Num_PThreads; i++) {

      //  Initialize each thread, reset the current position.

      thread_wa[i].bgnID = G.curRefID;
      thread_wa[i].endID = thread_wa[i].bgnID + G.perThread - 1;

      G.curRefID = thread_wa[i].endID + 1;

      if (G.endRefID > G.endRefID)
        G.endRefID = G.endRefID;

      int status = pthread_create(thread_id+i, &attr, Process_Overlaps, thread_wa+i);

      if (status != 0)
        fprintf(stderr, "pthread_create error:  %s\n", strerror(status)), exit(1);
    }

    //  The master thread just sits here and waits.

    for (uint32 i=0; i<G.Num_PThreads; i++) {
      int status = pthread_join(thread_id[i], NULL);
      if (status != 0)
        fprintf(stderr, "pthread_join error: %s\n", strerror(status)), exit(1);
    }

    //  Clear out the hash table.  This stuff is allocated in Build_Hash_Index

    delete [] basesData;  basesData = NULL;
    delete [] qualsData;  qualsData = NULL;
    delete [] nextRef;    nextRef   = NULL;

    //  This one could be left allocated, except for the last iteration.

    delete [] Extra_Ref_Space;  Extra_Ref_Space = NULL;  Max_Extra_Ref_Space = 0;

    //  Prepare for another hash table iteration.
    bgnHashID = endHashID + 1;
    endHashID = bgnHashID + G.Max_Hash_Strings - 1;  //  Inclusive!
  }

  pthread_mutex_destroy(&Write_Proto_Mutex);
  pthread_attr_destroy(&attr);

  gkpStore->gkStore_close();

  for (uint32 i=0;  i<G.Num_PThreads;  i++)
    Delete_Work_Area(thread_wa + i);

  delete [] thread_wa;
  delete [] thread_id;

  return  0;
}
Пример #12
0
void main_startup(void)
{
char errbuf[PCAP_ERRBUF_SIZE + 1];	// keeps the error string, prior to be printed
struct addrinfo *addrinfo;				// keeps the addrinfo chain; required to open a new socket
int i;
#ifdef WIN32
	pthread_t threadId;					// Pthread variable that keeps the thread structures
	pthread_attr_t detachedAttribute;	// PThread attribute needed to create the thread as detached
#else
	pid_t pid;
#endif

	i= 0;
	addrinfo= NULL;
	memset(errbuf, 0, sizeof(errbuf) );

	// Starts all the active threads
	while ( (activelist[i].address[0] != 0) && (i < MAX_ACTIVE_LIST) )
	{
		activelist[i].ai_family= mainhints.ai_family;
		
#ifdef WIN32
		/* GV we need this to create the thread as detached. */
		/* GV otherwise, the thread handle is not destroyed  */
		pthread_attr_init(&detachedAttribute); 
		pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);

		if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_active, (void *) &activelist[i]) )
		{
			SOCK_ASSERT("Error creating the active child thread", 1);
			pthread_attr_destroy(&detachedAttribute);
			continue;
		}
		pthread_attr_destroy(&detachedAttribute);
#else
		if ( (pid= fork() ) == 0)	// I am the child
		{
			main_active( (void *) &activelist[i]);
			exit(0);
		}
#endif
		i++;
	}

	/*
		The code that manages the active connections is not blocking; 
		vice versa, the code that manages the passive connection is blocking.
		So, if the user do not want to run in passive mode, we have to block
		the main thread here, otherwise the program ends and all threads
		are stopped.

		WARNING: this means that in case we have only active mode, the program does
		not terminate even if all the child thread terminates. The user has always to
		press Ctrl+C (or send a SIGTERM) to terminate the program.
	*/

	if (passivemode)
	{
	struct addrinfo *tempaddrinfo;

		// Do the work
		if (sock_initaddress((address[0]) ? address : NULL, port, &mainhints, &addrinfo, errbuf, PCAP_ERRBUF_SIZE) == -1)
		{
			SOCK_ASSERT(errbuf, 1);
			return;
		}

		tempaddrinfo= addrinfo;

		while (tempaddrinfo)
		{
		SOCKET *socktemp;

			if ( (sockmain= sock_open(tempaddrinfo, SOCKOPEN_SERVER, SOCKET_MAXCONN, errbuf, PCAP_ERRBUF_SIZE)) == -1)
			{
				SOCK_ASSERT(errbuf, 1);
				tempaddrinfo= tempaddrinfo->ai_next;
				continue;
			}

			// This trick is needed in order to allow the child thread to save the 'sockmain' variable
			// withouth getting it overwritten by the sock_open, in case we want to open more than one waiting sockets
			// For instance, the pthread_create() will accept the socktemp variable, and it will deallocate immediately that variable
			socktemp= (SOCKET *) malloc (sizeof (SOCKET));
			if (socktemp == NULL)
				exit(0);

			*socktemp= sockmain;

#ifdef WIN32
			/* GV we need this to create the thread as detached. */
			/* GV otherwise, the thread handle is not destroyed  */
			pthread_attr_init(&detachedAttribute); 
			pthread_attr_setdetachstate(&detachedAttribute, PTHREAD_CREATE_DETACHED);

			if ( pthread_create( &threadId, &detachedAttribute, (void *) &main_passive, (void *) socktemp ) )
			{
				SOCK_ASSERT("Error creating the passive child thread", 1);
				pthread_attr_destroy(&detachedAttribute);
				continue;
			}

			pthread_attr_destroy(&detachedAttribute);
#else
			if ( (pid= fork() ) == 0)	// I am the child
			{
				main_passive( (void *) socktemp);
				return;
			}
#endif
			tempaddrinfo= tempaddrinfo->ai_next;
		}

		freeaddrinfo(addrinfo);
	}

	// All the previous calls are no blocking, so the main line of execution goes here
	// and I have to avoid that the program terminates
	while (1)
		pthread_suspend(10*60*1000); // it wakes up every 10 minutes; it seems to me reasonable
}
Пример #13
0
/*
The main program creates threads which do all the work and then 
print out the result upon completion. Before creating the threads, 
the input data is created. Since all threads update a shared structure, 
we need a mutex for mutual exclusion. The main thread need to wait for 
all threads to complete, it waits for each one of the threads. We specify 
a thread attribute value that allow the main thread to join with the threads 
it creates. Note also that we free up handles when they are no longer needed.
*/
int main(int argc, char *argv[])
{
	int i, ret, len;
	double *a, *b;
	void *status;
	pthread_attr_t attr;

	/* Assign storage and initialize values */
	len = VECLEN * NUMTHRDS;
	a = (double *) calloc (1, sizeof(double) * len);
	b = (double *) calloc (1, sizeof(double) * len);
	for (i = 0; i < len; ++i)
	{
		a[i] = 1;
		b[i] = a[i];
	}

	dotstr.veclen = VECLEN;
	dotstr.a = a;
	dotstr.b = b;
	dotstr.sum = 0;

	/* Create thread to perform the dotproduct */
	pthread_mutex_init(&mutexsum, NULL);
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

	for (i = 0; i < NUMTHRDS; ++i)
	{
	/* Each thread works on a different set of data.
	 * The offset is specified by 'i'. The size of 
	 * the data for each thread is indicated by VECLEN.
	 */
		ret = pthread_create(thrd + i, &attr, dotprod, (void *)i);
		if (ret)
		{
			printf("ERROR; return code from pthread_create(): %d\r\n", ret);
			exit(-1);
		}
	}
	pthread_attr_destroy(&attr);

	/* Wait on the other threads */
	status = NULL;
	for (i = 0; i < NUMTHRDS; ++i)
	{
		ret = pthread_join(thrd[i], &status);
		if (ret)
		{
			printf("ERROR; return code from pthread_create(): %d\r\n", ret);
			exit(-1);
		}
	}

	/* After joining, print out the results and cleanup */
	printf("Sum = %.2lf\r\n", dotstr.sum);
	free(a);
	a = NULL;
	free(b);
	b = NULL;
	pthread_mutex_destroy(&mutexsum);
	pthread_exit(NULL);
}
Пример #14
0
/*! \fn main(int argc, char *argv[])
 *  \brief The Cactid program entry point
 *  \param argc The number of arguments passed to the function plus one (+1)
 *  \param argv An array of the command line arguments
 *
 *  The Cactid entry point.  This function performs the following tasks.
 *  1) Processes command line input parameters
 *  2) Processes the Cactid configuration file to obtain database access information
 *  3) Process runtime parameters from the settings table
 *  4) Initialize the runtime threads and mutexes for the threaded environment
 *  5) Initialize Net-SNMP, MySQL, and the PHP Script Server (if required)
 *  6) Spawns X threads in order to process hosts
 *  7) Loop until either all hosts have been processed or until the poller runtime
 *     has been exceeded
 *  8) Close database and free variables
 *  9) Log poller process statistics if required
 *  10) Exit
 *
 *  Note: Command line runtime parameters override any database settings.
 *
 *  \return 0 if SUCCESS, or -1 if FAILED
 *
 */
int main(int argc, char *argv[]) {
	struct timeval now;
	char *conf_file = NULL;
	double begin_time, end_time, current_time;
	int poller_interval;
	int num_rows;
	int device_counter = 0;
	int poller_counter = 0;
	int last_active_threads = 0;
	long int EXTERNAL_THREAD_SLEEP = 100000;
	long int internal_thread_sleep;
	time_t nowbin;
	struct tm now_time;
	struct tm *now_ptr;

	pthread_t* threads = NULL;
	pthread_attr_t attr;

	int* ids = NULL;
	MYSQL mysql;
	MYSQL_RES *result = NULL;
	MYSQL_ROW mysql_row;
	int canexit = 0;
	int host_id;
	int i;
	int mutex_status = 0;
	int thread_status = 0;

	UNUSED_PARAMETER(argc);		/* we operate strictly with argv */

	/* establish php processes and initialize space */
	php_processes = (php_t*) calloc(MAX_PHP_SERVERS, sizeof(php_t));
	for (i = 0; i < MAX_PHP_SERVERS; i++) {
		php_processes[i].php_state = PHP_BUSY;
	}

	/* set start time for cacti */
	begin_time = get_time_as_double();

	/* get time for poller_output table */
	if (time(&nowbin) == (time_t) - 1) {
		die("ERROR: Could not get time of day from time()\n");
	}
	localtime_r(&nowbin,&now_time);
	now_ptr = &now_time;

	if (strftime(start_datetime, sizeof(start_datetime), "%Y-%m-%d %H:%M:%S", now_ptr) == (size_t) 0) {
		die("ERROR: Could not get string from strftime()\n");
	}

	/* set default verbosity */
	set.log_level = POLLER_VERBOSITY_LOW;

	/* get static defaults for system */
	config_defaults();

	/*! ----------------------------------------------------------------
	 * PROCESS COMMAND LINE
	 *
	 * Run through the list of ARGV words looking for parameters we
	 * know about. Most have two flavors (-C + --conf), and many
	 * themselves take a parameter.
	 *
	 * These parameters can be structured in two ways:
	 *
	 *	--conf=FILE		both parts in one argv[] string
	 *	--conf FILE		two separate argv[] strings
	 *
	 * We set "arg" to point to "--conf", and "opt" to point to FILE.
	 * The helper routine
	 *
	 * In each loop we set "arg" to next argv[] string, then look
	 * to see if it has an equal sign. If so, we split it in half
	 * and point to the option separately.
	 *
	 * NOTE: most direction to the program is given with dash-type
	 * parameters, but we also allow standalone numeric device IDs
	 * in "first last" format: this is how poller.php calls this
	 * program.
	 */

	/* initialize some global variables */
	set.start_host_id = -1;
	set.end_host_id   = -1;
	set.php_initialized = FALSE;
	set.logfile_processed = FALSE;
	set.parent_fork = CACTID_PARENT;

	for (argv++; *argv; argv++) {
		char	*arg = *argv;
		char	*opt = strchr(arg, '=');	/* pick off the =VALUE part */

		if (opt) *opt++ = '\0';

		if (STRIMATCH(arg, "-f") ||
			STRIMATCH(arg, "--first")) {
			if (HOSTID_DEFINED(set.start_host_id)) {
				die("ERROR: %s can only be used once", arg);
			}

			set.start_host_id = atoi(opt = getarg(opt, &argv));

			if (!HOSTID_DEFINED(set.start_host_id)) {
				die("ERROR: '%s=%s' is invalid first-host ID", arg, opt);
			}
		}

		else if (STRIMATCH(arg, "-l") ||
				 STRIMATCH(arg, "--last")) {
			if (HOSTID_DEFINED(set.end_host_id)) {
				die("ERROR: %s can only be used once", arg);
			}

			set.end_host_id = atoi(opt = getarg(opt, &argv));

			if (!HOSTID_DEFINED(set.end_host_id)) {
				die("ERROR: '%s=%s' is invalid last-host ID", arg, opt);
			}
		}

		else if (STRIMATCH(arg, "-p") ||
				 STRIMATCH(arg, "--poller")) {
			set.poller_id = atoi(getarg(opt, &argv));
		}

		else if (STRIMATCH(arg, "-h") ||
				 STRIMATCH(arg, "-v") ||
				 STRIMATCH(arg, "--help") ||
				 STRIMATCH(arg, "--version")) {
			display_help();

			exit(EXIT_SUCCESS);
		}

		else if (STRIMATCH(arg, "-O") ||
				 STRIMATCH(arg, "--option")) {
			char	*setting = getarg(opt, &argv);
			char	*value   = strchr(setting, ':');

			if (*value) {
				*value++ = '\0';
			}else{
				die("ERROR: -O requires setting:value");
			}

			set_option(setting, value);
		}

		else if (STRIMATCH(arg, "-R") ||
				 STRIMATCH(arg, "--readonly") ||
				 STRIMATCH(arg, "--read-only")) {
			set.SQL_readonly = TRUE;
		}

		else if (STRIMATCH(arg, "-C") ||
				 STRIMATCH(arg, "--conf")) {
			conf_file = strdup(getarg(opt, &argv));
		}

		else if (STRIMATCH(arg, "-S") ||
				 STRIMATCH(arg, "--stdout")) {
			set_option("log_destination", "STDOUT");
		}

		else if (STRIMATCH(arg, "-L") ||
				 STRIMATCH(arg, "--log")) {
			set_option("log_destination", getarg(opt, &argv));
		}

		else if (STRIMATCH(arg, "-V") ||
				 STRIMATCH(arg, "--verbosity")) {
			set_option("log_verbosity", getarg(opt, &argv));
		}

		else if (STRIMATCH(arg, "--snmponly") ||
				 STRIMATCH(arg, "--snmp-only")) {
			set.snmponly = TRUE;
		}

		else if (!HOSTID_DEFINED(set.start_host_id) && all_digits(arg)) {
			set.start_host_id = atoi(arg);
		}

		else if (!HOSTID_DEFINED(set.end_host_id) && all_digits(arg)) {
			set.end_host_id = atoi(arg);
		}

		else {
			die("ERROR: %s is an unknown command-line parameter", arg);
		}
	}

	/* we require either both the first and last hosts, or niether host */
	if (HOSTID_DEFINED(set.start_host_id) != HOSTID_DEFINED(set.end_host_id)) {
		die("ERROR: must provide both -f/-l, or neither");
	}

	if (set.start_host_id > set.end_host_id) {
		die("ERROR: Invalid row spec; first host_id must be less than the second");
	}

	/* read configuration file to establish local environment */
	if (conf_file) {
		if ((read_cactid_config(conf_file)) < 0) {
			die("ERROR: Could not read config file: %s\n", conf_file);
		}
	}else{
		if (!(conf_file = calloc(1, BUFSIZE))) {
			die("ERROR: Fatal malloc error: cactid.c conf_file!\n");
		}

		for (i=0; i<CONFIG_PATHS; i++) {
			snprintf(conf_file, BUFSIZE-1, "%s%s", config_paths[i], DEFAULT_CONF_FILE);

			if (read_cactid_config(conf_file) >= 0) {
				break;
			}

			if (i == CONFIG_PATHS-1) {
				snprintf(conf_file, BUFSIZE-1, "%s%s", config_paths[0], DEFAULT_CONF_FILE);
			}
		}
	}

	/* read settings table from the database to further establish environment */
	read_config_options();

	/* set the poller interval for those who use less than 5 minute intervals */
	if (set.poller_interval == 0) {
		poller_interval = 300;
	}else {
		poller_interval = set.poller_interval;
	}

	/* calculate the external_tread_sleep value */
	internal_thread_sleep = EXTERNAL_THREAD_SLEEP * set.num_parent_processes / 2;

	if (set.log_level == POLLER_VERBOSITY_DEBUG) {
		CACTID_LOG_DEBUG(("CACTID: Version %s starting\n", VERSION));
	}else{
		printf("CACTID: Version %s starting\n", VERSION);
	}

	/* connect to database */
	db_connect(set.dbdb, &mysql);

	/* initialize SNMP */
	CACTID_LOG_DEBUG(("CACTID: Initializing Net-SNMP API\n"));
	snmp_cactid_init();

	/* initialize PHP if required */
	CACTID_LOG_DEBUG(("CACTID: Initializing PHP Script Server\n"));

	/* tell cactid that it is parent, and set the poller id */
	set.parent_fork = CACTID_PARENT;
	set.poller_id = 0;

	/* initialize the script server */
	if (set.php_required) {
		php_init(PHP_INIT);
		set.php_initialized = TRUE;
		set.php_current_server = 0;
	}

	/* obtain the list of hosts to poll */
	{
	char querybuf[256], *qp = querybuf;

	qp += sprintf(qp, "SELECT id FROM host");
	qp += sprintf(qp, " WHERE disabled=''");
	qp += append_hostrange(qp, "id");	/* AND id BETWEEN a AND b */
	qp += sprintf(qp, " ORDER BY id");

	result = db_query(&mysql, querybuf);
	}

	num_rows = mysql_num_rows(result) + 1; /* add 1 for host = 0 */

	if (!(threads = (pthread_t *)malloc(num_rows * sizeof(pthread_t)))) {
		die("ERROR: Fatal malloc error: cactid.c threads!\n");
	}

	if (!(ids = (int *)malloc(num_rows * sizeof(int)))) {
		die("ERROR: Fatal malloc error: cactid.c host id's!\n");
	}

	/* initialize threads and mutexes */
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	init_mutexes();

	CACTID_LOG_DEBUG(("DEBUG: Initial Value of Active Threads is %i\n", active_threads));

	/* tell fork processes that they are now active */
	set.parent_fork = CACTID_FORK;

	/* loop through devices until done */
	while ((device_counter < num_rows) && (canexit == 0)) {
		mutex_status = thread_mutex_trylock(LOCK_THREAD);

		switch (mutex_status) {
		case 0:
			if (last_active_threads != active_threads) {
				last_active_threads = active_threads;
			}

			while ((active_threads < set.threads) && (device_counter < num_rows)) {
				if (device_counter > 0) {
					mysql_row = mysql_fetch_row(result);
					host_id = atoi(mysql_row[0]);
					ids[device_counter] = host_id;
				}else{
					ids[device_counter] = 0;
				}

				/* create child process */
				thread_status = pthread_create(&threads[device_counter], &attr, child, &ids[device_counter]);

				switch (thread_status) {
					case 0:
						CACTID_LOG_DEBUG(("DEBUG: Valid Thread to be Created\n"));

						device_counter++;
						active_threads++;

						CACTID_LOG_DEBUG(("DEBUG: The Value of Active Threads is %i\n", active_threads));

						break;
					case EAGAIN:
						CACTID_LOG(("ERROR: The System Lacked the Resources to Create a Thread\n"));
						break;
					case EFAULT:
						CACTID_LOG(("ERROR: The Thread or Attribute Was Invalid\n"));
						break;
					case EINVAL:
						CACTID_LOG(("ERROR: The Thread Attribute is Not Initialized\n"));
						break;
					default:
						CACTID_LOG(("ERROR: Unknown Thread Creation Error\n"));
						break;
				}
				usleep(internal_thread_sleep);

				/* get current time and exit program if time limit exceeded */
				if (poller_counter >= 20) {
					current_time = get_time_as_double();

					if ((current_time - begin_time + 6) > poller_interval) {
						CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n"));
						canexit = 1;
						break;
					}

					poller_counter = 0;
				}else{
					poller_counter++;
				}
			}

			thread_mutex_unlock(LOCK_THREAD);

			break;
		case EDEADLK:
			CACTID_LOG(("ERROR: Deadlock Occured\n"));
			break;
		case EBUSY:
			break;
		case EINVAL:
			CACTID_LOG(("ERROR: Attempt to Unlock an Uninitialized Mutex\n"));
			break;
		case EFAULT:
			CACTID_LOG(("ERROR: Attempt to Unlock an Invalid Mutex\n"));
			break;
		default:
			CACTID_LOG(("ERROR: Unknown Mutex Lock Error Code Returned\n"));
			break;
		}

		usleep(internal_thread_sleep);

		/* get current time and exit program if time limit exceeded */
		if (poller_counter >= 20) {
			current_time = get_time_as_double();

			if ((current_time - begin_time + 6) > poller_interval) {
				CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n"));
				canexit = 1;
				break;
			}

			poller_counter = 0;
		}else{
			poller_counter++;
		}
	}

	/* wait for all threads to complete */
	while (canexit == 0) {
		if (thread_mutex_trylock(LOCK_THREAD) == 0) {
			if (last_active_threads != active_threads) {
				last_active_threads = active_threads;
			}

			if (active_threads == 0) {
				canexit = 1;
			}

			thread_mutex_unlock(LOCK_THREAD);
		}

		usleep(EXTERNAL_THREAD_SLEEP);

		/* get current time and exit program if time limit exceeded */
		if (poller_counter >= 20) {
			current_time = get_time_as_double();

			if ((current_time - begin_time + 6) > poller_interval) {
				CACTID_LOG(("ERROR: Cactid Timed Out While Processing Hosts Internal\n"));
				canexit = 1;
				break;
			}

			poller_counter = 0;
		}else{
			poller_counter++;
		}
	}

	/* tell Cactid that it is now parent */
	set.parent_fork = CACTID_PARENT;

	/* print out stats */
	gettimeofday(&now, NULL);

	/* update the db for |data_time| on graphs */
	db_insert(&mysql, "replace into settings (name,value) values ('date',NOW())");
	db_insert(&mysql, "insert into poller_time (poller_id, start_time, end_time) values (0, NOW(), NOW())");

	/* cleanup and exit program */
	pthread_attr_destroy(&attr);

	CACTID_LOG_DEBUG(("DEBUG: Thread Cleanup Complete\n"));

	/* close the php script server */
	if (set.php_required) {
		php_close(PHP_INIT);
	}

	CACTID_LOG_DEBUG(("DEBUG: PHP Script Server Pipes Closed\n"));

	/* free malloc'd variables */
	free(threads);
	free(ids);
	free(conf_file);

	CACTID_LOG_DEBUG(("DEBUG: Allocated Variable Memory Freed\n"));

	/* shutdown SNMP */
	snmp_cactid_close();

	CACTID_LOG_DEBUG(("CACTID: Net-SNMP API Shutdown Completed\n"));

	/* close mysql */
	mysql_free_result(result);
	mysql_close(&mysql);

	CACTID_LOG_DEBUG(("DEBUG: MYSQL Free & Close Completed\n"));

	/* finally add some statistics to the log and exit */
	end_time = TIMEVAL_TO_DOUBLE(now);

	CACTID_LOG_MEDIUM(("Time: %.4f s, Threads: %i, Hosts: %i\n", (end_time - begin_time), set.threads, num_rows));

	exit(EXIT_SUCCESS);
}
Пример #15
0
static int
do_test (void)
{
  int result = 0;
  pthread_attr_t a;
  cpu_set_t c1, c2;

  int err = pthread_attr_init (&a);
  if (err)
    {
      error (0, err, "pthread_attr_init failed");
      result = 1;
    }

  err = pthread_attr_getaffinity_np (&a, sizeof (c1), &c1);
  if (err && err != ENOSYS)
    {
      error (0, err, "pthread_attr_getaffinity_np failed");
      result = 1;
    }

  err = pthread_attr_destroy (&a);
  if (err)
    {
      error (0, err, "pthread_attr_destroy failed");
      result = 1;
    }

  err = pthread_getattr_np (pthread_self (), &a);
  if (err)
    {
      error (0, err, "pthread_getattr_np failed");
      result = 1;
    }

  int detachstate;
  err = pthread_attr_getdetachstate (&a, &detachstate);
  if (err)
    {
      error (0, err, "pthread_attr_getdetachstate failed");
      result = 1;
    }
  else if (detachstate != PTHREAD_CREATE_JOINABLE)
    {
      error (0, 0, "initial thread not joinable");
      result = 1;
    }

  void *stackaddr;
  size_t stacksize;
  err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
  if (err)
    {
      error (0, err, "pthread_attr_getstack failed");
      result = 1;
    }
  else if ((void *) &a < stackaddr
	   || (void *) &a >= stackaddr + stacksize)
    {
      error (0, 0, "pthread_attr_getstack returned range does not cover main's stack");
      result = 1;
    }
  else
    printf ("initial thread stack %p-%p (0x%zx)\n", stackaddr,
	    stackaddr + stacksize, stacksize);

  size_t guardsize;
  err = pthread_attr_getguardsize (&a, &guardsize);
  if (err)
    {
      error (0, err, "pthread_attr_getguardsize failed");
      result = 1;
    }
  else if (guardsize != 0)
    {
      error (0, 0, "pthread_attr_getguardsize returned %zd != 0",
	     guardsize);
      result = 1;
    }

  int scope;
  err = pthread_attr_getscope (&a, &scope);
  if (err)
    {
      error (0, err, "pthread_attr_getscope failed");
      result = 1;
    }
  else if (scope != PTHREAD_SCOPE_SYSTEM)
    {
      error (0, 0, "pthread_attr_getscope returned %d != PTHREAD_SCOPE_SYSTEM",
	     scope);
      result = 1;
    }

  int inheritsched;
  err = pthread_attr_getinheritsched (&a, &inheritsched);
  if (err)
    {
      error (0, err, "pthread_attr_getinheritsched failed");
      result = 1;
    }
  else if (inheritsched != PTHREAD_INHERIT_SCHED)
    {
      error (0, 0, "pthread_attr_getinheritsched returned %d != PTHREAD_INHERIT_SCHED",
	     inheritsched);
      result = 1;
    }

  err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
  if (err == 0)
    {
      err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
      if (err)
	{
	  error (0, err, "pthread_attr_getaffinity_np failed");
	  result = 1;
	}
      else if (memcmp (&c1, &c2, sizeof (c1)))
	{
	  error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
	  result = 1;
	}
    }

  err = pthread_attr_destroy (&a);
  if (err)
    {
      error (0, err, "pthread_attr_destroy failed");
      result = 1;
    }

  pthread_t th;
  err = pthread_create (&th, NULL, tf, NULL);
  if (err)
    {
      error (0, err, "pthread_create #1 failed");
      result = 1;
    }
  else
    {
      void *ret;
      err = pthread_join (th, &ret);
      if (err)
	{
	  error (0, err, "pthread_join #1 failed");
	  result = 1;
	}
      else if (ret != NULL)
	result = 1;
    }

  err = pthread_attr_init (&a);
  if (err)
    {
      error (0, err, "pthread_attr_init failed");
      result = 1;
    }

  DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
  /* GCC 8 warns about aliasing of the restrict-qualified arguments
     passed &a.  Since pthread_create does not dereference its fourth
     argument, this aliasing, which is deliberate in this test, cannot
     in fact cause problems.  */
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
#endif
  err = pthread_create (&th, &a, tf, &a);
  DIAG_POP_NEEDS_COMMENT;
  if (err)
    {
      error (0, err, "pthread_create #2 failed");
      result = 1;
    }
  else
    {
      void *ret;
      err = pthread_join (th, &ret);
      if (err)
	{
	  error (0, err, "pthread_join #2 failed");
	  result = 1;
	}
      else if (ret != NULL)
	result = 1;
    }

  err = pthread_attr_setguardsize (&a, 16 * sysconf (_SC_PAGESIZE));
  if (err)
    {
      error (0, err, "pthread_attr_setguardsize failed");
      result = 1;
    }

  DIAG_PUSH_NEEDS_COMMENT;
#if __GNUC_PREREQ (7, 0)
  /* GCC 8 warns about aliasing of the restrict-qualified arguments
     passed &a.  Since pthread_create does not dereference its fourth
     argument, this aliasing, which is deliberate in this test, cannot
     in fact cause problems.  */
  DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
#endif
  err = pthread_create (&th, &a, tf, &a);
  DIAG_POP_NEEDS_COMMENT;
  if (err)
    {
      error (0, err, "pthread_create #3 failed");
      result = 1;
    }
  else
    {
      void *ret;
      err = pthread_join (th, &ret);
      if (err)
	{
	  error (0, err, "pthread_join #3 failed");
	  result = 1;
	}
      else if (ret != NULL)
	result = 1;
    }

  err = pthread_attr_destroy (&a);
  if (err)
    {
      error (0, err, "pthread_attr_destroy failed");
      result = 1;
    }

  return result;
}
Пример #16
0
int
do_test (void)
{
  if (pthread_barrier_init (&b, NULL, N + 1) != 0)
    {
      puts ("barrier_init failed");
      exit (1);
    }

  if (sem_init (&s, 0, 0) != 0)
    {
      puts ("sem_init failed");
      exit (1);
    }

  struct sigaction sa;
  sa.sa_handler = handler;
  sigemptyset (&sa.sa_mask);
  sa.sa_flags = 0;
  if (sigaction (THE_SIG, &sa, NULL) != 0)
    {
      puts ("sigaction failed");
      exit (1);
    }

  pthread_attr_t a;

  if (pthread_attr_init (&a) != 0)
    {
      puts ("attr_init failed");
      exit (1);
    }

  if (pthread_attr_setstacksize (&a, 1 * 1024 * 1024) != 0)
    {
      puts ("attr_setstacksize failed");
      return 1;
    }

  int i;
  for (i = 0; i < N; ++i)
    if (pthread_create (&th[i], &a, tf, cbs[i]) != 0)
      {
	puts ("pthread_create failed");
	exit (1);
      }

  if (pthread_attr_destroy (&a) != 0)
    {
      puts ("attr_destroy failed");
      exit (1);
    }

  pthread_barrier_wait (&b);

  sigset_t ss;
  sigemptyset (&ss);
  sigaddset (&ss, THE_SIG);
  if (pthread_sigmask (SIG_BLOCK, &ss, NULL) != 0)
    {
      puts ("pthread_sigmask failed");
      exit (1);
    }

  /* Start sending signals.  */
  for (i = 0; i < TOTAL_SIGS; ++i)
    {
      if (kill (getpid (), THE_SIG) != 0)
	{
	  puts ("kill failed");
	  exit (1);
	}

      if (TEMP_FAILURE_RETRY (sem_wait (&s)) != 0)
	{
	  puts ("sem_wait failed");
	  exit (1);
	}

      ++nsigs;
    }

  pthread_barrier_wait (&b);

  for (i = 0; i < N; ++i)
    if (pthread_join (th[i], NULL) != 0)
      {
	puts ("join failed");
	exit (1);
      }

  return 0;
}
Пример #17
0
static void *
tf (void *arg)
{
  pthread_attr_t a, *ap, a2;
  int err;
  void *result = NULL;

  if (arg == NULL)
    {
      ap = &a2;
      err = pthread_attr_init (ap);
      if (err)
	{
	  error (0, err, "pthread_attr_init failed");
	  return tf;
	}
    }
  else
    ap = (pthread_attr_t *) arg;

  err = pthread_getattr_np (pthread_self (), &a);
  if (err)
    {
      error (0, err, "pthread_getattr_np failed");
      result = tf;
    }

  int detachstate1, detachstate2;
  err = pthread_attr_getdetachstate (&a, &detachstate1);
  if (err)
    {
      error (0, err, "pthread_attr_getdetachstate failed");
      result = tf;
    }
  else
    {
      err = pthread_attr_getdetachstate (ap, &detachstate2);
      if (err)
	{
	  error (0, err, "pthread_attr_getdetachstate failed");
	  result = tf;
	}
      else if (detachstate1 != detachstate2)
	{
	  error (0, 0, "detachstate differs %d != %d",
		 detachstate1, detachstate2);
	  result = tf;
	}
    }

  void *stackaddr;
  size_t stacksize;
  err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
  if (err)
    {
      error (0, err, "pthread_attr_getstack failed");
      result = tf;
    }
  else if ((void *) &a < stackaddr
	   || (void *) &a >= stackaddr + stacksize)
    {
      error (0, 0, "pthread_attr_getstack returned range does not cover thread's stack");
      result = tf;
    }
  else
    printf ("thread stack %p-%p (0x%zx)\n", stackaddr, stackaddr + stacksize,
	    stacksize);

  size_t guardsize1, guardsize2;
  err = pthread_attr_getguardsize (&a, &guardsize1);
  if (err)
    {
      error (0, err, "pthread_attr_getguardsize failed");
      result = tf;
    }
  else
    {
      err = pthread_attr_getguardsize (ap, &guardsize2);
      if (err)
	{
	  error (0, err, "pthread_attr_getguardsize failed");
	  result = tf;
	}
      else if (guardsize1 != guardsize2)
	{
	  error (0, 0, "guardsize differs %zd != %zd",
		 guardsize1, guardsize2);
	  result = tf;
	}
      else
	printf ("thread guardsize %zd\n", guardsize1);
    }

  int scope1, scope2;
  err = pthread_attr_getscope (&a, &scope1);
  if (err)
    {
      error (0, err, "pthread_attr_getscope failed");
      result = tf;
    }
  else
    {
      err = pthread_attr_getscope (ap, &scope2);
      if (err)
	{
	  error (0, err, "pthread_attr_getscope failed");
	  result = tf;
	}
      else if (scope1 != scope2)
	{
	  error (0, 0, "scope differs %d != %d",
		 scope1, scope2);
	  result = tf;
	}
    }

  int inheritsched1, inheritsched2;
  err = pthread_attr_getinheritsched (&a, &inheritsched1);
  if (err)
    {
      error (0, err, "pthread_attr_getinheritsched failed");
      result = tf;
    }
  else
    {
      err = pthread_attr_getinheritsched (ap, &inheritsched2);
      if (err)
	{
	  error (0, err, "pthread_attr_getinheritsched failed");
	  result = tf;
	}
      else if (inheritsched1 != inheritsched2)
	{
	  error (0, 0, "inheritsched differs %d != %d",
		 inheritsched1, inheritsched2);
	  result = tf;
	}
    }

  cpu_set_t c1, c2;
  err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
  if (err == 0)
    {
      err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
      if (err)
	{
	  error (0, err, "pthread_attr_getaffinity_np failed");
	  result = tf;
	}
      else if (memcmp (&c1, &c2, sizeof (c1)))
	{
	  error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
	  result = tf;
	}
    }

  err = pthread_attr_destroy (&a);
  if (err)
    {
      error (0, err, "pthread_attr_destroy failed");
      result = tf;
    }

  if (ap == &a2)
    {
      err = pthread_attr_destroy (ap);
      if (err)
	{
	  error (0, err, "pthread_attr_destroy failed");
	  result = tf;
	}
    }

  return result;
}
Пример #18
0
int main(int argc, char *argv[]) {
  int pids[4] = { 1, 2, 3, 4 };
  int opt, rc = 0;
  pthread_attr_t attr;

  signal (SIGINT, sigint_handler);
  signal (SIGQUIT, sigquit_handler);

  sem_init(&stats_lock, 0, 1);
  sem_init(&timers_lock, 0, 1);
  sem_init(&counters_lock, 0, 1);

  queue_init();

  while ((opt = getopt(argc, argv, "dDfhp:m:s:cg:G:F:S:P:l:")) != -1) {
    switch (opt) {
      case 'd':
        printf("Debug enabled.\n");
        debug = 1;
        break;
      case 'D':
        printf("Daemonize enabled.\n");
        daemonize = 1;
        break;
      case 'f':
        printf("Friendly mode enabled (breaks wire compatibility).\n");
        friendly = 1;
        break;
      case 'F':
        flush_interval = atoi(optarg);
        printf("Flush interval set to %d seconds.\n", flush_interval);
        break;
      case 'p':
        port = atoi(optarg);
        printf("Statsd port set to %d\n", port);
        break;
      case 'm':
        mgmt_port = atoi(optarg);
        printf("Management port set to %d\n", mgmt_port);
        break;
      case 's':
        serialize_file = strdup(optarg);
        printf("Serialize to file %s\n", serialize_file);
        break;
      case 'c':
        clear_stats = 1;
        printf("Clearing stats on start.\n");
        break;
      case 'G':
        ganglia_host = strdup(optarg);
        enable_gmetric = 1;
        printf("Ganglia host %s\n", ganglia_host);
        break;
      case 'g':
        ganglia_port = atoi(optarg);
        printf("Ganglia port %d\n", ganglia_port);
        break;
      case 'S':
        ganglia_spoof = strdup(optarg);
        printf("Ganglia spoof host %s\n", ganglia_spoof);
        break;
      case 'P':
        ganglia_metric_prefix = strdup(optarg);
        printf("Ganglia metric prefix %s\n", ganglia_metric_prefix);
        break;
      case 'l':
        lock_file = strdup(optarg);
        printf("Lock file %s\n", lock_file);
        break;
      case 'h':
      default:
        syntax(argv);
        break;
    }
  }

  if (ganglia_spoof == NULL) {
    ganglia_spoof = strdup("statsd:statsd");
  }

  if (debug) {
    setlogmask(LOG_UPTO(LOG_DEBUG));
    openlog("statsd-c",  LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
  } else {
    setlogmask(LOG_UPTO(LOG_INFO));
    openlog("statsd-c", LOG_CONS, LOG_USER);
  }

  /* Initialization of certain stats, here. */
  init_stats();

  if (daemonize) {
    syslog(LOG_DEBUG, "Daemonizing statsd-c");
    daemonize_server();

    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN + 1024 * 1024);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  }

  pthread_create (&thread_udp,   daemonize ? &attr : NULL, (void *) &p_thread_udp,   (void *) &pids[0]);
  pthread_create (&thread_mgmt,  daemonize ? &attr : NULL, (void *) &p_thread_mgmt,  (void *) &pids[1]);
  pthread_create (&thread_flush, daemonize ? &attr : NULL, (void *) &p_thread_flush, (void *) &pids[2]);
  pthread_create (&thread_queue, daemonize ? &attr : NULL, (void *) &p_thread_queue, (void *) &pids[3]);

  if (daemonize) {
    syslog(LOG_DEBUG, "Destroying pthread attributes");
    pthread_attr_destroy(&attr);
    syslog(LOG_DEBUG, "Detaching pthreads");
    rc = pthread_detach(thread_udp);
    CHECK_PTHREAD_DETACH();
    rc = pthread_detach(thread_mgmt);
    CHECK_PTHREAD_DETACH();
    rc = pthread_detach(thread_flush);
    CHECK_PTHREAD_DETACH();
    rc = pthread_detach(thread_queue);
    CHECK_PTHREAD_DETACH();
    for (;;) { }
  } else {
    syslog(LOG_DEBUG, "Waiting for pthread termination");
    pthread_join(thread_udp,   NULL);
    pthread_join(thread_mgmt,  NULL);
    pthread_join(thread_flush, NULL);
    pthread_join(thread_queue, NULL);
    syslog(LOG_DEBUG, "Pthreads terminated");
  }

  return 0;
}
Пример #19
0
void
mono_threads_core_get_stack_bounds (guint8 **staddr, size_t *stsize)
{
#if defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
	/* Mac OS X */
	*staddr = (guint8*)pthread_get_stackaddr_np (pthread_self());
	*stsize = pthread_get_stacksize_np (pthread_self());

#ifdef TARGET_OSX
	/*
	 * Mavericks reports stack sizes as 512kb:
	 * http://permalink.gmane.org/gmane.comp.java.openjdk.hotspot.devel/11590
	 * https://bugs.openjdk.java.net/browse/JDK-8020753
	 */
	if (pthread_main_np () && *stsize == 512 * 1024)
		*stsize = 2048 * mono_pagesize ();
#endif

	/* staddr points to the start of the stack, not the end */
	*staddr -= *stsize;

	/* When running under emacs, sometimes staddr is not aligned to a page size */
	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize() - 1));
	return;

#elif (defined(HAVE_PTHREAD_GETATTR_NP) || defined(HAVE_PTHREAD_ATTR_GET_NP)) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
	/* Linux, BSD */

	pthread_attr_t attr;
	guint8 *current = (guint8*)&attr;

	*staddr = NULL;
	*stsize = (size_t)-1;

	pthread_attr_init (&attr);

#if     defined(HAVE_PTHREAD_GETATTR_NP)
	/* Linux */
	pthread_getattr_np (pthread_self(), &attr);

#elif   defined(HAVE_PTHREAD_ATTR_GET_NP)
	/* BSD */
	pthread_attr_get_np (pthread_self(), &attr);

#else
#error 	Cannot determine which API is needed to retrieve pthread attributes.
#endif

	pthread_attr_getstack (&attr, (void**)staddr, stsize);
	pthread_attr_destroy (&attr);

	if (*staddr)
		g_assert ((current > *staddr) && (current < *staddr + *stsize));

	/* When running under emacs, sometimes staddr is not aligned to a page size */
	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
	return;

#elif defined(__OpenBSD__)
	/* OpenBSD */
	/* TODO :   Determine if this code is actually still needed. It may already be covered by the case above. */

	pthread_attr_t attr;
	guint8 *current = (guint8*)&attr;

	*staddr = NULL;
	*stsize = (size_t)-1;

	pthread_attr_init (&attr);

	stack_t ss;
	int rslt;

	rslt = pthread_stackseg_np(pthread_self(), &ss);
	g_assert (rslt == 0);

	*staddr = (guint8*)((size_t)ss.ss_sp - ss.ss_size);
	*stsize = ss.ss_size;

	pthread_attr_destroy (&attr);

	if (*staddr)
		g_assert ((current > *staddr) && (current < *staddr + *stsize));

	/* When running under emacs, sometimes staddr is not aligned to a page size */
	*staddr = (guint8*)((gssize)*staddr & ~(mono_pagesize () - 1));
	return;

#elif defined(sun) || defined(__native_client__)
	/* Solaris/Illumos, NaCl */
	pthread_attr_t attr;
	pthread_attr_init (&attr);
	pthread_attr_getstacksize (&attr, &stsize);
	pthread_attr_destroy (&attr);
	*staddr = NULL;
	return;

#else
	/* FIXME:   It'd be better to use the 'error' preprocessor macro here so we know
		    at compile-time if the target platform isn't supported. */
#warning "Unable to determine how to retrieve a thread's stack-bounds for this platform in 'mono_thread_get_stack_bounds()'."
	*staddr = NULL;
	*stsize = 0;
	return;
#endif
}
Пример #20
0
pthread_t
uorb_receive_start(void)
{
    /* --- SENSORS RAW VALUE --- */
    mavlink_subs.sensor_sub = orb_subscribe(ORB_ID(sensor_combined));
    /* rate limit set externally based on interface speed, set a basic default here */
    orb_set_interval(mavlink_subs.sensor_sub, 200);	/* 5Hz updates */

    /* --- ATTITUDE VALUE --- */
    mavlink_subs.att_sub = orb_subscribe(ORB_ID(vehicle_attitude));
    /* rate limit set externally based on interface speed, set a basic default here */
    orb_set_interval(mavlink_subs.att_sub, 200);	/* 5Hz updates */

    /* --- GPS VALUE --- */
    mavlink_subs.gps_sub = orb_subscribe(ORB_ID(vehicle_gps_position));
    orb_set_interval(mavlink_subs.gps_sub, 200);	/* 5Hz updates */

    /* --- HOME POSITION --- */
    mavlink_subs.home_sub = orb_subscribe(ORB_ID(home_position));
    orb_set_interval(mavlink_subs.home_sub, 1000);	/* 1Hz updates */

    /* --- SYSTEM STATE --- */
    status_sub = orb_subscribe(ORB_ID(vehicle_status));
    orb_set_interval(status_sub, 300);		/* max 3.33 Hz updates */

    /* --- RC CHANNELS VALUE --- */
    rc_sub = orb_subscribe(ORB_ID(rc_channels));
    orb_set_interval(rc_sub, 100);			/* 10Hz updates */

    /* --- RC RAW VALUE --- */
    mavlink_subs.input_rc_sub = orb_subscribe(ORB_ID(input_rc));
    orb_set_interval(mavlink_subs.input_rc_sub, 100);

    /* --- GLOBAL POS VALUE --- */
    mavlink_subs.global_pos_sub = orb_subscribe(ORB_ID(vehicle_global_position));
    orb_set_interval(mavlink_subs.global_pos_sub, 100);	/* 10 Hz active updates */

    /* --- LOCAL POS VALUE --- */
    mavlink_subs.local_pos_sub = orb_subscribe(ORB_ID(vehicle_local_position));
    orb_set_interval(mavlink_subs.local_pos_sub, 1000);	/* 1Hz active updates */

    /* --- GLOBAL SETPOINT VALUE --- */
    mavlink_subs.spg_sub = orb_subscribe(ORB_ID(vehicle_global_position_setpoint));
    orb_set_interval(mavlink_subs.spg_sub, 2000);	/* 0.5 Hz updates */

    /* --- LOCAL SETPOINT VALUE --- */
    mavlink_subs.spl_sub = orb_subscribe(ORB_ID(vehicle_local_position_setpoint));
    orb_set_interval(mavlink_subs.spl_sub, 2000);	/* 0.5 Hz updates */

    /* --- ATTITUDE SETPOINT VALUE --- */
    mavlink_subs.spa_sub = orb_subscribe(ORB_ID(vehicle_attitude_setpoint));
    orb_set_interval(mavlink_subs.spa_sub, 2000);	/* 0.5 Hz updates */

    /* --- RATES SETPOINT VALUE --- */
    mavlink_subs.rates_setpoint_sub = orb_subscribe(ORB_ID(vehicle_rates_setpoint));
    orb_set_interval(mavlink_subs.rates_setpoint_sub, 2000);  /* 0.5 Hz updates */

    /* --- ACTUATOR OUTPUTS --- */
    mavlink_subs.act_0_sub = orb_subscribe(ORB_ID(actuator_outputs_0));
    mavlink_subs.act_1_sub = orb_subscribe(ORB_ID(actuator_outputs_1));
    mavlink_subs.act_2_sub = orb_subscribe(ORB_ID(actuator_outputs_2));
    mavlink_subs.act_3_sub = orb_subscribe(ORB_ID(actuator_outputs_3));
    /* rate limits set externally based on interface speed, set a basic default here */
    orb_set_interval(mavlink_subs.act_0_sub, 100);	/* 10Hz updates */
    orb_set_interval(mavlink_subs.act_1_sub, 100);	/* 10Hz updates */
    orb_set_interval(mavlink_subs.act_2_sub, 100);	/* 10Hz updates */
    orb_set_interval(mavlink_subs.act_3_sub, 100);	/* 10Hz updates */

    /* --- ACTUATOR ARMED VALUE --- */
    mavlink_subs.armed_sub = orb_subscribe(ORB_ID(actuator_armed));
    orb_set_interval(mavlink_subs.armed_sub, 100);	/* 10Hz updates */

    /* --- MAPPED MANUAL CONTROL INPUTS --- */
    mavlink_subs.man_control_sp_sub = orb_subscribe(ORB_ID(manual_control_setpoint));
    /* rate limits set externally based on interface speed, set a basic default here */
    orb_set_interval(mavlink_subs.man_control_sp_sub, 100);	/* 10Hz updates */

    /* --- ACTUATOR CONTROL VALUE --- */
    mavlink_subs.actuators_effective_sub = orb_subscribe(ORB_ID_VEHICLE_ATTITUDE_CONTROLS_EFFECTIVE);
    orb_set_interval(mavlink_subs.actuators_effective_sub, 100);	/* 10Hz updates */

    mavlink_subs.actuators_sub = orb_subscribe(ORB_ID_VEHICLE_ATTITUDE_CONTROLS);
    orb_set_interval(mavlink_subs.actuators_sub, 100);	/* 10Hz updates */

    /* --- DEBUG VALUE OUTPUT --- */
    mavlink_subs.debug_key_value = orb_subscribe(ORB_ID(debug_key_value));
    orb_set_interval(mavlink_subs.debug_key_value, 100);	/* 10Hz updates */

    /* --- FLOW SENSOR --- */
    mavlink_subs.optical_flow = orb_subscribe(ORB_ID(optical_flow));
    orb_set_interval(mavlink_subs.optical_flow, 200); 	/* 5Hz updates */

    /* --- AIRSPEED / VFR / HUD --- */
    mavlink_subs.airspeed_sub = orb_subscribe(ORB_ID(airspeed));
    orb_set_interval(mavlink_subs.airspeed_sub, 200); 	/* 5Hz updates */

    /* start the listener loop */
    pthread_attr_t uorb_attr;
    pthread_attr_init(&uorb_attr);

    /* Set stack size, needs less than 2k */
    pthread_attr_setstacksize(&uorb_attr, 2048);

    pthread_t thread;
    pthread_create(&thread, &uorb_attr, uorb_receive_thread, NULL);

    pthread_attr_destroy(&uorb_attr);
    return thread;
}
Пример #21
0
void testSystemSpecific1( void )
	{
#if 0	/* See comment below */
	const CRYPT_ATTRIBUTE_TYPE testType = -1;
#endif /* 0 */
	int bigEndian;
#ifndef _WIN32_WCE
	int i;
#endif /* WinCE */

	/* Make sure that we've got the endianness set right.  If the machine is
	   big-endian (up to 64 bits) the following value will be signed,
	   otherwise it will be unsigned.  We can't easily test for things like
	   middle-endianness without knowing the size of the data types, but
	   then again it's unlikely we're being run on a PDP-11 */
	bigEndian = ( *( long * ) "\x80\x00\x00\x00\x00\x00\x00\x00" < 0 );
#ifdef DATA_LITTLEENDIAN
	if( bigEndian )
		{
		puts( "The CPU endianness define is set wrong in crypt.h, this "
			  "machine appears to be\nbig-endian, not little-endian.  Edit "
			  "the file and rebuild cryptlib." );
		exit( EXIT_FAILURE );
		}
#else
	if( !bigEndian )
		{
		puts( "The CPU endianness define is set wrong in crypt.h, this "
			  "machine appears to be\nlittle-endian, not big-endian.  Edit "
			  "the file and rebuild cryptlib." );
		exit( EXIT_FAILURE );
		}
#endif /* DATA_LITTLEENDIAN */

	/* Make sure that the compiler doesn't use variable-size enums (done by, 
	   for example, the PalmOS SDK for backwards compatibility with 
	   architectural decisions made for 68K-based PalmPilots) */
	if( sizeof( CRYPT_ALGO_TYPE ) != sizeof( int ) || \
		sizeof( CRYPT_MODE_TYPE ) != sizeof( int ) ||
		sizeof( CRYPT_ATTRIBUTE_TYPE ) != sizeof( int ) )
		{
		puts( "The compiler you are using treats enumerated types as "
			  "variable-length non-\ninteger values, making it impossible "
			  "to reliably pass the address of an\nenum as a function "
			  "parameter.  To fix this you need to rebuild cryptlib\nwith "
			  "the appropriate compiler option or pragma to ensure that\n"
			  "sizeof( enum ) == sizeof( int )." );
		exit( EXIT_FAILURE );
		}

#if 0	/* The ANSI C default is 'int' with signedness being unimportant, 
		   MSVC defaults to signed, gcc defaults to unsigned, and cryptlib
		   works with either, so whatever the CodeSourcery build of gcc is
		   doing it's more serious than a simple signedness issue */
	/* Make sure that the compiler doesn't use unsigned enums (for example a 
	   mutant CodeSourcery build of gcc for eCos does this) */
	if( testType >= 0 )
		{
		puts( "The compiler you are using treats enumerated types as "
			  "unsigned values,\nmaking it impossible to reliably use enums "
			  "in conjunction with standard\n(signed) integers.  To fix this "
			  "you need to rebuild cryptlib with the\nappropriate compiler "
			  "option or pragma to ensure that enumerated types\nare signed "
			  "like standard data types." );
		exit( EXIT_FAILURE );
		}
#endif /* 0 */

	/* Make sure that mktime() works properly (there are some systems on
	   which it fails well before 2038) */
#ifndef _WIN32_WCE
	for( i = 10; i < 36; i ++ )
		{
		const time_t theTime = testTime( i );

		if( theTime < 0 )
			{
			printf( "Warning: This system has a buggy mktime() that can't "
					"handle dates beyond %d.\n         Some certificate tests "
					"will fail, and long-lived CA certificates\n         won't "
					"be correctly imported.\nPress a key...\n", 2000 + i );
			getchar();
			break;
			}
		}
#endif /* !WinCE */

	/* If we're compiling under Unix with threading support, make sure the
	   default thread stack size is sensible.  We don't perform the check for
	   UnixWare/SCO since this already has the workaround applied */
#if defined( UNIX_THREADS ) && !defined( __SCO_VERSION__ )
	{
	pthread_attr_t attr;
	size_t stackSize;

	pthread_attr_init( &attr );
	pthread_attr_getstacksize( &attr, &stackSize );
    pthread_attr_destroy( &attr );
  #if ( defined( sun ) && OSVERSION > 4 )
	/* Slowaris uses a special-case value of 0 (actually NULL) to indicate
	   the default stack size of 1MB (32-bit) or 2MB (64-bit), so we have to
	   handle this specially */
	if( stackSize < 32768 && stackSize != 0 )
  #else
	if( stackSize < 32768 )
  #endif /* Slowaris special-case handling */
		{
		printf( "The pthread stack size is defaulting to %ld bytes, which is "
				"too small for\ncryptlib to run in.  To fix this, edit the "
				"thread-creation function macro in\ncryptos.h and recompile "
				"cryptlib.\n", ( long ) stackSize );
		exit( EXIT_FAILURE );
		}
	}
#endif /* UNIX_THREADS */
	}
Пример #22
0
static enum MqErrorE SysServerThread (
    struct MqS * const context,
    struct MqFactoryS factory,
    struct MqBufferLS ** argvP,
    struct MqBufferLS ** alfaP,
    MQ_CST  name,
    int state,
    struct MqIdS * idP
)
{
#if defined(MQ_HAS_THREAD)
    mqthread_t threadId;
#if defined(HAVE_PTHREAD)
    int ret;
#endif

    // fill thread data
    struct MqSysServerThreadMainS * argP = (struct MqSysServerThreadMainS *) MqSysMalloc(MQ_ERROR_PANIC,sizeof(*argP));
    argP->factory = factory;
    argP->argv = *argvP;
    argP->alfa = *alfaP;
    argP->tmpl = context;

    // pointers are owned by SysServerThread
    *argvP = NULL;
    *alfaP = NULL;

    // after a "thread" no "fork" is possible
    MqConfigSetIgnoreFork (context, MQ_YES);

#if defined(HAVE_PTHREAD)

    // thread attributes
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setdetachstate(&attr, state);

    // thread setup !before! a thread was created
    if (context->setup.fThreadInit) (*context->setup.fThreadInit)(context);

    // start thread
    do {
        ret = pthread_create(&threadId,&attr,sSysServerThreadInit,argP);
    } while (ret == EAGAIN);

    // cleanup attribute
    pthread_attr_destroy(&attr);

    if (unlikely(ret != 0)) {
        MqErrorDbV (MQ_ERROR_CAN_NOT_START_SERVER, name);
        goto error;
    }

#elif defined(MQ_IS_WIN32)

    if (unlikely ( (threadId = _beginthreadex(NULL, 0, sSysServerThreadInit, argP, 0, NULL)) == 0)) {
        MqErrorDbV (MQ_ERROR_CAN_NOT_START_SERVER, name);
        MqErrorSysAppend (_beginthreadex);
        goto error;
    }

#endif

    // save tid
    (*idP).val = (mqthread_t)threadId;
    (*idP).type = MQ_ID_THREAD;

    return MQ_OK;

error:
    MqBufferLDelete (&argP->argv);
    MqBufferLDelete (&argP->alfa);
    MqSysFree (argP);
    return MQ_ERROR;
#else
    return MqErrorDb(MQ_ERROR_NOT_SUPPORTED);
#endif   /* MQ_HAS_THREAD */
}
Пример #23
0
/**
 * 功能:创建工作线程
 * 参数:@pool: 线程池句柄 
 *      @worker: 工作函数
 *      @idx: 线程位置索引号 
 * 描述:
 *      1. 首先创建woker线程的资源,并初始化
 *      2. 将线程句柄放入主线程的容器中的对应位置
 *      3. 启动woker线程,开始干活,函数返回
 * 返回:成功:0; 失败:-x
 **/
static int msd_thread_worker_create(msd_thread_pool_t *pool, void* (*worker_task)(void *), int idx)
{
    msd_thread_worker_t *worker  = NULL;
    char error_buf[256];
    if(!(worker = calloc(1, sizeof(msd_thread_worker_t))))
    {
        MSD_ERROR_LOG("Thread_worker_creat failed, idx:%d", idx);
        return MSD_ERR;
    }
    
    worker->pool                 = pool;
    worker->idx                  = idx;
    worker->status               = W_STOP;
    worker->priv_data            = NULL;
    pool->thread_worker_array[idx] = worker; /* 放入对应的位置 */

    /* 
     * 创建通信管道
     * master线程将需要处理的fd写入管道,woker线程从管道取出
     **/
    int fds[2];
    if (pipe(fds) != 0)
    {
        free(worker);
        MSD_ERROR_LOG("Thread_worker_creat pipe failed, idx:%d", idx);
        return MSD_ERR;
    }
    worker->notify_read_fd  = fds[0];
    worker->notify_write_fd = fds[1];

    /* 管道不能是阻塞的! */
    if((MSD_OK != msd_anet_nonblock(error_buf,  worker->notify_read_fd))
        || (MSD_OK != msd_anet_nonblock(error_buf,  worker->notify_write_fd)))
    {
        close(worker->notify_read_fd);
        close(worker->notify_write_fd);
        free(worker);
        MSD_ERROR_LOG("Set pipe nonblock failed, err:%s", error_buf);
        return MSD_ERR;        
    }

    /* 创建ae句柄 */
    if(!(worker->t_ael = msd_ae_create_event_loop()))
    {
        close(worker->notify_read_fd);
        close(worker->notify_write_fd);
        free(worker);
        MSD_ERROR_LOG("Create ae failed");
        return MSD_ERR;  
    }

    /* 初始化client队列 */
    if(!(worker->client_list = msd_dlist_init()))
    {
        close(worker->notify_read_fd);
        close(worker->notify_write_fd);
        msd_ae_free_event_loop(worker->t_ael);
        free(worker);
        MSD_ERROR_LOG("Create ae failed");
        return MSD_ERR;         
    }

    /* 创建线程 */
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    pthread_attr_setstacksize(&attr, pool->thread_stack_size);
    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    if(pthread_create(&worker->tid, &attr, worker_task, worker) != 0)
    {
        close(worker->notify_read_fd);
        close(worker->notify_write_fd);
        free(worker);
        MSD_ERROR_LOG("Thread_worker_creat failed, idx:%d", idx);
        return MSD_ERR;        
    }
    pthread_attr_destroy(&attr);
    return MSD_OK;    
}
Пример #24
0
static void internal_pthread_backtrace(pthread_t thread, void** buffer, size_t max, size_t* depth, size_t skip)
{
	*depth = 0;

	//! Get information about the stack (pos & size).
	uint8_t* stackbot;
	size_t stack_size; //! in bytes
	size_t guard_size; //! in bytes
#if defined(__FreeBSD__)
	pthread_attr_t attr;
	pthread_attr_init(&attr);
	pthread_attr_get_np(thread, &attr);
	pthread_attr_getstack(&attr, (void**)&stackbot, &stack_size);
	pthread_attr_getguardsize(&attr, &guard_size);
	pthread_attr_destroy(&attr);
#elif defined(__APPLE__)
	stackbot = (uint8_t*)pthread_get_stackaddr_np(thread);
	stack_size = pthread_get_stacksize_np(thread);
	guard_size = 0; //FIXME anyway to get that?
#else
	pthread_attr_t attr;
	pthread_getattr_np(thread, &attr);
	pthread_attr_getstack(&attr, (void**)&stackbot, &stack_size);
	pthread_attr_getguardsize(&attr, &guard_size);
	pthread_attr_destroy(&attr);
#endif
	stack_size -= guard_size;

	//! The thread is is still running!!!
	//! So make a buffer copy of the stack, else it gets changed while we reading from it!
	std::vector<uint8_t> sbuffer(stack_size);
	uint8_t* stack_buffer = &sbuffer[0];
	memcpy(stack_buffer, stackbot, stack_size);

	//! It is impossible to get the current frame (the current function pos) on the stack
	//! for other pthreads, so we need to find it ourself. The beneath method is very naive
	//! and just searchs for the starting address that gives us the longest stackdepth.
	unsigned longest_stack = 0;
	unsigned longest_offset = 0;
	int check_area = MAX(0, stack_size - 1024*sizeof(uintptr_t));
	check_area *= 0.8f; //! only check ~20% from the top of the stack
	for (int offset = stack_size - sizeof(uintptr_t); offset >= check_area; offset -= sizeof(uintptr_t)) {
		unsigned stack_depth = 0;
		uint8_t* frame = stack_buffer + offset;
		frame = TranslateStackAddrToBufferAddr(frame, stackbot, stack_buffer);
		uint8_t* last_frame = frame;
		while (INSTACK(frame) && (frame > last_frame)) {
			last_frame = frame;
			frame = TranslateStackAddrToBufferAddr(frame, stackbot, stack_buffer);
			stack_depth++;
		}
		if (stack_depth > longest_stack) {
			longest_stack = stack_depth;
			longest_offset = offset;
		}
	}

	//! Now get the list of function addresses from the stack.
	uint8_t* frame = stack_buffer + longest_offset;
	if(!INSTACK(frame))
		return;
	while (skip--) {
		uint8_t* next = TranslateStackAddrToBufferAddr(frame, stackbot, stack_buffer);
		if(!INSTACK(next))
			return;
		frame = next;
	}
	while (max--) {
		uint8_t* next = TranslateStackAddrToBufferAddr(frame, stackbot, stack_buffer);
		buffer[*depth] = (void*)*((uintptr_t*)frame + FP_OFFSET);
		(*depth)++;
		if(!INSTACK(next))
			return;
		frame = next;
	}
}
Пример #25
0
int main(int argc, char **argv)
{
  int ret;
  baseRateInfo_t info;
  pthread_attr_t attr;
  pthread_t baseRateThread;
  size_t stackSize;
  unsigned long cpuMask = 0x1;
  unsigned int len = sizeof(cpuMask);
  printf("**starting the model**\n");
  fflush(stdout);
  rtmSetErrorStatus(testA_M, 0);

  /* Unused arguments */
  (void)(argc);
  (void)(argv);

  /* All threads created by this process must run on a single CPU */
  ret = sched_setaffinity(0, len, (cpu_set_t *) &cpuMask);
  CHECK_STATUS(ret, "sched_setaffinity");

  /* Initialize semaphore used for thread synchronization */
  ret = sem_init(&stopSem, 0, 0);
  CHECK_STATUS(ret, "sem_init:stopSem");

  /* Create threads executing the Simulink model */
  pthread_attr_init(&attr);
  ret = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
  CHECK_STATUS(ret, "pthread_attr_setinheritsched");
  ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
  CHECK_STATUS(ret, "pthread_attr_setdetachstate");

  /* PTHREAD_STACK_MIN is the minimum stack size required to start a thread */
  stackSize = 64000 + PTHREAD_STACK_MIN;
  ret = pthread_attr_setstacksize(&attr, stackSize);
  CHECK_STATUS(ret, "pthread_attr_setstacksize");

  /* Block signal used for timer notification */
  info.period = 0.01;
  info.signo = SIGRTMIN;
  sigemptyset(&info.sigMask);
  MW_blockSignal(info.signo, &info.sigMask);
  signal(SIGTERM, MW_exitHandler);     /* kill */
  signal(SIGHUP, MW_exitHandler);      /* kill -HUP */
  signal(SIGINT, MW_exitHandler);      /* Interrupt from keyboard */
  signal(SIGQUIT, MW_exitHandler);     /* Quit from keyboard */
  testA_initialize();

  /* Create base rate task */
  ret = pthread_create(&baseRateThread, &attr, (void *) baseRateTask, (void *)
                       &info);
  CHECK_STATUS(ret, "pthread_create");
  pthread_attr_destroy(&attr);

  /* Wait for a stopping condition. */
  MW_sem_wait(&stopSem);

  /* Received stop signal */
  printf("**stopping the model**\n");
  if (rtmGetErrorStatus(testA_M) != NULL) {
    printf("\n**%s**\n", rtmGetErrorStatus(testA_M));
  }

  /* Disable rt_OneStep() here */

  /* Terminate model */
  testA_terminate();
  return 0;
}
Пример #26
0
// Foreground waits for exit of the main persistent threads
// that are started here. The threads are created to manage
// UNIX domain client sockets for writing, reading and
// controlling the user space logger, and for any additional
// logging plugins like auditd and restart control. Additional
// transitory per-client threads are created for each reader.
int main(int argc, char *argv[]) {
    int fdPmesg = -1;
    bool klogd = property_get_bool_svelte("logd.klogd");
    if (klogd) {
        fdPmesg = open("/proc/kmsg", O_RDONLY | O_NDELAY);
    }
    fdDmesg = open("/dev/kmsg", O_WRONLY);

    // issue reinit command. KISS argument parsing.
    if ((argc > 1) && argv[1] && !strcmp(argv[1], "--reinit")) {
        int sock = TEMP_FAILURE_RETRY(
            socket_local_client("logd",
                                ANDROID_SOCKET_NAMESPACE_RESERVED,
                                SOCK_STREAM));
        if (sock < 0) {
            return -errno;
        }
        static const char reinit[] = "reinit";
        ssize_t ret = TEMP_FAILURE_RETRY(write(sock, reinit, sizeof(reinit)));
        if (ret < 0) {
            return -errno;
        }
        struct pollfd p;
        memset(&p, 0, sizeof(p));
        p.fd = sock;
        p.events = POLLIN;
        ret = TEMP_FAILURE_RETRY(poll(&p, 1, 100));
        if (ret < 0) {
            return -errno;
        }
        if ((ret == 0) || !(p.revents & POLLIN)) {
            return -ETIME;
        }
        static const char success[] = "success";
        char buffer[sizeof(success) - 1];
        memset(buffer, 0, sizeof(buffer));
        ret = TEMP_FAILURE_RETRY(read(sock, buffer, sizeof(buffer)));
        if (ret < 0) {
            return -errno;
        }
        return strncmp(buffer, success, sizeof(success) - 1) != 0;
    }

    // Reinit Thread
    sem_init(&reinit, 0, 0);
    sem_init(&uidName, 0, 0);
    sem_init(&sem_name, 0, 1);
    pthread_attr_t attr;
    if (!pthread_attr_init(&attr)) {
        struct sched_param param;

        memset(&param, 0, sizeof(param));
        pthread_attr_setschedparam(&attr, &param);
        pthread_attr_setschedpolicy(&attr, SCHED_BATCH);
        if (!pthread_attr_setdetachstate(&attr,
                                         PTHREAD_CREATE_DETACHED)) {
            pthread_t thread;
            reinit_running = true;
            if (pthread_create(&thread, &attr, reinit_thread_start, NULL)) {
                reinit_running = false;
            }
        }
        pthread_attr_destroy(&attr);
    }

    if (drop_privs() != 0) {
        return -1;
    }

    // Serves the purpose of managing the last logs times read on a
    // socket connection, and as a reader lock on a range of log
    // entries.

    LastLogTimes *times = new LastLogTimes();

    // LogBuffer is the object which is responsible for holding all
    // log entries.

    logBuf = new LogBuffer(times);

    signal(SIGHUP, reinit_signal_handler);

    if (property_get_bool_svelte("logd.statistics")) {
        logBuf->enableStatistics();
    }

    // LogReader listens on /dev/socket/logdr. When a client
    // connects, log entries in the LogBuffer are written to the client.

    LogReader *reader = new LogReader(logBuf);
    if (reader->startListener()) {
        exit(1);
    }

    // LogListener listens on /dev/socket/logdw for client
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    LogListener *swl = new LogListener(logBuf, reader);
    // Backlog and /proc/sys/net/unix/max_dgram_qlen set to large value
    if (swl->startListener(300)) {
        exit(1);
    }

    // Command listener listens on /dev/socket/logd for incoming logd
    // administrative commands.

    CommandListener *cl = new CommandListener(logBuf, reader, swl);
    if (cl->startListener()) {
        exit(1);
    }

    // LogAudit listens on NETLINK_AUDIT socket for selinux
    // initiated log messages. New log entries are added to LogBuffer
    // and LogReader is notified to send updates to connected clients.

    bool auditd = property_get_bool("logd.auditd", true);

    LogAudit *al = NULL;
    if (auditd) {
        bool dmesg = property_get_bool("logd.auditd.dmesg", true);
        al = new LogAudit(logBuf, reader, dmesg ? fdDmesg : -1);
    }

    LogKlog *kl = NULL;
    if (klogd) {
        kl = new LogKlog(logBuf, reader, fdDmesg, fdPmesg, al != NULL);
    }

    if (al || kl) {
        int len = klogctl(KLOG_SIZE_BUFFER, NULL, 0);
        if (len > 0) {
            len++;
            char buf[len];

            int rc = klogctl(KLOG_READ_ALL, buf, len);

            buf[len - 1] = '\0';

            if ((rc >= 0) && kl) {
                kl->synchronize(buf);
            }

            for (char *ptr = NULL, *tok = buf;
                 (rc >= 0) && ((tok = log_strtok_r(tok, &ptr)));
                 tok = NULL) {
                if (al) {
                    rc = al->log(tok);
                }
                if (kl) {
                    rc = kl->log(tok);
                }
            }
        }

        // failure is an option ... messages are in dmesg (required by standard)

        if (kl && kl->startListener()) {
            delete kl;
        }

        if (al && al->startListener()) {
            delete al;
        }
    }

    TEMP_FAILURE_RETRY(pause());

    exit(0);
}
Пример #27
0
 Thread::~Thread()
 {
   if (pthread_attr_destroy(&m_attr) != 0)
     throw ThreadException("pthread_attr_destroy error", __LINE__, __FILE__);
 }
//Return the negative log likelihood for a PDF/DataSet result
double NegativeLogLikelihoodThreaded::EvaluateDataSet( IPDF * FittingPDF, IDataSet * TotalDataSet, int number )
{
	(void) FittingPDF;

	if( TotalDataSet->GetDataNumber() == 0 ) return 0.;

	if( Threads <= 0 )
	{
		cerr<< "Bad Number of Threads: " << Threads << " check your XML!!!" << endl << endl;
		exit(-125);
	}

	//	1 thread per core
	pthread_t* Thread = new pthread_t[ (unsigned)Threads ];
	pthread_attr_t attrib;

	//	Threads HAVE to be joinable
	//	We CANNOT _AND_SHOULD_NOT_ ***EVER*** return information to Minuit without the results from ALL threads successfully returned
	//	Not all pthread implementations are required to obey this as default when constructing the thread _SO_BE_EXPLICIT_
	pthread_attr_init(&attrib);
	pthread_attr_setdetachstate(&attrib, PTHREAD_CREATE_JOINABLE);

	//cout << "Setup Threads: " << Threads << endl;
	ObservableRef weightObservableRef( weightObservableName );

	/*
	   for( int i=0; i< StoredDataSubSet.size(); ++i )
	   {
	   if( i == number )
	   {
	   int tot=0;
	   for( int j=0; j< StoredDataSubSet[i].size(); ++j )
	   {
	   cout << "+" << StoredDataSubSet[i][j].size() << endl;
	   tot+=StoredDataSubSet[i][j].size();
	   }
	   cout << "=" << tot << endl;
	   }
	   }
	   */

	//	Initialize the Fitting_Thread objects which contain the objects to be passed to each thread
	for( unsigned int threadnum=0; threadnum< (unsigned)Threads; ++threadnum )
	{
		fit_thread_data[threadnum].dataSubSet = StoredDataSubSet[(unsigned)number][threadnum];
		fit_thread_data[threadnum].fittingPDF = stored_pdfs[((unsigned)number)*(unsigned)Threads + threadnum];
		fit_thread_data[threadnum].fittingPDF->SetDebugMutex( &eval_lock, false );
		fit_thread_data[threadnum].useWeights = useWeights;					//	Defined in the fitfunction baseclass
		fit_thread_data[threadnum].FitBoundary = StoredBoundary[(unsigned)Threads*((unsigned)number)+threadnum];
		fit_thread_data[threadnum].dataPoint_Result = vector<double>();
		fit_thread_data[threadnum].weightsSquared = weightsSquared;
	}

	//cout << "Creating Threads" << endl;

	//	Create the Threads and set them to be joinable
	for( unsigned int threadnum=0; threadnum< (unsigned)Threads ; ++threadnum )
	{
		int status = pthread_create(&Thread[threadnum], &attrib, this->ThreadWork, (void *) &fit_thread_data[threadnum] );
		if( status )
		{
			cerr << "ERROR:\tfrom pthread_create()\t" << status << "\t...Exiting\n" << endl;
			exit(-1);
		}
	}

	//cout << "Joining Threads!!" << endl;

	//	Join the Threads
	for( unsigned int threadnum=0; threadnum< (unsigned)Threads ; ++threadnum )
	{
		int status = pthread_join( Thread[threadnum], NULL);
		if( status )
		{
			cerr << "Error Joining a Thread:\t" << threadnum << "\t:\t" << status << "\t...Exiting\n" << endl;
		}
	}

	//      Do some cleaning Up
	pthread_attr_destroy(&attrib);

	//cout << "Leaving Threads" << endl;

	double total=0;

	vector<double> NLLValues;

	for( unsigned int threadnum=0; threadnum< (unsigned)Threads; ++threadnum )
	{
		for( unsigned int point_num=0; point_num< fit_thread_data[threadnum].dataPoint_Result.size(); ++point_num )
		{
			if( fabs(fit_thread_data[threadnum].dataPoint_Result[ point_num ]) >= DBL_MAX )
			{
				return DBL_MAX;
			}

			DataPoint* thisPoint = fit_thread_data[threadnum].dataSubSet[ point_num ];

			if( this->GetOffSetNLL() && !std::isnan(thisPoint->GetInitialNLL()) )
			{
				NLLValues.push_back(fit_thread_data[threadnum].dataPoint_Result[ point_num ] - thisPoint->GetInitialNLL() );
			}
			else
			{
				if( this->GetOffSetNLL() )
				{
					NLLValues.push_back( 0. );
					thisPoint->SetInitialNLL( fit_thread_data[threadnum].dataPoint_Result[ point_num ] );
				}
				else
				{
					NLLValues.push_back( fit_thread_data[threadnum].dataPoint_Result[ point_num ] );
				}
			}

		}
		vector<double> empty;
		fit_thread_data[threadnum].dataPoint_Result.swap( empty );
	}

	sort( NLLValues.begin(), NLLValues.end(), NLLSort );

	for( vector<double>::iterator this_i = NLLValues.begin(); this_i != NLLValues.end(); ++this_i )
	{
		total+=*this_i;
	}

	delete [] Thread;

	//cout << total << endl;
	//exit(0);

	return -total;
}
Пример #29
0
int main(int argc, char **argv)
{
		int s, tnum, opt, num_threads;
		struct thread_info *tinfo;
		pthread_attr_t attr;
		void *res;
		
		num_threads = 1;
    while ((opt = getopt(argc, argv, "n:")) != -1) {
        switch (opt) {
        case 'n':
            num_threads = strtoul(optarg, NULL, 0);
            break;

        default:
            fprintf(stderr, "Usage: %s [-n pthread-num] arg...\n",
                    argv[0]);
            exit(EXIT_FAILURE);
        }
    }
	
    tinfo = calloc(num_threads, sizeof(struct thread_info));
    if (tinfo == NULL)
        perror("calloc");
        
    s = pthread_attr_init(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_init");
        
    s = pthread_mutex_init(&mutex, NULL);
    if(s != 0)
    	 handle_error_en(s, "pthread_mutex_init");
    
    for(tnum = 0; tnum < num_threads; tnum++)
    {
    	s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    	if (s != 0)
      handle_error_en(s, "pthread_attr_setdetachstate");
    	
    	s = pthread_create(&tinfo[tnum].thread_id, &attr, &thread_start, &tinfo[tnum]);
    	if (s != 0)
            handle_error_en(s, "pthread_create");
    	tinfo[tnum].thread_num = tnum + 1;
    }
    
    s = pthread_mutex_destroy(&mutex);
    if(s != 0)
    	 handle_error_en(s, "pthread_mutex_destroy");
    	 
    s = pthread_attr_destroy(&attr);
    if (s != 0)
        handle_error_en(s, "pthread_attr_destroy");
    /*    
    for (tnum = 0; tnum < num_threads; tnum++) {
        s = pthread_join(tinfo[tnum].thread_id, &res);
        if (s != 0) {
        	if(s == EINVAL)
        		printf("thread is not a joinable thread.\n");
        	else
          	handle_error_en(s, "pthread_join");
        }
				else {
        	printf("Joined with thread %d; returned value was %s\n",
                tinfo[tnum].thread_num, (char *) res);
        	free(res);      
        }
    }
		*/
		sleep(1000);
		
    free(tinfo);
    exit(EXIT_SUCCESS);
    
	return 0;
}
Пример #30
0
/*
========================
Sys_Createthread
========================
*/
uintptr_t Sys_CreateThread( xthread_t function, void* parms, xthreadPriority priority, const char* name, core_t core, int stackSize, bool suspended )
{
	pthread_attr_t attr;
	pthread_attr_init( &attr );
	
	if( pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ) != 0 )
	{
		idLib::common->FatalError( "ERROR: pthread_attr_setdetachstate %s failed\n", name );
		return ( uintptr_t )0;
	}
	
	pthread_t handle;
	if( pthread_create( ( pthread_t* )&handle, &attr, ( pthread_function_t )function, parms ) != 0 )
	{
		idLib::common->FatalError( "ERROR: pthread_create %s failed\n", name );
		return ( uintptr_t )0;
	}
	
#if defined(DEBUG_THREADS)
	if( Sys_SetThreadName( handle, name ) != 0 )
	{
		idLib::common->Warning( "Warning: pthread_setname_np %s failed\n", name );
		return ( uintptr_t )0;
	}
#endif
	
	pthread_attr_destroy( &attr );
	
	
#if 0
	// RB: realtime policies require root privileges
	
	// all Linux threads have one of the following scheduling policies:
	
	// SCHED_OTHER or SCHED_NORMAL: the default policy,  priority: [-20..0..19], default 0
	
	// SCHED_FIFO: first in/first out realtime policy
	
	// SCHED_RR: round-robin realtime policy
	
	// SCHED_BATCH: similar to SCHED_OTHER, but with a throughput orientation
	
	// SCHED_IDLE: lower priority than SCHED_OTHER
	
	int schedulePolicy = SCHED_OTHER;
	struct sched_param scheduleParam;
	
	int error = pthread_getschedparam( handle, &schedulePolicy, &scheduleParam );
	if( error != 0 )
	{
		idLib::common->FatalError( "ERROR: pthread_getschedparam %s failed: %s\n", name, strerror( error ) );
		return ( uintptr_t )0;
	}
	
	schedulePolicy = SCHED_FIFO;
	
	int minPriority = sched_get_priority_min( schedulePolicy );
	int maxPriority = sched_get_priority_max( schedulePolicy );
	
	if( priority == THREAD_HIGHEST )
	{
		//  we better sleep enough to do this
		scheduleParam.__sched_priority = maxPriority;
	}
	else if( priority == THREAD_ABOVE_NORMAL )
	{
		scheduleParam.__sched_priority = Lerp( minPriority, maxPriority, 0.75f );
	}
	else if( priority == THREAD_NORMAL )
	{
		scheduleParam.__sched_priority = Lerp( minPriority, maxPriority, 0.5f );
	}
	else if( priority == THREAD_BELOW_NORMAL )
	{
		scheduleParam.__sched_priority = Lerp( minPriority, maxPriority, 0.25f );
	}
	else if( priority == THREAD_LOWEST )
	{
		scheduleParam.__sched_priority = minPriority;
	}
	
	// set new priority
	error = pthread_setschedparam( handle, schedulePolicy, &scheduleParam );
	if( error != 0 )
	{
		idLib::common->FatalError( "ERROR: pthread_setschedparam( name = %s, policy = %i, priority = %i ) failed: %s\n", name, schedulePolicy, scheduleParam.__sched_priority, strerror( error ) );
		return ( uintptr_t )0;
	}
	
	pthread_getschedparam( handle, &schedulePolicy, &scheduleParam );
	if( error != 0 )
	{
		idLib::common->FatalError( "ERROR: pthread_getschedparam %s failed: %s\n", name, strerror( error ) );
		return ( uintptr_t )0;
	}
#endif
	
	// Under Linux, we don't set the thread affinity and let the OS deal with scheduling
	
	return ( uintptr_t )handle;
}