Ejemplo n.º 1
0
static int parsecfg(xmlDocPtr doc, xmlNodePtr node, struct state *state, unsigned int *schedrr)
{
	xmlNodePtr audio = NULL;
	xmlNodePtr ptt = NULL;
	const char *par[MAXPAR];
	struct modemchannel *chan;
        pthread_attr_t rxattr;
	size_t stacksize;
	unsigned int samplerate = 5000, mode;

	for (; node; node = node->next) {
		if (!node->name)
			logprintf(MLOG_FATAL, "Node has no name\n");
		if (!strcmp(node->name, "audio")) {
			audio = node;
			continue;
		}
		if (!strcmp(node->name, "ptt")) {
			ptt = node;
			continue;
		}
		if (!strcmp(node->name, "chaccess")) {
			getparam(doc, node, chaccparams, par);
			if (par[0])
				state->chacc.txdelay = strtoul(par[0], NULL, 0);
			if (par[1])
				state->chacc.slottime = strtoul(par[1], NULL, 0);
			if (par[2])
				state->chacc.ppersist = strtoul(par[2], NULL, 0);
			if (par[3])
				state->chacc.fullduplex = !!strtoul(par[3], NULL, 0);
			if (par[4])
				state->chacc.txtail = strtoul(par[4], NULL, 0);
			continue;
		}
		if (!strcmp(node->name, "channel")) {
			if (node->childs)
				parsechannel(doc, node->childs, state, &samplerate);
			continue;
		}
		logprintf(MLOG_ERROR, "unknown node \"%s\"\n", node->name);
	}
        /* find audio mode */
        mode = 0;
        for (chan = state->channels; chan; chan = chan->next) {
                if (chan->demod && chan->demod->demodulate)
                        mode |= IO_RDONLY;
                if (chan->mod && chan->mod->modulate)
                        mode |= IO_WRONLY;
        }
	if (!state->channels || !mode) {
		logprintf(MLOG_ERROR, "no channels configured\n");
		return -1;
	}
        /* open PTT */
	getparam(doc, ptt, pttparams, par);
	if (pttinit(&state->ptt, par))
                logprintf(MLOG_ERROR, "cannot start PTT output\n");
        /* open audio */
	getparam(doc, audio, ioparam_type, par);
	if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[1])) {
		getparam(doc, audio, ioparams_filein, par);
		state->audioio = ioopen_filein(&samplerate, IO_RDONLY, par);
		if (schedrr)
			*schedrr = 0;
	} else if (par[0] && !strcmp(par[0], ioparam_type[0].u.c.combostr[2])) {
                getparam(doc, audio, ioparams_sim, par);
		state->audioio = ioopen_sim(&samplerate, IO_RDWR, par);
		if (schedrr)
			*schedrr = 0;
	} else {
		getparam(doc, audio, ioparams_soundcard, par);
		state->audioio = ioopen_soundcard(&samplerate, mode, par);
	}
	if (!state->audioio)
                logprintf(MLOG_FATAL, "cannot start audio\n");
	for (chan = state->channels; chan; chan = chan->next) {
		if (chan->demod) {
			chan->demod->init(chan->demodstate, samplerate, &chan->rxbitrate);
                        if (pthread_attr_init(&rxattr))
				logerr(MLOG_FATAL, "pthread_attr_init");
			/* needed on FreeBSD, according to [email protected] */
			if (pthread_attr_getstacksize(&rxattr, &stacksize))
				logerr(MLOG_ERROR, "pthread_attr_getstacksize");
			else if (stacksize < 256*1024)
				if (pthread_attr_setstacksize(&rxattr, 256*1024))
					logerr(MLOG_ERROR, "pthread_attr_setstacksize");
#ifdef HAVE_SCHED_H
                        if (schedrr && *schedrr) {
                                struct sched_param schp;
                                memset(&schp, 0, sizeof(schp));
                                schp.sched_priority = sched_get_priority_min(SCHED_RR)+1;
                                if (pthread_attr_setschedpolicy(&rxattr, SCHED_RR))
                                        logerr(MLOG_ERROR, "pthread_attr_setschedpolicy");
                                if (pthread_attr_setschedparam(&rxattr, &schp))
                                        logerr(MLOG_ERROR, "pthread_attr_setschedparam");
                        }
#endif /* HAVE_SCHED_H */
			if (pthread_create(&chan->rxthread, &rxattr, demodthread, chan))
				logerr(MLOG_FATAL, "pthread_create");
                        pthread_attr_destroy(&rxattr);
		}
		if (chan->mod)
			chan->mod->init(chan->modstate, samplerate);
	}
	return 0;
}
Ejemplo n.º 2
0
TIMM_OSAL_ERRORTYPE TIMM_OSAL_CreateTask (TIMM_OSAL_PTR *pTask,
                                          TIMM_OSAL_TaskProc pFunc,
                                          TIMM_OSAL_U32 uArgc,
                                          TIMM_OSAL_PTR pArgv,
                                          TIMM_OSAL_U32 uStackSize,
                                          TIMM_OSAL_U32 uPriority,
                                          TIMM_OSAL_S8 *pName)
{

    TIMM_OSAL_ERRORTYPE bReturnStatus = TIMM_OSAL_ERR_UNKNOWN;
    TIMM_OSAL_TASK *pHandle = TIMM_OSAL_NULL;
	struct sched_param sched;
    size_t stackSize;
    *pTask = TIMM_OSAL_NULL;
    unsigned int temp = (unsigned int)pFunc;


	/*Task structure allocation*/
    pHandle = (TIMM_OSAL_TASK *) TIMM_OSAL_Malloc(sizeof(TIMM_OSAL_TASK), 0, 0, 0);
    if(pHandle == TIMM_OSAL_NULL) {
        bReturnStatus =  TIMM_OSAL_ERR_ALLOC;
        goto EXIT;
	}

    /* Initial cleaning of the task structure */
    TIMM_OSAL_Memset((TIMM_OSAL_PTR)pHandle, 0, sizeof(TIMM_OSAL_TASK));

	/*Arguments for task*/
	pHandle->uArgc = uArgc;
	pHandle->pArgv = pArgv;

    pHandle->isCreated = TIMM_OSAL_FALSE;


	if(SUCCESS != pthread_attr_init(&pHandle->ThreadAttr)){
		/*TIMM_OSAL_Error("Task Init Attr Init failed!");*/
		goto EXIT;
	}
	/* Updation of the priority and the stack size*/
	
    if(SUCCESS != pthread_attr_getschedparam(&pHandle->ThreadAttr, &sched)){
		/*TIMM_OSAL_Error("Task Init Get Sched Params failed!");*/
		goto EXIT;
    }

    sched.sched_priority = uPriority; /* relative to the default priority */
    if(SUCCESS != pthread_attr_setschedparam(&pHandle->ThreadAttr, &sched)){
		/*TIMM_OSAL_Error("Task Init Set Sched Paramsfailed!");*/
		goto EXIT;
	}

    /*First get the default stack size*/
    if(SUCCESS != pthread_attr_getstacksize(&pHandle->ThreadAttr, &stackSize)){        
		/*TIMM_OSAL_Error("Task Init Set Stack Size failed!");*/
		goto EXIT;
	}

    /*Check if requested stack size is larger than the current default stack size*/
    if(uStackSize > stackSize) {
        stackSize = uStackSize;
        if(SUCCESS != pthread_attr_setstacksize(&pHandle->ThreadAttr, stackSize)){
		    /*TIMM_OSAL_Error("Task Init Set Stack Size failed!");*/
		    goto EXIT;
	    }
    }



	if (SUCCESS != pthread_create(&pHandle->threadID, &pHandle->ThreadAttr, pFunc, pArgv)) {
        /*TIMM_OSAL_Error ("Create_Task failed !");*/
        goto EXIT;
    }


    /* Task was successfully created */
    pHandle->isCreated = TIMM_OSAL_TRUE;
    *pTask = (TIMM_OSAL_PTR )pHandle;
    bReturnStatus = TIMM_OSAL_ERR_NONE;
    /**pTask = (TIMM_OSAL_PTR *)pHandle;*/

EXIT:
/*    if((TIMM_OSAL_ERR_NONE != bReturnStatus) && (TIMM_OSAL_NULL != pHandle)) {
       TIMM_OSAL_Free (pHandle->stackPtr);*/
	if((TIMM_OSAL_ERR_NONE != bReturnStatus)) {
        TIMM_OSAL_Free(pHandle);
    }
    return bReturnStatus;

}
Ejemplo n.º 3
0
size_t
TclpThreadGetStackSize(void)
{
    size_t stackSize = 0;
#if defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) && defined(TclpPthreadGetAttrs)
    pthread_attr_t threadAttr;	/* This will hold the thread attributes for
				 * the current thread. */
#ifdef __GLIBC__ 
    /*
     * Fix for [Bug 1815573]
     *
     * DESCRIPTION:
     * On linux TclpPthreadGetAttrs (which is pthread_attr_get_np) may return
     * bogus values on the initial thread. 
     *
     * ASSUMPTIONS:
     * There seems to be no api to determine if we are on the initial
     * thread. The simple scheme implemented here assumes:
     *   1. The first Tcl interp to be created lives in the initial thread. If
     *      this assumption is not true, the fix is to call
     *      TclpThreadGetStackSize from the initial thread previous to
     *      creating any Tcl interpreter. In this case, especially if another
     *      Tcl interpreter may be created in the initial thread, it might be
     *      better to enable the second branch in the #if below
     *   2. There will be no races in creating the first Tcl interp - ie, the
     *      second Tcl interp will be created only after the first call to
     *      Tcl_CreateInterp returns.
     *
     * These assumptions are satisfied by tclsh. Embedders on linux may want
     * to check their validity, and possibly adapt the code on failing to meet
     * them.
     */

    static int initialized = 0;

    if (!initialized) {
	initialized = 1;
	return 0;
    } else {
#else
    {
#endif
	if (pthread_attr_init(&threadAttr) != 0) {
	    return -1;
	}
	if (TclpPthreadGetAttrs(pthread_self(), &threadAttr) != 0) {
	    pthread_attr_destroy(&threadAttr);
	    return (size_t)-1;
	}
    }

    
    if (pthread_attr_getstacksize(&threadAttr, &stackSize) != 0) {
	pthread_attr_destroy(&threadAttr);
	return (size_t)-1;
    }
    pthread_attr_destroy(&threadAttr);
#elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP)
#ifdef __APPLE__
    /*
     * On Darwin, the API below does not return the correct stack size for the
     * main thread (which is not a real pthread), so fallback to getrlimit().
     */  
    if (!pthread_main_np())
#endif
    stackSize = pthread_get_stacksize_np(pthread_self());
#else
    /*
     * Cannot determine the real stack size of this thread. The caller might
     * want to try looking at the process accounting limits instead.
     */
#endif
    return stackSize;
}
#endif /* TCL_THREADS */

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetCurrentThread --
 *
 *	This procedure returns the ID of the currently running thread.
 *
 * Results:
 *	A thread ID.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_ThreadId
Tcl_GetCurrentThread(void)
{
#ifdef TCL_THREADS
    return (Tcl_ThreadId) pthread_self();
#else
    return (Tcl_ThreadId) 0;
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TclpInitLock
 *
 *	This procedure is used to grab a lock that serializes initialization
 *	and finalization of Tcl. On some platforms this may also initialize
 *	the mutex used to serialize creation of more mutexes and thread local
 *	storage keys.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the initialization mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpInitLock(void)
{
#ifdef TCL_THREADS
    pthread_mutex_lock(&initLock);
#endif
}
Ejemplo n.º 4
0
void chpl_thread_init(void(*threadBeginFn)(void*),
                      void(*threadEndFn)(void)) {
  //
  // This threading layer does not have any inherent limit on the number
  // of threads.  Its limit is the lesser of any limits imposed by the
  // comm layer and the user.
  //
  {
    uint32_t lim;

    if ((lim = chpl_task_getenvNumThreadsPerLocale()) > 0)
      maxThreads = lim;
    else if ((lim = chpl_comm_getMaxThreads()) > 0)
      maxThreads = lim;
  }

  //
  // Count the main thread on locale 0 as already existing, since it
  // is (or soon will be) running the main program.
  //
  if (chpl_nodeID == 0)
    numThreads = 1;

  //
  // If a value was specified for the call stack size config const, use
  // that (rounded up to a whole number of pages) to set the system and
  // pthread stack limits.
  //
  if (pthread_attr_init(&thread_attributes) != 0)
    chpl_internal_error("pthread_attr_init() failed");

  //
  // If a value was specified for the call stack size, use that (rounded
  // up to a whole number of pages) to set the system and pthread stack
  // limits.  This will in turn limit the stack for any task hosted by
  // either the main process or a pthread.
  //
  {
    size_t        css;
    size_t        pagesize = (size_t) sysconf(_SC_PAGESIZE);
    struct rlimit rlim;

    if ((css = chpl_task_getEnvCallStackSize()) == 0)
      css = chpl_task_getDefaultCallStackSize();
    assert(css > 0);

    css = (css + pagesize - 1) & ~(pagesize - 1);

    if (getrlimit(RLIMIT_STACK, &rlim) != 0)
      chpl_internal_error("getrlimit() failed");

    if (rlim.rlim_max != RLIM_INFINITY && css > rlim.rlim_max) {
      char warning[128];
      sprintf(warning, "call stack size capped at %lu\n", 
              (unsigned long)rlim.rlim_max);
      chpl_warning(warning, 0, 0);

      css = rlim.rlim_max;
    }

    rlim.rlim_cur = css;

#ifndef __CYGWIN__
    //
    // Cygwin can't do setrlimit(RLIMIT_STACK).
    //
    if (setrlimit(RLIMIT_STACK, &rlim) != 0)
      chpl_internal_error("setrlimit() failed");
#endif

    if (pthread_attr_setstacksize(&thread_attributes, css) != 0)
      chpl_internal_error("pthread_attr_setstacksize() failed");
  }

  if (pthread_attr_getstacksize(&thread_attributes, &threadCallStackSize) != 0)
      chpl_internal_error("pthread_attr_getstacksize() failed");

  saved_threadBeginFn = threadBeginFn;
  saved_threadEndFn   = threadEndFn;

  CHPL_TLS_INIT(chpl_thread_id);
  CHPL_TLS_SET(chpl_thread_id, (intptr_t) --curr_thread_id);
  CHPL_TLS_INIT(chpl_thread_data);

  pthread_mutex_init(&thread_info_lock, NULL);
  pthread_mutex_init(&numThreadsLock, NULL);

  //
  // This is something of a hack, but it makes us a bit more resilient
  // if we're out of memory or near to it at shutdown time.  Launch,
  // cancel, and join with an initial pthread, forcing initialization
  // needed by any of those activities.  (In particular we have found
  // that cancellation needs to dlopen(3) a shared object, which fails
  // if we are out of memory.  Doing it now means that shared object is
  // already available when we need it later.)
  //
  {
    pthread_t initial_pthread;

    if (!pthread_create(&initial_pthread, NULL, initial_pthread_func, NULL)) {
      (void) pthread_cancel(initial_pthread);
      (void) pthread_join(initial_pthread, NULL);
    }
  }
}
int main(int argn, char *argc[])
{
	//Program parameters : argc[1] : HostName or Host IP
	//                                         argc[2] : Server Program Number
	//                                         argc[3] : Maximal number of threads
	//                                         argc[4] : Number of calls per thread
	//                                         other arguments depend on test case

	//run_mode can switch into stand alone program or program launch by shell script
	//1 : stand alone, debug mode, more screen information
	//0 : launch by shell script as test case, only one printf -> result status
	run_mode = 0;
	int test_status = 1;	//Default test result set to FAILED
	int i, rthcreate;
	long j;
	int threadNb = atoi((char *)argc[3]);
	int curThd = 1;

	//Thread declarations
	pthread_t *pThreadArray;
	void *ret = NULL;
	pthread_attr_t thread_attr;
	int ssz = 0;

	//Time measurement declarations
	struct timeval tv1, tv2;
	struct timezone tz;
	long long diff;
	double rslt;

	//Program initialization
	progNum = atoi((char *)argc[2]);
	callNb = atoi((char *)argc[4]);
	hostname = (char *)argc[1];

	//Initialization
	maxThd = maxThd << (threadNb - 1);	//Set the maximum threads number

	pthread_attr_init(&thread_attr);

	if (run_mode == 1) {
		pthread_attr_getstacksize(&thread_attr, (size_t *) & ssz);	//For debug purpose, get default thread stack size
		fprintf(stderr, "Server #%d\n", progNum);
		fprintf(stderr, "Calls per thread : %d\n", callNb);
		fprintf(stderr, "Instances : %d\n", threadNb);
		fprintf(stderr, "Max threads to create : %d\n", maxThd);
		fprintf(stderr, "Standard thread stack size in bytes %d\n",
			ssz);
	}

	pthread_attr_setstacksize(&thread_attr, 40000);	//Set thread stack size to 40 KB

	//Init results table
	thread_time_result = (double *)malloc((threadNb) * sizeof(double));
	memset(&thread_time_result[0], (double)0, (threadNb) * sizeof(double));

	//Create all threads
	//Run all threads
	pThreadArray = (pthread_t *) malloc(maxThd * sizeof(pthread_t));

	for (i = 0; i < threadNb; i++) {
		if (run_mode)
			fprintf(stderr, "Threads for pass %d : %d\n", i,
				curThd);

		gettimeofday(&tv1, &tz);

		for (j = 0; j < curThd; j++) {
			//Create thread using defined parameters (stack size = 40 KB)
			if (pthread_create
			    (&pThreadArray[j], &thread_attr, my_thread_process,
			     (void *)j) != 0) {
				fprintf(stderr,
					"pthread_create error for thread %d\n",
					j);
				printf("1\n");
				exit(1);
			}
		}

		//Clean threads
		for (j = 0; j < curThd; j++) {
			if ((pthread_t *) pThreadArray[j] != NULL) {
				(void)pthread_join(pThreadArray[j], &ret);
			} else {
				fprintf(stderr, "pThread Join Err : %d\n", j);
			}
		}

		gettimeofday(&tv2, &tz);

		//Calculate and store delay to table results
		diff =
		    (tv2.tv_sec - tv1.tv_sec) * 1000000L + (tv2.tv_usec -
							    tv1.tv_usec);
		rslt = (double)diff / 1000;
		thread_time_result[i] = rslt;

		curThd = curThd * 2;
	}

	//Check if all threads results are ok
	test_status = 0;
	for (i = 0; i < threadNb; i++) {
		if (thread_time_result[i] == 0) {
			test_status = 1;
			break;
		}
	}

	//This last printf gives the result status to the tests suite
	//normally should be 0: test has passed or 1: test has failed
	printf("%d\n", test_status);

	//Print scalability results
	curThd = 1;
	for (i = 0; i < threadNb; i++) {
		printf("%d %lf\n", curThd, thread_time_result[i]);
		curThd = curThd * 2;
	}

	return test_status;
}
Ejemplo n.º 6
0
/*
 * Get the initial address and size of current thread's stack
 */
static int
get_stack(void **addr, size_t *size)
{
#define CHECK_ERR(expr)				\
    {int err = (expr); if (err) return err;}
#ifdef HAVE_PTHREAD_GETATTR_NP /* Linux */
    pthread_attr_t attr;
    size_t guard = 0;
    STACK_GROW_DIR_DETECTION;
    CHECK_ERR(pthread_getattr_np(pthread_self(), &attr));
# ifdef HAVE_PTHREAD_ATTR_GETSTACK
    CHECK_ERR(pthread_attr_getstack(&attr, addr, size));
    STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
# else
    CHECK_ERR(pthread_attr_getstackaddr(&attr, addr));
    CHECK_ERR(pthread_attr_getstacksize(&attr, size));
# endif
    CHECK_ERR(pthread_attr_getguardsize(&attr, &guard));
    *size -= guard;
    pthread_attr_destroy(&attr);
#elif defined HAVE_PTHREAD_ATTR_GET_NP /* FreeBSD, DragonFly BSD, NetBSD */
    pthread_attr_t attr;
    CHECK_ERR(pthread_attr_init(&attr));
    CHECK_ERR(pthread_attr_get_np(pthread_self(), &attr));
# ifdef HAVE_PTHREAD_ATTR_GETSTACK
    CHECK_ERR(pthread_attr_getstack(&attr, addr, size));
# else
    CHECK_ERR(pthread_attr_getstackaddr(&attr, addr));
    CHECK_ERR(pthread_attr_getstacksize(&attr, size));
# endif
    STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
    pthread_attr_destroy(&attr);
#elif (defined HAVE_PTHREAD_GET_STACKADDR_NP && defined HAVE_PTHREAD_GET_STACKSIZE_NP) /* MacOS X */
    pthread_t th = pthread_self();
    *addr = pthread_get_stackaddr_np(th);
    *size = pthread_get_stacksize_np(th);
#elif defined HAVE_THR_STKSEGMENT || defined HAVE_PTHREAD_STACKSEG_NP
    stack_t stk;
# if defined HAVE_THR_STKSEGMENT /* Solaris */
    CHECK_ERR(thr_stksegment(&stk));
# else /* OpenBSD */
    CHECK_ERR(pthread_stackseg_np(pthread_self(), &stk));
# endif
    *addr = stk.ss_sp;
    *size = stk.ss_size;
#elif defined HAVE_PTHREAD_GETTHRDS_NP /* AIX */
    pthread_t th = pthread_self();
    struct __pthrdsinfo thinfo;
    char reg[256];
    int regsiz=sizeof(reg);
    CHECK_ERR(pthread_getthrds_np(&th, PTHRDSINFO_QUERY_ALL,
				   &thinfo, sizeof(thinfo),
				   &reg, &regsiz));
    *addr = thinfo.__pi_stackaddr;
    *size = thinfo.__pi_stacksize;
    STACK_DIR_UPPER((void)0, (void)(*addr = (char *)*addr + *size));
#else
#error STACKADDR_AVAILABLE is defined but not implemented.
#endif
    return 0;
#undef CHECK_ERR
}
Ejemplo n.º 7
0
int main(int argc, char **argv)
{
	int i;
	int config_loaded = 0;
	int dont_fork = 0;
	size_t wanted_stacksize = 0, stacksize = 0;
	pthread_attr_t attr;

	// global initialization
	get_HZ();

	// set the name for logging
	program_name = "netdata";

	// parse command line.

	// parse depercated options
	// TODO: Remove this block with the next major release.
	{
		i = 1;
		while(i < argc) {
			if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) {
				strncpyz(pidfile, argv[i+1], FILENAME_MAX);
				fprintf(stderr, "%s: deprecated option -- %s -- please use -P instead.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) {
				dont_fork = 1;
				fprintf(stderr, "%s: deprecated option -- %s -- please use -D instead.\n ", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) {
				config_set("global", "host access prefix", argv[i+1]);
				fprintf(stderr, "%s: deprecated option -- %s -- please use -s instead.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else if(strcmp(argv[i], "-l") == 0 && (i+1) < argc) {
				config_set("global", "history", argv[i+1]);
				fprintf(stderr, "%s: deprecated option -- %s -- This option will be removed with V2.*.\n", argv[0], argv[i]);
				remove_option(i, &argc, argv);
			}
			else i++;
		}
	}

	// parse options
	{
		int num_opts = sizeof(options) / sizeof(struct option_def);
		char optstring[(num_opts * 2) + 1];

		int string_i = 0;
		for( i = 0; i < num_opts; i++ ) {
			optstring[string_i] = options[i].val;
			string_i++;
			if(options[i].arg_name) {
				optstring[string_i] = ':';
				string_i++;
			}
		}

		int opt;
		while( (opt = getopt(argc, argv, optstring)) != -1 ) {
			switch(opt) {
				case 'c':
					if(load_config(optarg, 1) != 1) {
						error("Cannot load configuration file %s.", optarg);
						exit(1);
					}
					else {
						debug(D_OPTIONS, "Configuration loaded from %s.", optarg);
						config_loaded = 1;
					}
					break;
				case 'D':
					dont_fork = 1;
					break;
				case 'h':
					help(0);
					break;
				case 'i':
					config_set("global", "bind to", optarg);
					break;
				case 'P':
					strncpy(pidfile, optarg, FILENAME_MAX);
					pidfile[FILENAME_MAX] = '\0';
					break;
				case 'p':
					config_set("global", "default port", optarg);
					break;
				case 's':
					config_set("global", "host access prefix", optarg);
					break;
				case 't':
					config_set("global", "update every", optarg);
					break;
				case 'u':
					config_set("global", "run as user", optarg);
					break;
				case 'v':
					// TODO: Outsource version to makefile which can compute version from git.
					printf("netdata 1.2.1_master\n");
					return 0;
					break;
				case 'W':
					{
						char* stacksize = "stacksize=";
						char* debug_flags_string = "debug_flags=";
						if(strcmp(optarg, "unittest") == 0) {
							rrd_update_every = 1;
							if(run_all_mockup_tests()) exit(1);
							if(unit_test_storage()) exit(1);
							fprintf(stderr, "\n\nALL TESTS PASSED\n\n");
							exit(0);
						} else if(strncmp(optarg, stacksize, strlen(stacksize)) == 0) {
							optarg += strlen(stacksize);
							config_set("global", "pthread stack size", optarg);
						} else if(strncmp(optarg, debug_flags_string, strlen(debug_flags_string)) == 0) {
							optarg += strlen(debug_flags_string);
							config_set("global", "debug flags",  optarg);
							debug_flags = strtoull(optarg, NULL, 0);
						}
					}
					break;
				default: /* ? */
					help(1);
					break;
			}
		}
	}

	if(!config_loaded) load_config(NULL, 0);

	// prepare configuration environment variables for the plugins
	setenv("NETDATA_CONFIG_DIR" , config_get("global", "config directory"   , CONFIG_DIR) , 1);
	setenv("NETDATA_PLUGINS_DIR", config_get("global", "plugins directory"  , PLUGINS_DIR), 1);
	setenv("NETDATA_WEB_DIR"    , config_get("global", "web files directory", WEB_DIR)    , 1);
	setenv("NETDATA_CACHE_DIR"  , config_get("global", "cache directory"    , CACHE_DIR)  , 1);
	setenv("NETDATA_LIB_DIR"    , config_get("global", "lib directory"      , VARLIB_DIR) , 1);
	setenv("NETDATA_LOG_DIR"    , config_get("global", "log directory"      , LOG_DIR)    , 1);
	setenv("NETDATA_HOST_PREFIX", config_get("global", "host access prefix" , "")         , 1);
	setenv("HOME"               , config_get("global", "home directory"     , CACHE_DIR)  , 1);

	// disable buffering for python plugins
	setenv("PYTHONUNBUFFERED", "1", 1);

	// avoid flood calls to stat(/etc/localtime)
	// http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
	setenv("TZ", ":/etc/localtime", 0);

	{
		char path[1024 + 1], *p = getenv("PATH");
		if(!p) p = "/bin:/usr/bin";
		snprintfz(path, 1024, "%s:%s", p, "/sbin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
		setenv("PATH", config_get("plugins", "PATH environment variable", path), 1);
	}

	// cd to /tmp to avoid any plugins writing files at random places
	if(chdir("/tmp")) error("netdata: ERROR: Cannot cd to /tmp");

	char *input_log_file = NULL;
	char *output_log_file = NULL;
	char *error_log_file = NULL;
	char *access_log_file = NULL;
	char *user = NULL;
	{
		char *flags = config_get("global", "debug flags",  "0x00000000");
		setenv("NETDATA_DEBUG_FLAGS", flags, 1);

		debug_flags = strtoull(flags, NULL, 0);
		debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);

		if(debug_flags != 0) {
			struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
			if(setrlimit(RLIMIT_CORE, &rl) != 0)
				info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
		}

		// --------------------------------------------------------------------

#ifdef MADV_MERGEABLE
		enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm);
#else
#warning "Kernel memory deduplication (KSM) is not available"
#endif

		// --------------------------------------------------------------------


		global_host_prefix = config_get("global", "host access prefix", "");
		setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);

		// --------------------------------------------------------------------

		output_log_file = config_get("global", "debug log", LOG_DIR "/debug.log");
		if(strcmp(output_log_file, "syslog") == 0) {
			output_log_syslog = 1;
			output_log_file = NULL;
		}
		else if(strcmp(output_log_file, "none") == 0) {
			output_log_syslog = 0;
			output_log_file = NULL;
		}
		else output_log_syslog = 0;

		// --------------------------------------------------------------------

		error_log_file = config_get("global", "error log", LOG_DIR "/error.log");
		if(strcmp(error_log_file, "syslog") == 0) {
			error_log_syslog = 1;
			error_log_file = NULL;
		}
		else if(strcmp(error_log_file, "none") == 0) {
			error_log_syslog = 0;
			error_log_file = NULL;
			// optimization - do not even generate debug log entries
		}
		else error_log_syslog = 0;

		error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period);
		setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period"    , ""), 1);

		error_log_errors_per_period = (unsigned long)config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period);
		setenv("NETDATA_ERRORS_PER_PERIOD"     , config_get("global", "errors to trigger flood protection", ""), 1);

		// --------------------------------------------------------------------

		access_log_file = config_get("global", "access log", LOG_DIR "/access.log");
		if(strcmp(access_log_file, "syslog") == 0) {
			access_log_syslog = 1;
			access_log_file = NULL;
		}
		else if(strcmp(access_log_file, "none") == 0) {
			access_log_syslog = 0;
			access_log_file = NULL;
		}
		else access_log_syslog = 0;

		// --------------------------------------------------------------------

		rrd_memory_mode = rrd_memory_mode_id(config_get("global", "memory mode", rrd_memory_mode_name(rrd_memory_mode)));

		// --------------------------------------------------------------------

		{
			char hostnamebuf[HOSTNAME_MAX + 1];
			if(gethostname(hostnamebuf, HOSTNAME_MAX) == -1)
				error("WARNING: Cannot get machine hostname.");
			hostname = config_get("global", "hostname", hostnamebuf);
			debug(D_OPTIONS, "hostname set to '%s'", hostname);
		}

		// --------------------------------------------------------------------

		rrd_default_history_entries = (int) config_get_number("global", "history", RRD_DEFAULT_HISTORY_ENTRIES);
		if(rrd_default_history_entries < 5 || rrd_default_history_entries > RRD_HISTORY_ENTRIES_MAX) {
			info("Invalid save lines %d given. Defaulting to %d.", rrd_default_history_entries, RRD_DEFAULT_HISTORY_ENTRIES);
			rrd_default_history_entries = RRD_DEFAULT_HISTORY_ENTRIES;
		}
		else {
			debug(D_OPTIONS, "save lines set to %d.", rrd_default_history_entries);
		}

		// --------------------------------------------------------------------

		rrd_update_every = (int) config_get_number("global", "update every", UPDATE_EVERY);
		if(rrd_update_every < 1 || rrd_update_every > 600) {
			info("Invalid update timer %d given. Defaulting to %d.", rrd_update_every, UPDATE_EVERY_MAX);
			rrd_update_every = UPDATE_EVERY;
		}
		else debug(D_OPTIONS, "update timer set to %d.", rrd_update_every);

		// let the plugins know the min update_every
		{
			char buf[16];
			snprintfz(buf, 15, "%d", rrd_update_every);
			setenv("NETDATA_UPDATE_EVERY", buf, 1);
		}

		// --------------------------------------------------------------------

		// block signals while initializing threads.
		// this causes the threads to block signals.
		sigset_t sigset;
		sigfillset(&sigset);

		if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1) {
			error("Could not block signals for threads");
		}

		// Catch signals which we want to use to quit savely
		struct sigaction sa;
		sigemptyset(&sa.sa_mask);
		sigaddset(&sa.sa_mask, SIGHUP);
		sigaddset(&sa.sa_mask, SIGINT);
		sigaddset(&sa.sa_mask, SIGTERM);
		sa.sa_handler = sig_handler_exit;
		sa.sa_flags = 0;
		if(sigaction(SIGHUP, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGHUP");
		}
		if(sigaction(SIGINT, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGINT");
		}
		if(sigaction(SIGTERM, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGTERM");
		}

		// save database on SIGUSR1
		sa.sa_handler = sig_handler_save;
		if(sigaction(SIGUSR1, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGUSR1");
		}

		// Ignore SIGPIPE completely.
		// INFO: If we add signals here we have to unblock them
		// at popen.c when running a external plugin.
		sa.sa_handler = SIG_IGN;
		if(sigaction(SIGPIPE, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGPIPE");
		}

		// --------------------------------------------------------------------

		i = pthread_attr_init(&attr);
		if(i != 0)
			fatal("pthread_attr_init() failed with code %d.", i);

		i = pthread_attr_getstacksize(&attr, &stacksize);
		if(i != 0)
			fatal("pthread_attr_getstacksize() failed with code %d.", i);
		else
			debug(D_OPTIONS, "initial pthread stack size is %zu bytes", stacksize);

		wanted_stacksize = config_get_number("global", "pthread stack size", stacksize);

		// --------------------------------------------------------------------

		for (i = 0; static_threads[i].name != NULL ; i++) {
			struct netdata_static_thread *st = &static_threads[i];

			if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled);
			if(st->enabled && st->init_routine) st->init_routine();
		}

		// --------------------------------------------------------------------

		// get the user we should run
		// IMPORTANT: this is required before web_files_uid()
		user = config_get("global", "run as user"    , (getuid() == 0)?NETDATA_USER:"");

		// IMPORTANT: these have to run once, while single threaded
		web_files_uid(); // IMPORTANT: web_files_uid() before web_files_gid()
		web_files_gid();

		// --------------------------------------------------------------------

		create_listen_sockets();
	}

	// never become a problem
	if(nice(20) == -1) error("Cannot lower my CPU priority.");

	if(become_daemon(dont_fork, 0, user, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1)
		fatal("Cannot demonize myself.");

#ifdef NETDATA_INTERNAL_CHECKS
	if(debug_flags != 0) {
		struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
		if(setrlimit(RLIMIT_CORE, &rl) != 0)
			info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
		prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
	}
#endif /* NETDATA_INTERNAL_CHECKS */

	if(output_log_syslog || error_log_syslog || access_log_syslog)
		openlog("netdata", LOG_PID, LOG_DAEMON);

	info("NetData started on pid %d", getpid());


	// ------------------------------------------------------------------------
	// get default pthread stack size

	if(stacksize < wanted_stacksize) {
		i = pthread_attr_setstacksize(&attr, wanted_stacksize);
		if(i != 0)
			fatal("pthread_attr_setstacksize() to %zu bytes, failed with code %d.", wanted_stacksize, i);
		else
			info("Successfully set pthread stacksize to %zu bytes", wanted_stacksize);
	}

	// --------------------------------------------------------------------
	// initialize the registry

	registry_init();

	// ------------------------------------------------------------------------
	// spawn the threads

	web_server_threading_selection();

	for (i = 0; static_threads[i].name != NULL ; i++) {
		struct netdata_static_thread *st = &static_threads[i];

		if(st->enabled) {
			st->thread = malloc(sizeof(pthread_t));
			if(!st->thread)
				fatal("Cannot allocate pthread_t memory");

			info("Starting thread %s.", st->name);

			if(pthread_create(st->thread, &attr, st->start_routine, NULL))
				error("failed to create new thread for %s.", st->name);

			else if(pthread_detach(*st->thread))
				error("Cannot request detach of newly created %s thread.", st->name);
		}
		else info("Not starting thread %s.", st->name);
	}

	// ------------------------------------------------------------------------
	// block signals while initializing threads.
	sigset_t sigset;
	sigfillset(&sigset);

	if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
		error("Could not unblock signals for threads");
	}

	// Handle flags set in the signal handler.
	while(1) {
		pause();
		if(netdata_exit) {
			info("Exit main loop of netdata.");
			netdata_cleanup_and_exit(0);
			exit(0);
		}
	}
}
Ejemplo n.º 8
0
static void* GetActualStackSizeFn(void* arg) {
  pthread_attr_t attributes;
  pthread_getattr_np(pthread_self(), &attributes);
  pthread_attr_getstacksize(&attributes, reinterpret_cast<size_t*>(arg));
  return NULL;
}
Ejemplo n.º 9
0
pthread_t ydb_storage_syncquery_init(
        SpxLogDelegate *log,
        u32_t timeout,
        struct ydb_storage_configurtion *config,\
        err_t *err){/*{{{*/
    struct spx_job_context_transport arg;
    SpxZero(arg);
    arg.timeout = timeout;
    arg.nio_reader = spx_nio_reader;
    arg.nio_writer = spx_nio_writer;
    arg.log = log;
    arg.reader_body_process = ydb_storage_syncquery_nio_body_reader;
    arg.writer_body_process = ydb_storage_syncquery_nio_body_writer;
    arg.config = config;
    sync_timer = spx_alloc_alone(sizeof(*sync_timer),err);
    if(NULL == sync_timer){
        SpxLog2(log,SpxLogError,*err,"alloc sync timer is fail.");
        goto r1;
    }
    sloop = ev_loop_new(0);
    if(NULL == sloop){
        *err = errno;
        SpxLog2(log,SpxLogError,*err,\
                "new event loop for sync is fail.");
        goto r1;
    }

    if(!ydb_storage_get_remote(config,&arg)){
        goto r1;
    }

    pthread_t tid = 0;
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    size_t ostack_size = 0;
    pthread_attr_getstacksize(&attr, &ostack_size);
    do{
        if (ostack_size != config->stacksize
                && (0 != (*err = pthread_attr_setstacksize(&attr,config->stacksize)))){
            pthread_attr_destroy(&attr);
            SpxLog2(log,SpxLogError,*err,\
                    "set thread stack size is fail.");
            goto r1;
        }
        if (0 !=(*err =  pthread_create(&(tid), &attr,
                        ydb_storage_syncquery_heartbeat,
                        NULL))){
            pthread_attr_destroy(&attr);
            SpxLog2(log,SpxLogError,*err,\
                    "create heartbeat thread is fail.");
            goto r1;
        }
    }while(false);
    pthread_attr_destroy(&attr);
    return tid;
r1:
    if(NULL != sync_timer){
        SpxFree(sync_timer);
    }
    return 0;
}/*}}}*/
Ejemplo n.º 10
0
DirectResult
direct_thread_init( DirectThread *thread )
{
     pthread_attr_t     attr;
     struct sched_param param;
     int                policy;
     int                priority;

     direct_once( &thread_init_once, init_once );

     /* Initialize scheduling and other parameters. */
     pthread_attr_init( &attr );

#ifdef PTHREAD_EXPLICIT_SCHED
     pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
#endif

     /* Select scheduler. */
     switch (direct_config->thread_scheduler) {
          case DCTS_FIFO:
               policy = SCHED_FIFO;
               break;

          case DCTS_RR:
               policy = SCHED_RR;
               break;

          default:
               policy = SCHED_OTHER;
               break;
     }

     if (pthread_attr_setschedpolicy( &attr, policy ))
          D_PERROR( "Direct/Thread: Could not set scheduling policy to %s!\n", direct_thread_policy_name(policy) );

     /* Read (back) value. */
     pthread_attr_getschedpolicy( &attr, &policy );

     /* Select priority. */
     switch (thread->type) {
          case DTT_CLEANUP:
          case DTT_INPUT:
          case DTT_OUTPUT:
          case DTT_MESSAGING:
          case DTT_CRITICAL:
               priority = thread->type * direct_config->thread_priority_scale / 100;
               break;

          default:
               priority = direct_config->thread_priority;
               break;
     }

     D_DEBUG_AT( Direct_ThreadInit, "  -> %s (%d) [%d;%d]\n", direct_thread_policy_name(policy), priority,
                 sched_get_priority_min( policy ), sched_get_priority_max( policy ) );

     if (priority < sched_get_priority_min( policy ))
          priority = sched_get_priority_min( policy );

     if (priority > sched_get_priority_max( policy ))
          priority = sched_get_priority_max( policy );

     param.sched_priority = priority;

     if (pthread_attr_setschedparam( &attr, &param ))
          D_PERROR( "Direct/Thread: Could not set scheduling priority to %d!\n", priority );

     /* Select stack size? */
     if (direct_config->thread_stack_size > 0) {
          if (pthread_attr_setstacksize( &attr, direct_config->thread_stack_size ))
               D_PERROR( "Direct/Thread: Could not set stack size to %d!\n", direct_config->thread_stack_size );
     }


     if (pthread_create( &thread->handle.thread, &attr, direct_thread_main, thread ))
          return errno2result( errno );

     pthread_attr_destroy( &attr );

     /* Read (back) value. */
     pthread_getattr_np( thread->handle.thread, &attr );
     pthread_attr_getstacksize( &attr, &thread->stack_size );
     pthread_attr_getschedparam( &attr, &param );
     thread->priority = param.sched_priority;
     pthread_attr_destroy( &attr );

     return DR_OK;
}
Ejemplo n.º 11
0
void *my_thread(void *arg){
    int retval = 0;
    pthread_attr_t attr;
    struct sched_param param;
    size_t stacksize;
    int detachstate;
    int scope;
    int inherit;
    int policy;

    if(pthread_attr_init (&attr) == 0){

        if(pthread_attr_getstacksize(&attr, &stacksize) == 0){
            printf("StackSize :%d\n", stacksize);
        }

        if(pthread_attr_getdetachstate (&attr, &detachstate) == 0){

            if(detachstate == PTHREAD_CREATE_JOINABLE){
                printf("DetachState : PTHREAD_CREATE_JOINABLE\n");
            }else if(detachstate == PTHREAD_CREATE_DETACHED){
                printf("DetachState:PTHREAD_CREATE_DETACHED\n");
            }
        }

        if(pthread_attr_getscope (&attr, &scope) == 0){
            if(scope == PTHREAD_SCOPE_PROCESS){
                printf("Scope : PTHREAD_SCOPE_PROCESS\n");
            }else if(scope == PTHREAD_SCOPE_SYSTEM){
                printf("Scope : PTHREAD_SCOPE_SYSTEM\n");
            }
        }


        if(pthread_attr_getinheritsched(&attr, &inherit) == 0){
            if(inherit == PTHREAD_INHERIT_SCHED){
                printf("InheritSched : PTHREAD_INHERIT_SCHED\n");
            }else if(inherit == PTHREAD_EXPLICIT_SCHED){
                printf("InheritSched : PTHREAD_EXPLICIT_SCHED\n");
            }
        }

        if(pthread_attr_getschedpolicy (&attr, &policy) == 0){
            if(policy == SCHED_FIFO){
                printf("SchedPolicy : SCHED_FIFO\n");
            }else if(policy == SCHED_RR){
                printf("SchedPolicy:SCHED_RR\n");
            }else{
                printf("SchedPolicy :SCHED_OTHER\n");
            }
        }

        if(pthread_attr_getschedparam (&attr, &param) == 0){
            printf("schedPriority:%d\n", param.sched_priority);
        }

        pthread_attr_destroy (&attr);
    }

    pthread_exit(&retval);
}
Ejemplo n.º 12
0
/**
 * Create a thread.  Note: thread values are not supported on OS/2.
 *    execution starts on the thread immediately. To pause execution 
 *    use a Mutex between the thread and the thread creator.
 *
 * @param   thread the thread object to be created
 * @param   thread_function the function for the thread to start execution on
 * @param   thread_arg the arguments to the thread function
 * @return  VXItrdResult of operation.  Return SUCCESS if thread has been 
 *          created and started.
 *
 */
VXITRD_API 
VXItrdResult VXItrdThreadCreate(VXItrdThread **thread,
				VXItrdThreadStartFunc thread_function,
				VXItrdThreadArg thread_arg)
{
  if ((thread == NULL) || (thread_function == NULL))
    return VXItrd_RESULT_INVALID_ARGUMENT;

  *thread = NULL;

  // Create the wrapper object
  VXItrdThread *result = new VXItrdThread;
  if (result == NULL)
    return VXItrd_RESULT_OUT_OF_MEMORY;

  memset(result, 0, sizeof (VXItrdThread));
  result->state = STATE_STARTING;
  result->refCount = 1; // 1 for parent
  result->thread_function = thread_function;
  result->thread_arg = thread_arg;

  if (VXItrdMutexCreate(&result->refCountMutex) != VXItrd_RESULT_SUCCESS) {
    VXItrdThreadDestroyHandle(&result);
    return VXItrd_RESULT_SYSTEM_ERROR;
  }

  // construct thread attribute
  pthread_attr_t thread_attr;
  int prc = pthread_attr_init(&thread_attr);
  if (prc != 0) {
    VXItrdThreadDestroyHandle(&result);
    return VXItrd_RESULT_NON_FATAL_ERROR;
  }
  
  // configure thread attribute
#ifdef USE_DETACHED_THREADS
  prc = pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED);
  if (prc != 0) {
    pthread_attr_destroy(&thread_attr);
    VXItrdThreadDestroyHandle(&result);
    return VXItrd_RESULT_NON_FATAL_ERROR;
  }
#else
  // use joinable threads
  // this is default - no work required
#endif

  // Instead of using the default 2M as stack size, reduce it to 1M
  size_t stacksize = 0;

  prc = pthread_attr_getstacksize(&thread_attr, &stacksize);

  if (prc == 0) { 
    prc = pthread_attr_setstacksize(&thread_attr, SIPXCHANGE_STACK_SIZE_128K);
  }

  // Start the thread using our wrapper function
  result->refCount++;  // for child
  prc = pthread_create(&result->thread, &thread_attr, VXItrdThreadStart,
                       (VXItrdThreadArg) result);

  pthread_attr_destroy(&thread_attr);

  if (prc != 0) {
    result->refCount--;
    VXItrdThreadDestroyHandle(&result);
    return VXItrd_RESULT_NON_FATAL_ERROR;
  }

  *thread = result;

  return VXItrd_RESULT_SUCCESS;
}
Ejemplo n.º 13
0
void *POSIX_Init(
  void *argument
)
{
  int                 status;
  int                 scope;
  int                 inheritsched;
  int                 schedpolicy;
  size_t              stacksize;
#if HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE
  size_t              guardsize;
#endif
  void               *stackaddr;
  int                 detachstate;
  struct sched_param  schedparam;
  pthread_attr_t      attr;
  pthread_attr_t      destroyed_attr;

  TEST_BEGIN();

  /* set the time of day, and print our buffer in multiple ways */

  set_time( TM_FRIDAY, TM_MAY, 24, 96, 11, 5, 0 );

  /* get id of this thread */

  Init_id = pthread_self();
  printf( "Init's ID is 0x%08" PRIxpthread_t "\n", Init_id );

  /* exercise init and destroy */

  puts( "Init - pthread_attr_init - EINVAL (NULL attr)" );
  status = pthread_attr_init( NULL );
  fatal_directive_check_status_only( status, EINVAL, "null attribute" );

  puts( "Init - pthread_attr_init - SUCCESSFUL" );
  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init" );

  puts( "Init - initialize and destroy an attribute - SUCCESSFUL" );
  status = pthread_attr_init( &destroyed_attr );
  posix_service_failed( status, "pthread_attr_init");

  status = pthread_attr_destroy( &destroyed_attr );
  posix_service_failed( status, "pthread_attr_destroy");

  puts( "Init - pthread_attr_destroy - EINVAL (NULL attr)" );
  status = pthread_attr_destroy( NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL attribute" );

  puts( "Init - pthread_attr_destroy - EINVAL (not initialized)" );
  status = pthread_attr_destroy( &destroyed_attr );
  fatal_directive_check_status_only( status, EINVAL, "not initialized" );

  /* check some errors in pthread_create */

  puts( "Init - pthread_create - EINVAL (attr not initialized)" );
  status = pthread_create( &Task_id, &destroyed_attr, Task_1, NULL );
  fatal_directive_check_status_only( status, EINVAL, "attribute not initialized" );

  /* junk stack address */
  status = pthread_attr_setstackaddr( &attr, (void *)&schedparam );
  posix_service_failed( status, "setstackaddr");

  /* must go around pthread_attr_setstacksize to set a bad stack size */
  attr.stacksize = 0;

  puts( "Init - pthread_create - EINVAL (stacksize too small)" );
  status = pthread_create( &Task_id, &attr, Task_1, NULL );
  fatal_directive_check_status_only( status, EINVAL, "stacksize too small" );

  /* reset all the fields */
  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init");

#if HAVE_DECL_PTHREAD_ATTR_SETSTACKADDR
  attr.stacksize = rtems_configuration_get_work_space_size() * 10;
  puts( "Init - pthread_create - EAGAIN (stacksize too large)" );
  status = pthread_create( &Task_id, &attr, Task_1, NULL );
  fatal_directive_check_status_only( status, EAGAIN, "stacksize too large" );
#endif

  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init");

  /* must go around pthread_attr_set routines to set a bad value */
  attr.inheritsched = -1;

  puts( "Init - pthread_create - EINVAL (invalid inherit scheduler)" );
  status = pthread_create( &Task_id, &attr, Task_1, NULL );
  fatal_directive_check_status_only( status, EINVAL, "invalid inherit scheduler" );

  /* check out the error case for system scope not supported */

  status = pthread_attr_init( &attr );
  posix_service_failed( status, " pthread_attr_init");

  /* must go around pthread_attr_set routines to set a bad value */
  attr.contentionscope = PTHREAD_SCOPE_SYSTEM;

  puts( "Init - pthread_create - ENOTSUP (unsupported system contention scope)" );
  status = pthread_create( &Task_id, &attr, Task_1, NULL );
  fatal_directive_check_status_only( status, ENOTSUP,
    "unsupported system contention scope" );

  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init");

  /* now check out pthread_create for inherit scheduler */

  status = pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED );
  posix_service_failed( status, "pthread_attr_setinheritsched");

  puts( "Init - pthread_create - SUCCESSFUL (inherit scheduler)" );
  status = pthread_create( &Task_id, &attr, Task_1, NULL );
  posix_service_failed( status, "pthread_create");

  status = pthread_join( Task_id, NULL );
  posix_service_failed( status, " pthread_join");

    /* switch to Task_1 */

  /* exercise get and set scope */

  empty_line();

  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init");

  puts( "Init - pthread_attr_setscope - EINVAL (NULL attr)" );
  status = pthread_attr_setscope( NULL, PTHREAD_SCOPE_PROCESS );
  fatal_directive_check_status_only( status, EINVAL , "NULL attr" );

  puts( "Init - pthread_attr_setscope - ENOTSUP" );
  status = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM );
  fatal_directive_check_status_only( status, ENOTSUP, "PTHREAD_SCOPE_SYSTEM" );

  puts( "Init - pthread_attr_setscope - EINVAL (not initialized attr)" );
  status = pthread_attr_setscope( &destroyed_attr, PTHREAD_SCOPE_PROCESS );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setscope - EINVAL (invalid scope)" );
  status = pthread_attr_setscope( &attr, -1 );
  fatal_directive_check_status_only( status, EINVAL, "invalid scope" );

  puts( "Init - pthread_attr_setscope - SUCCESSFUL" );
  status = pthread_attr_setscope( &attr, PTHREAD_SCOPE_PROCESS );
  posix_service_failed( status, "pthread_attr_setscope");

  puts( "Init - pthread_attr_getscope - EINVAL (NULL attr)" );
  status = pthread_attr_getscope( NULL, &scope );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getscope - EINVAL (NULL scope)" );
  status = pthread_attr_getscope( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL scope" );

  puts( "Init - pthread_attr_getscope - EINVAL (not initialized attr)" );
  status = pthread_attr_getscope( &destroyed_attr, &scope );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getscope - SUCCESSFUL" );
  status = pthread_attr_getscope( &attr, &scope );
  posix_service_failed( status, "pthread_attr_getscope");
  printf( "Init - current scope attribute = %d\n", scope );

  /* exercise get and set inherit scheduler */

  empty_line();

  puts( "Init - pthread_attr_setinheritsched - EINVAL (NULL attr)" );
  status = pthread_attr_setinheritsched( NULL, PTHREAD_INHERIT_SCHED );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setinheritsched - EINVAL (not initialized attr)" );
  status =
     pthread_attr_setinheritsched( &destroyed_attr, PTHREAD_INHERIT_SCHED );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setinheritsched - ENOTSUP (invalid inheritsched)" );
  status = pthread_attr_setinheritsched( &attr, -1 );
  fatal_directive_check_status_only( status, ENOTSUP, "invalid inheritsched" );

  puts( "Init - pthread_attr_setinheritsched - SUCCESSFUL" );
  status = pthread_attr_setinheritsched( &attr, PTHREAD_INHERIT_SCHED );
  posix_service_failed( status, "pthread_attr_setinheritsched");

  puts( "Init - pthread_attr_getinheritsched - EINVAL (NULL attr)" );
  status = pthread_attr_getinheritsched( NULL, &inheritsched );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getinheritsched - EINVAL (NULL inheritsched)" );
  status = pthread_attr_getinheritsched( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL inheritsched" );

  puts( "Init - pthread_attr_getinheritsched - EINVAL (not initialized attr)" );
  status = pthread_attr_getinheritsched( &destroyed_attr, &inheritsched );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getinheritsched - SUCCESSFUL" );
  status = pthread_attr_getinheritsched( &attr, &inheritsched );
  posix_service_failed( status, "pthread_attr_getinheritsched");
  printf( "Init - current inherit scheduler attribute = %d\n", inheritsched );

  /* exercise get and set inherit scheduler */

  empty_line();

  puts( "Init - pthread_attr_setschedpolicy - EINVAL (NULL attr)" );
  status = pthread_attr_setschedpolicy( NULL, SCHED_FIFO );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setschedpolicy - EINVAL (not initialized attr)" );
  status =
     pthread_attr_setschedpolicy( &destroyed_attr, SCHED_OTHER );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setschedpolicy - ENOTSUP (invalid schedpolicy)" );
  status = pthread_attr_setschedpolicy( &attr, -1 );
  fatal_directive_check_status_only( status, ENOTSUP, "invalid schedpolicy" );

  puts( "Init - pthread_attr_setschedpolicy - SUCCESSFUL" );
  status = pthread_attr_setschedpolicy( &attr, SCHED_RR );
  posix_service_failed( status, "pthread_attr_setschedpolicy");

  puts( "Init - pthread_attr_getschedpolicy - EINVAL (NULL attr)" );
  status = pthread_attr_getschedpolicy( NULL, &schedpolicy );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getschedpolicy - EINVAL (NULL schedpolicy)" );
  status = pthread_attr_getschedpolicy( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL schedpolicy" );

  puts( "Init - pthread_attr_getschedpolicy - EINVAL (not initialized attr)" );
  status = pthread_attr_getschedpolicy( &destroyed_attr, &schedpolicy );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getschedpolicy - SUCCESSFUL" );
  status = pthread_attr_getschedpolicy( &attr, &schedpolicy );
  posix_service_failed( status, "pthread_attr_getschedpolicy");
  printf( "Init - current scheduler policy attribute = %d\n", schedpolicy );

  /* exercise get and set stack size */

  empty_line();

  puts( "Init - pthread_attr_setstacksize - EINVAL (NULL attr)" );
  status = pthread_attr_setstacksize( NULL, 0 );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setstacksize - EINVAL (not initialized attr)" );
  status =
     pthread_attr_setstacksize( &destroyed_attr, 0 );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setstacksize - SUCCESSFUL (low stacksize)" );
  status = pthread_attr_setstacksize( &attr, 0 );
  posix_service_failed( status, "pthread_attr_setstacksize");

  puts( "Init - pthread_attr_setstacksize - SUCCESSFUL (high stacksize)" );
  status = pthread_attr_setstacksize( &attr, STACK_MINIMUM_SIZE * 2 );
  posix_service_failed( status, "");

  puts( "Init - pthread_attr_getstacksize - EINVAL (NULL attr)" );
  status = pthread_attr_getstacksize( NULL, &stacksize );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getstacksize - EINVAL (NULL stacksize)" );
  status = pthread_attr_getstacksize( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL stacksize" );

  puts( "Init - pthread_attr_getstacksize - EINVAL (not initialized attr)" );
  status = pthread_attr_getstacksize( &destroyed_attr, &stacksize );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getstacksize - SUCCESSFUL" );
  status = pthread_attr_getstacksize( &attr, &stacksize );
  posix_service_failed( status, "pthread_attr_getstacksize");
  if ( stacksize == (STACK_MINIMUM_SIZE * 2) )
    printf( "Init - current stack size attribute is OK\n" );

  /* exercise get and set stack address */
  empty_line();

  puts( "Init - pthread_attr_setstackaddr - EINVAL (NULL attr)" );
  status = pthread_attr_setstackaddr( NULL, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setstackaddr - EINVAL (not initialized attr)" );
  status = pthread_attr_setstackaddr( &destroyed_attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setstackaddr - SUCCESSFUL" );
  status = pthread_attr_setstackaddr( &attr, 0 );
  posix_service_failed( status, "");

  /* get stack addr */
  puts( "Init - pthread_attr_getstackaddr - EINVAL (NULL attr)" );
  status = pthread_attr_getstackaddr( NULL, &stackaddr );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getstackaddr - EINVAL (NULL stackaddr)" );
  status = pthread_attr_getstackaddr( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL stackaddr" );

  puts( "Init - pthread_attr_getstackaddr - EINVAL (not initialized attr)" );
  status = pthread_attr_getstackaddr( &destroyed_attr, &stackaddr );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getstackaddr - SUCCESSFUL" );
  status = pthread_attr_getstackaddr( &attr, &stackaddr );
  posix_service_failed( status, "pthread_attr_getstackaddr");
  printf( "Init - current stack address attribute = %p\n", stackaddr );

  /* exercise get and set stack (as pair) */
  empty_line();

#if HAVE_DECL_PTHREAD_ATTR_SETSTACK
  puts( "Init - pthread_attr_setstack- EINVAL (NULL attr)" );
  status = pthread_attr_setstack( NULL, &stackaddr, 1024 );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setstack- EINVAL (destroyed attr)" );
  status = pthread_attr_setstack( &destroyed_attr, &stackaddr, 1024 );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setstack- SUCCESSFUL (< min stack)" );
  status = pthread_attr_setstack( &attr, stackaddr, 0 );
  posix_service_failed( status, "OK");

  puts( "Init - pthread_attr_setstack- SUCCESSFUL (big stack)" );
  status = pthread_attr_setstack( &attr, stackaddr, STACK_MINIMUM_SIZE * 2 );
  posix_service_failed( status, "OK");
#endif

#if HAVE_DECL_PTHREAD_ATTR_GETSTACK
  puts( "Init - pthread_attr_getstack- EINVAL (NULL attr)" );
  status = pthread_attr_getstack( NULL, &stackaddr, &stacksize );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getstack- EINVAL (destroyed attr)" );
  status = pthread_attr_getstack( &destroyed_attr, &stackaddr, &stacksize );
  fatal_directive_check_status_only( status, EINVAL, "&destroyed attr" );

  puts( "Init - pthread_attr_getstack- EINVAL (NULL stack)" );
  status = pthread_attr_getstack( &attr, NULL, &stacksize );
  fatal_directive_check_status_only( status, EINVAL, "&NULL stack" );

  puts( "Init - pthread_attr_getstack- EINVAL (NULL stacksize)" );
  status = pthread_attr_getstack( &attr, &stackaddr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "&NULL size" );

  puts( "Init - pthread_attr_getstack- SUCCESSFUL" );
  status = pthread_attr_getstack( &attr, &stackaddr, &stacksize );
  posix_service_failed( status, "pthread_attr_getstack");
#endif

  /* exercise get and set detach state */
  empty_line();

#if HAVE_DECL_PTHREAD_ATTR_SETGUARDSIZE
  puts( "Init - pthread_attr_setguardsize - EINVAL (NULL attr)" );
  status = pthread_attr_setguardsize( NULL, 0 );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setguardsize - EINVAL (not initialized attr)" );
  status = pthread_attr_setguardsize( &destroyed_attr, 0 );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setguardsize - SUCCESSFUL (low guardsize)" );
  status = pthread_attr_setguardsize( &attr, 0 );
  posix_service_failed( status, "pthread_attr_setguardsize");

  puts( "Init - pthread_attr_setguardsize - SUCCESSFUL (high guardsize)" );
  status = pthread_attr_setguardsize( &attr, STACK_MINIMUM_SIZE * 2 );
  posix_service_failed( status, "");
#endif

#if HAVE_DECL_PTHREAD_ATTR_GETGUARDSIZE
  puts( "Init - pthread_attr_getguardsize - EINVAL (NULL attr)" );
  status = pthread_attr_getguardsize( NULL, &guardsize );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getguardsize - EINVAL (NULL guardsize)" );
  status = pthread_attr_getguardsize( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL guardsize" );

  puts( "Init - pthread_attr_getguardsize - EINVAL (not initialized attr)" );
  status = pthread_attr_getguardsize( &destroyed_attr, &guardsize );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getguardsize - SUCCESSFUL" );
  status = pthread_attr_getguardsize( &attr, &guardsize );
  posix_service_failed( status, "pthread_attr_getguardsize");
#endif

  /* exercise get and set detach state */
  empty_line();

  puts( "Init - pthread_attr_setdetachstate - EINVAL (NULL attr)" );
  status = pthread_attr_setdetachstate( NULL, PTHREAD_CREATE_DETACHED );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setdetachstate - EINVAL (not initialized attr)" );
  status =
     pthread_attr_setdetachstate( &destroyed_attr, PTHREAD_CREATE_JOINABLE );
  fatal_directive_check_status_only( status, EINVAL, "not initialized att" );

  puts( "Init - pthread_attr_setdetachstate - EINVAL (invalid detachstate)" );
  status = pthread_attr_setdetachstate( &attr, -1 );
  fatal_directive_check_status_only( status, EINVAL, "invalid detachstate" );

  puts( "Init - pthread_attr_setdetachstate - SUCCESSFUL" );
  status = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE );
  posix_service_failed( status, "pthread_attr_setdetachstate");

  puts( "Init - pthread_attr_getdetachstate - EINVAL (NULL attr)" );
  status = pthread_attr_getdetachstate( NULL, &detachstate );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_getdetachstate - EINVAL (NULL detatchstate)" );
  status = pthread_attr_getdetachstate( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL detatchstate" );

  puts( "Init - pthread_attr_getdetachstate - EINVAL (not initialized attr)" );
  status = pthread_attr_getdetachstate( &destroyed_attr, &detachstate );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getdetachstate - SUCCESSFUL" );
  status = pthread_attr_getdetachstate( &attr, &detachstate );
  posix_service_failed( status, "pthread_attr_getdetachstate");
  printf( "Init - current detach state attribute = %d\n", detachstate );

  /* exercise get and set scheduling parameters */

  empty_line();

  puts( "Init - pthread_attr_getschedparam - SUCCESSFUL" );
  status = pthread_attr_getschedparam( &attr, &schedparam );
  posix_service_failed( status, "pthread_attr_getschedparam");

  print_schedparam( "Init - ", &schedparam );

  puts( "Init - pthread_attr_setschedparam - EINVAL (NULL attr)" );
  status = pthread_attr_setschedparam( NULL, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "NULL attr" );

  puts( "Init - pthread_attr_setschedparam - EINVAL (not initialized attr)" );
  status = pthread_attr_setschedparam( &destroyed_attr, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_setschedparam - EINVAL (NULL schedparam)" );
  status = pthread_attr_setschedparam( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL schedparam" );

  puts( "Init - pthread_attr_setschedparam - SUCCESSFUL" );
  status = pthread_attr_setschedparam( &attr, &schedparam );
  posix_service_failed( status, "pthread_attr_setschedparam");

  puts( "Init - pthread_attr_getschedparam - EINVAL (NULL attr)" );
  status = pthread_attr_getschedparam( NULL, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "pthread_attr_getschedparam" );

  puts( "Init - pthread_attr_getschedparam - EINVAL (not initialized attr)" );
  status = pthread_attr_getschedparam( &destroyed_attr, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "not initialized attr" );

  puts( "Init - pthread_attr_getschedparam - EINVAL (NULL schedparam)" );
  status = pthread_attr_getschedparam( &attr, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL schedparam" );

  /* exercise pthread_getschedparam */

  empty_line();

  puts( "Init - pthread_getschedparam - EINVAL (NULL policy)" );
  status = pthread_getschedparam( pthread_self(), NULL, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "NULL policy" );

  puts( "Init - pthread_getschedparam - EINVAL (NULL schedparam)" );
  status = pthread_getschedparam( pthread_self(), &schedpolicy, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL schedparam" );

  puts( "Init - pthread_getschedparam - ESRCH (bad thread)" );
  status = pthread_getschedparam( (pthread_t) -1, &schedpolicy, &schedparam );
  fatal_directive_check_status_only( status, ESRCH, "bad thread" );

  puts( "Init - pthread_getschedparam - SUCCESSFUL" );
  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
  posix_service_failed( status, "pthread_getschedparam");

  printf( "Init - policy = %d\n", schedpolicy );

  print_schedparam( "Init - ", &schedparam );

  /* exercise pthread_setschedparam */

  empty_line();

  puts( "Init - pthread_setschedparam - EINVAL (NULL schedparam)" );
  status = pthread_setschedparam( pthread_self(), SCHED_OTHER, NULL );
  fatal_directive_check_status_only( status, EINVAL, "NULL schedparam" );

  schedparam.sched_priority = -1;

  puts( "Init - pthread_setschedparam - EINVAL (invalid priority)" );
  status = pthread_setschedparam( pthread_self(), SCHED_OTHER, NULL );
  fatal_directive_check_status_only( status, EINVAL, "invalid priority" );

  /* reset sched_param */
  status = pthread_getschedparam( pthread_self(), &schedpolicy, &schedparam );
  posix_service_failed( status, "pthread_getschedparam");

  puts( "Init - pthread_setschedparam - EINVAL (invalid policy)" );
  status = pthread_setschedparam( pthread_self(), -1, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "invalid policy" );

  puts( "Init - pthread_setschedparam - ESRCH (invalid thread)" );
  status = pthread_setschedparam( (pthread_t) -1, SCHED_OTHER, &schedparam );
  fatal_directive_check_status_only( status, ESRCH, "invalid thread" );

  /* now get sporadic server errors */

  schedparam.sched_ss_repl_period.tv_sec = 0;
  schedparam.sched_ss_repl_period.tv_nsec = 0;
  schedparam.sched_ss_init_budget.tv_sec = 1;
  schedparam.sched_ss_init_budget.tv_nsec = 1;

  puts( "Init - pthread_setschedparam - EINVAL (replenish == 0)" );
  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "replenish == 0" );

  schedparam.sched_ss_repl_period.tv_sec = 1;
  schedparam.sched_ss_repl_period.tv_nsec = 1;
  schedparam.sched_ss_init_budget.tv_sec = 0;
  schedparam.sched_ss_init_budget.tv_nsec = 0;

  puts( "Init - pthread_setschedparam - EINVAL (budget == 0)" );
  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "budget == 0" );

  schedparam.sched_ss_repl_period.tv_sec = 1;
  schedparam.sched_ss_repl_period.tv_nsec = 0;
  schedparam.sched_ss_init_budget.tv_sec = 1;
  schedparam.sched_ss_init_budget.tv_nsec = 1;

  puts( "Init - pthread_setschedparam - EINVAL (replenish < budget)" );
  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "replenish < budget" );

  schedparam.sched_ss_repl_period.tv_sec = 2;
  schedparam.sched_ss_repl_period.tv_nsec = 0;
  schedparam.sched_ss_init_budget.tv_sec = 1;
  schedparam.sched_ss_init_budget.tv_nsec = 0;
  schedparam.sched_ss_low_priority = -1;

  puts( "Init - pthread_setschedparam - EINVAL (invalid priority)" );
  status = pthread_setschedparam( pthread_self(), SCHED_SPORADIC, &schedparam );
  fatal_directive_check_status_only( status, EINVAL, "invalid priority" );

  /*
   *  Create a sporadic thread that doesn't need it's priority
   *  boosted
   */
  empty_line();

  puts( "Init - pthread_attr_init - SUCCESSFUL" );
  status = pthread_attr_init( &attr );
  posix_service_failed( status, "pthread_attr_init" );

  puts( "Init - pthread_attr_setinheritsched - EXPLICIT - SUCCESSFUL" );
  status = pthread_attr_setinheritsched( &attr, PTHREAD_EXPLICIT_SCHED );
  rtems_test_assert( !status );

  schedparam.sched_ss_repl_period.tv_sec = 3;
  schedparam.sched_ss_repl_period.tv_nsec = 3;
  schedparam.sched_ss_init_budget.tv_sec = 1;
  schedparam.sched_ss_init_budget.tv_nsec = 1;
  schedparam.sched_priority = sched_get_priority_max( SCHED_FIFO );
  schedparam.sched_ss_low_priority = sched_get_priority_max( SCHED_FIFO ) - 6;

  puts( "Init - pthread_attr_setschedpolicy - SUCCESSFUL" );
  status = pthread_attr_setschedpolicy( &attr, SCHED_SPORADIC );
  posix_service_failed( status, "pthread_attr_setschedparam");
  puts( "Init - pthread_attr_setschedparam - SUCCESSFUL" );
  status = pthread_attr_setschedparam( &attr, &schedparam );
  posix_service_failed( status, "pthread_attr_setschedparam");

  status = pthread_create( &Task2_id, &attr, Task_2, NULL );
  rtems_test_assert( !status );

  status = pthread_join( Task2_id, NULL );
  posix_service_failed( status, " pthread_join");

  TEST_END();
  rtems_test_exit( 0 );

  return NULL; /* just so the compiler thinks we returned something */
}
Ejemplo n.º 14
0
TEST(pthread, pthread_attr_getstack__main_thread) {
  // This test is only meaningful for the main thread, so make sure we're running on it!
  ASSERT_EQ(getpid(), syscall(__NR_gettid));

  // Get the main thread's attributes.
  pthread_attr_t attributes;
  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));

  // Check that we correctly report that the main thread has no guard page.
  size_t guard_size;
  ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
  ASSERT_EQ(0U, guard_size); // The main thread has no guard page.

  // Get the stack base and the stack size (both ways).
  void* stack_base;
  size_t stack_size;
  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
  size_t stack_size2;
  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));

  // The two methods of asking for the stack size should agree.
  EXPECT_EQ(stack_size, stack_size2);

#if defined(__BIONIC__)
  // What does /proc/self/maps' [stack] line say?
  void* maps_stack_hi = NULL;
  FILE* fp = fopen("/proc/self/maps", "r");
  ASSERT_TRUE(fp != NULL);
  char line[BUFSIZ];
  while (fgets(line, sizeof(line), fp) != NULL) {
    uintptr_t lo, hi;
    char name[10];
    sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name);
    if (strcmp(name, "[stack]") == 0) {
      maps_stack_hi = reinterpret_cast<void*>(hi);
      break;
    }
  }
  fclose(fp);

  // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size.
  // Remember that the stack grows down (and is mapped in on demand), so the low address of the
  // region isn't very interesting.
  EXPECT_EQ(maps_stack_hi, reinterpret_cast<uint8_t*>(stack_base) + stack_size);

  // The stack size should correspond to RLIMIT_STACK.
  rlimit rl;
  ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl));
  uint64_t original_rlim_cur = rl.rlim_cur;
  if (rl.rlim_cur == RLIM_INFINITY) {
    rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB.
  }
  EXPECT_EQ(rl.rlim_cur, stack_size);

  auto guard = make_scope_guard([&rl, original_rlim_cur]() {
    rl.rlim_cur = original_rlim_cur;
    ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
  });

  //
  // What if RLIMIT_STACK is smaller than the stack's current extent?
  //
  rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already.
  rl.rlim_max = RLIM_INFINITY;
  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));

  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));

  EXPECT_EQ(stack_size, stack_size2);
  ASSERT_EQ(1024U, stack_size);

  //
  // What if RLIMIT_STACK isn't a whole number of pages?
  //
  rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages.
  rl.rlim_max = RLIM_INFINITY;
  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));

  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));

  EXPECT_EQ(stack_size, stack_size2);
  ASSERT_EQ(6666U, stack_size);
#endif
}
Ejemplo n.º 15
0
thread_t *
thread_create (
    thread_init_func initial_function,
    unsigned long stack_size,
    void *initial_argument)
{
  thread_t *thr;
  int rc;

  assert (_main_thread != NULL);

  if (stack_size == 0)
    stack_size = THREAD_STACK_SIZE;

#if (SIZEOF_VOID_P == 8)
  stack_size *= 2;
#endif
#if defined (__x86_64 ) && defined (SOLARIS)
  /*GK: the LDAP on that platform requires that */
  stack_size *= 2;
#endif
#ifdef HPUX_ITANIUM64
  stack_size += 8 * 8192;
#endif

  stack_size = ((stack_size / 8192) + 1) * 8192;

#if defined (PTHREAD_STACK_MIN)
  if (stack_size < PTHREAD_STACK_MIN)
    {
      stack_size = PTHREAD_STACK_MIN;
    }
#endif
  /* Any free threads with the right stack size? */
  Q_LOCK ();
  for (thr = (thread_t *) _deadq.thq_head.thr_next;
       thr != (thread_t *) &_deadq.thq_head;
       thr = (thread_t *) thr->thr_hdr.thr_next)
    {
      /* if (thr->thr_stack_size >= stack_size) */
	break;
    }
  Q_UNLOCK ();

  /* No free threads, create a new one */
  if (thr == (thread_t *) &_deadq.thq_head)
    {
#ifndef OLD_PTHREADS
      size_t os_stack_size = stack_size;
#endif
      thr = thread_alloc ();
      thr->thr_initial_function = initial_function;
      thr->thr_initial_argument = initial_argument;
      thr->thr_stack_size = stack_size;
      if (thr->thr_cv == NULL)
	goto failed;

#ifdef HPUX_ITANIUM64
      if (stack_size > PTHREAD_STACK_MIN)
        {
	  size_t s, rses;
          pthread_attr_getstacksize (&_thread_attr, &s);
	  pthread_attr_getrsestacksize_np (&_thread_attr, &rses);
	  log_error ("default rses=%d stack=%d : %m", rses,s);
	}
#endif


#ifndef OLD_PTHREADS
# if  defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
      rc = pthread_attr_setstacksize (&_thread_attr, stack_size);
      if (rc)
	{
          log_error ("Failed setting the OS thread stack size to %d : %m", stack_size);
	}
# endif

#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE)
      if (0 == pthread_attr_getstacksize (&_thread_attr, &os_stack_size))
	{
	  if (os_stack_size > 4 * 8192)
	    stack_size = thr->thr_stack_size = ((unsigned long) os_stack_size) - 4 * 8192;
	}
#endif
#ifdef HPUX_ITANIUM64
      if (stack_size > PTHREAD_STACK_MIN)
        {
	  size_t rsestack_size = stack_size / 2;
          rc = pthread_attr_setrsestacksize_np (&_thread_attr, rsestack_size);
	  if (rc)
	    {
	      log_error ("Failed setting the OS thread 'rse' stack size to %d (plain stack size set to %d) : %m", rsestack_size, stack_size);
	    }
	  thr->thr_stack_size /= 2;
	}
#endif

      rc = pthread_create ((pthread_t *) thr->thr_handle, &_thread_attr,
	  _thread_boot, thr);
      CKRET (rc);

      /* rc = pthread_detach (*(pthread_t *) thr->thr_handle); */
      /* CKRET (rc); */

#else /* OLD_PTHREAD */
      rc = pthread_attr_setstacksize (&_thread_attr, stack_size);
      CKRET (rc);

      rc = pthread_create ((pthread_t *) thr->thr_handle, _thread_attr,
	  _thread_boot, thr);
      CKRET (rc);

      /* rc = pthread_detach ((pthread_t *) thr->thr_handle); */
      /* CKRET (rc); */
#endif

      _thread_num_total++;
#if 0
      if (DO_LOG(LOG_THR))
	log_info ("THRD_0 OS threads create (%i)", _thread_num_total);
#endif
      thread_set_priority (thr, NORMAL_PRIORITY);
    }
  else
    {
      Q_LOCK ();
      thread_queue_remove (&_deadq, thr);
      _thread_num_dead--;
      Q_UNLOCK ();
      assert (thr->thr_status == DEAD);
      /* Set new context for the thread and resume it */
      thr->thr_initial_function = initial_function;
      thr->thr_initial_argument = initial_argument;
      thr->thr_status = RUNNABLE;
      rc = pthread_cond_signal ((pthread_cond_t *) thr->thr_cv);
      CKRET (rc);
/*    if (DO_LOG(LOG_THR))
	log_info ("THRD_3 OS threads reuse. Info threads - total (%ld) wait (%ld) dead (%ld)",
            _thread_num_total, _thread_num_wait, _thread_num_dead);*/
    }

  return thr;

failed:
  if (thr->thr_status == RUNNABLE)
    {
      _thread_free_attributes (thr);
      dk_free (thr, sizeof (thread_t));
    }
  return NULL;
}
Ejemplo n.º 16
0
int
GC_pthread_create(pthread_t *new_thread,
          const pthread_attr_t *attr_in,
          void * (*thread_execp)(void *), void *arg)
{
    int result;
    GC_thread t;
    pthread_t my_new_thread;
    pthread_attr_t  attr;
    word my_flags = 0;
    int  flag;
    void * stack = 0;
    size_t stack_size = 0;
    int    n;
    struct sched_param schedparam;
   
    (void)pthread_attr_init(&attr);
    if (attr_in != 0) {
	(void)pthread_attr_getstacksize(attr_in, &stack_size);
	(void)pthread_attr_getstackaddr(attr_in, &stack);
    }

    LOCK();
    if (!GC_is_initialized) {
	    GC_init_inner();
    }
    GC_multithreaded++;
	    
    if (stack == 0) {
     	if (stack_size == 0)
		stack_size = 1048576;
			  /* ^-- 1 MB (this was GC_min_stack_sz, but that
			   * violates the pthread_create documentation which
			   * says the default value if none is supplied is
			   * 1MB) */
	else
		stack_size += thr_min_stack();

     	stack = (void *)GC_stack_alloc(&stack_size);
     	if (stack == 0) {
	    GC_multithreaded--;
     	    UNLOCK();
	    errno = ENOMEM;
     	    return -1;
     	}
    } else {
    	my_flags |= CLIENT_OWNS_STACK;
    }
    (void)pthread_attr_setstacksize(&attr, stack_size);
    (void)pthread_attr_setstackaddr(&attr, stack);
    if (attr_in != 0) {
	(void)pthread_attr_getscope(attr_in, &n);
	(void)pthread_attr_setscope(&attr, n);
	(void)pthread_attr_getschedparam(attr_in, &schedparam);
	(void)pthread_attr_setschedparam(&attr, &schedparam);
	(void)pthread_attr_getschedpolicy(attr_in, &n);
	(void)pthread_attr_setschedpolicy(&attr, n);
	(void)pthread_attr_getinheritsched(attr_in, &n);
	(void)pthread_attr_setinheritsched(&attr, n);

	(void)pthread_attr_getdetachstate(attr_in, &flag);
	if (flag == PTHREAD_CREATE_DETACHED) {
		my_flags |= DETACHED;
	}
	(void)pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
    }
    /*
     * thr_create can call malloc(), which if redirected will
     * attempt to acquire the allocation lock.
     * Unlock here to prevent deadlock.
     */


#if 0
#ifdef I386
    UNLOCK();
#endif
#endif
    result = 
	    pthread_create(&my_new_thread, &attr, thread_execp, arg);
#if 0
#ifdef I386
    LOCK();
#endif
#endif
    if (result == 0) {
        t = GC_new_thread(my_new_thread);
        t -> flags = my_flags;
        if (!(my_flags & DETACHED)) cond_init(&(t->join_cv), USYNC_THREAD, 0);
        t -> stack = stack;
        t -> stack_size = stack_size;
        if (new_thread != 0) *new_thread = my_new_thread;
        pthread_cond_signal(&GC_create_cv);
    } else {
	    if (!(my_flags & CLIENT_OWNS_STACK)) {
		    GC_stack_free(stack, stack_size);
	    }        
	    GC_multithreaded--;
    }
    UNLOCK();
    pthread_attr_destroy(&attr);
    return(result);
}
Ejemplo n.º 17
0
int main(int argc, char** argv)
{
    {
        size_t stacksize;
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &stacksize);
        defaultStackSize = stacksize * 2;
    }

    Rct::findExecutablePath(*argv);

    struct option opts[] = {
        { "help", no_argument, 0, 'h' },
        { "include-path", required_argument, 0, 'I' },
        { "include", required_argument, 0, 'i' },
        { "define", required_argument, 0, 'D' },
        { "log-file", required_argument, 0, 'L' },
        { "no-builtin-includes", no_argument, 0, 'U' },
        { "setenv", required_argument, 0, 'e' },
        { "no-Wall", no_argument, 0, 'W' },
        { "append", no_argument, 0, 'A' },
        { "verbose", no_argument, 0, 'v' },
        { "thread-count", required_argument, 0, 'j' },
        { "clean-slate", no_argument, 0, 'C' },
        { "enable-sighandler", no_argument, 0, 's' },
        { "silent", no_argument, 0, 'S' },
        { "validate", no_argument, 0, 'V' },
        { "exclude-filter", required_argument, 0, 'x' },
        { "socket-file", required_argument, 0, 'n' },
        { "rc-file", required_argument, 0, 'c' },
        { "no-rc", no_argument, 0, 'N' },
        { "data-dir", required_argument, 0, 'd' },
        { "ignore-printf-fixits", no_argument, 0, 'F' },
        { "unlimited-errors", no_argument, 0, 'f' },
        { "completion-cache-size", required_argument, 0, 'a' },
        { "no-spell-checking", no_argument, 0, 'l' },
        { "large-by-value-copy", required_argument, 0, 'r' },
        { "allow-multiple-builds", no_argument, 0, 'm' },
        { "unload-timer", required_argument, 0, 'u' },
        { "no-current-project", no_argument, 0, 'o' },
        { "clang-stack-size", required_argument, 0, 't' },
        { "ignore-compiler", required_argument, 0, 'b' },
        { "compiler-flags", no_argument, 0, 'G' },
        { 0, 0, 0, 0 }
    };
    const String shortOptions = Rct::shortOptions(opts);
    if (getenv("RTAGS_DUMP_UNUSED")) {
        String unused;
        for (int i=0; i<26; ++i) {
            if (!shortOptions.contains('a' + i))
                unused.append('a' + i);
            if (!shortOptions.contains('A' + i))
                unused.append('A' + i);
        }
        printf("Unused: %s\n", unused.constData());
        for (int i=0; opts[i].name; ++i) {
            if (opts[i].name) {
                if (!opts[i].val) {
                    printf("No shortoption for %s\n", opts[i].name);
                } else if (opts[i].name[0] != opts[i].val) {
                    printf("Not ideal option for %s|%c\n", opts[i].name, opts[i].val);
                }
            }
        }
        return 0;
    }


    List<String> argCopy;
    List<char*> argList;
    {
        bool norc = false;
        Path rcfile = Path::home() + ".rdmrc";
        opterr = 0;
        while (true) {
            const int c = getopt_long(argc, argv, shortOptions.constData(), opts, 0);
            if (c == -1)
                break;
            switch (c) {
            case 'N':
                norc = true;
                break;
            case 'c':
                rcfile = optarg;
                break;
            default:
                break;
            }
        }
        opterr = 1;
        argList.append(argv[0]);
        if (!norc) {
            char *rc;
            int size = Path("/etc/rdmrc").readAll(rc);
            if (rc) {
                argCopy = String(rc, size).split('\n');
                delete[] rc;
            }
            if (!rcfile.isEmpty()) {
                size = rcfile.readAll(rc);
                if (rc) {
                    List<String> split = String(rc, size).split('\n');
                    argCopy.append(split);
                    delete[] rc;
                }
            }
            const int s = argCopy.size();
            for (int i=0; i<s; ++i) {
                String &arg = argCopy.at(i);
                if (!arg.isEmpty() && !arg.startsWith('#') && !arg.startsWith(' '))
                    argList.append(arg.data());
            }
        }
        for (int i=1; i<argc; ++i) {
            argList.append(argv[i]);
        }

        optind = 1;
    }

    Server::Options serverOpts;
    serverOpts.socketFile = String::format<128>("%s.rdm", Path::home().constData());
    serverOpts.threadCount = ThreadPool::idealThreadCount();
    serverOpts.completionCacheSize = 0;
    serverOpts.options = Server::Wall|Server::SpellChecking;
    serverOpts.excludeFilters = String(EXCLUDEFILTER_DEFAULT).split(';');
    serverOpts.dataDir = String::format<128>("%s.rtags", Path::home().constData());
    serverOpts.unloadTimer = 0;
    serverOpts.clangStackSize = defaultStackSize;

    const char *logFile = 0;
    unsigned logFlags = 0;
    int logLevel = 0;
    assert(Path::home().endsWith('/'));
    int argCount = argList.size();
    char **args = argList.data();
    while (true) {
        const int c = getopt_long(argCount, args, shortOptions.constData(), opts, 0);
        if (c == -1)
            break;
        switch (c) {
        case 'N':
        case 'c':
            // ignored
            break;
        case 'S':
            logLevel = -1;
            break;
        case 'x':
            serverOpts.excludeFilters += String(optarg).split(';');
            break;
        case 't':
            serverOpts.clangStackSize = atoi(optarg);
            if (serverOpts.clangStackSize <= 0) {
                fprintf(stderr, "Invalid stack size: %s\n", optarg);
                return 1;
            }
            break;
        case 'b':
            serverOpts.ignoredCompilers.insert(Path::resolved(optarg));
            break;
        case 'n':
            serverOpts.socketFile = optarg;
            break;
        case 'd':
            serverOpts.dataDir = String::format<128>("%s", Path::resolved(optarg).constData());
            break;
        case 'h':
            usage(stdout);
            return 0;
        case 'm':
            serverOpts.options |= Server::AllowMultipleBuildsForSameCompiler;
            break;
        case 'V':
            serverOpts.options |= Server::Validate;
            break;
        case 'o':
            serverOpts.options |= Server::NoStartupCurrentProject;
            break;
        case 'G':
            serverOpts.options |= Server::UseCompilerFlags;
            break;
        case 'F':
            serverOpts.options |= Server::IgnorePrintfFixits;
            break;
        case 'f':
            serverOpts.options |= Server::UnlimitedErrors;
            break;
        case 'l':
            serverOpts.options &= ~Server::SpellChecking;
            break;
        case 'U':
            serverOpts.options |= Server::NoBuiltinIncludes;
            break;
        case 'W':
            serverOpts.options &= ~Server::Wall;
            break;
        case 'C':
            serverOpts.options |= Server::ClearProjects;
            break;
        case 'e':
            putenv(optarg);
            break;
        case 's':
            signal(SIGSEGV, sigSegvHandler);
            break;
        case 'u': {
            bool ok;
            serverOpts.unloadTimer = static_cast<int>(String(optarg).toULongLong(&ok));
            if (!ok) {
                fprintf(stderr, "Invalid argument to --unload-timer %s\n", optarg);
                return 1;
            }
            break; }
        case 'a':
            serverOpts.completionCacheSize = atoi(optarg);
            if (serverOpts.completionCacheSize < 1) {
                fprintf(stderr, "Invalid argument to -a %s\n", optarg);
                return 1;
            }
            break;
        case 'j':
            serverOpts.threadCount = atoi(optarg);
            if (serverOpts.threadCount <= 0) {
                fprintf(stderr, "Can't parse argument to -j %s\n", optarg);
                return 1;
            }
            break;
        case 'r': {
            int large = atoi(optarg);
            if (large <= 0) {
                fprintf(stderr, "Can't parse argument to -r %s\n", optarg);
                return 1;
            }
            serverOpts.defaultArguments.append("-Wlarge-by-value-copy=" + String(optarg)); // ### not quite working
            break; }
        case 'D':
            serverOpts.defaultArguments.append("-D" + String(optarg));
            break;
        case 'I':
            serverOpts.defaultArguments.append("-I" + String(optarg));
            break;
        case 'i':
            serverOpts.defaultArguments.append("-include");
            serverOpts.defaultArguments.append(optarg);
            break;
        case 'A':
            logFlags |= Log::Append;
            break;
        case 'L':
            logFile = optarg;
            break;
        case 'v':
            if (logLevel >= 0)
                ++logLevel;
            break;
        case '?':
            usage(stderr);
            return 1;
        }
    }
    if (optind < argCount) {
        fprintf(stderr, "rdm: unexpected option -- '%s'\n", args[optind]);
        return 1;
    }

    signal(SIGINT, sigIntHandler);

    if (!initLogging(logLevel, logFile, logFlags)) {
        fprintf(stderr, "Can't initialize logging with %d %s 0x%0x\n",
                logLevel, logFile ? logFile : "", logFlags);
        return 1;
    }
    warning("Running with %d jobs", serverOpts.threadCount);

    EventLoop loop;

    shared_ptr<Server> server(new Server);
    ::socketFile = serverOpts.socketFile;
    if (!serverOpts.dataDir.endsWith('/'))
        serverOpts.dataDir.append('/');
    if (!server->init(serverOpts)) {
        cleanupLogging();
        return 1;
    }

    loop.run();
    cleanupLogging();
    return 0;
}
Ejemplo n.º 18
0
Archivo: team.c Proyecto: 0mp/freebsd
void
gomp_team_start (void (*fn) (void *), void *data, unsigned nthreads,
		 struct gomp_work_share *work_share)
{
  struct gomp_thread_start_data *start_data;
  struct gomp_thread *thr, *nthr;
  struct gomp_team *team;
  bool nested;
  unsigned i, n, old_threads_used = 0;
  pthread_attr_t thread_attr, *attr;

  thr = gomp_thread ();
  nested = thr->ts.team != NULL;

  team = new_team (nthreads, work_share);

  /* Always save the previous state, even if this isn't a nested team.
     In particular, we should save any work share state from an outer
     orphaned work share construct.  */
  team->prev_ts = thr->ts;

  thr->ts.team = team;
  thr->ts.work_share = work_share;
  thr->ts.team_id = 0;
  thr->ts.work_share_generation = 0;
  thr->ts.static_trip = 0;

  if (nthreads == 1)
    return;

  i = 1;

  /* We only allow the reuse of idle threads for non-nested PARALLEL
     regions.  This appears to be implied by the semantics of
     threadprivate variables, but perhaps that's reading too much into
     things.  Certainly it does prevent any locking problems, since
     only the initial program thread will modify gomp_threads.  */
  if (!nested)
    {
      old_threads_used = gomp_threads_used;

      if (nthreads <= old_threads_used)
	n = nthreads;
      else if (old_threads_used == 0)
	{
	  n = 0;
	  gomp_barrier_init (&gomp_threads_dock, nthreads);
	}
      else
	{
	  n = old_threads_used;

	  /* Increase the barrier threshold to make sure all new
	     threads arrive before the team is released.  */
	  gomp_barrier_reinit (&gomp_threads_dock, nthreads);
	}

      /* Not true yet, but soon will be.  We're going to release all
	 threads from the dock, and those that aren't part of the 
	 team will exit.  */
      gomp_threads_used = nthreads;

      /* Release existing idle threads.  */
      for (; i < n; ++i)
	{
	  nthr = gomp_threads[i];
	  nthr->ts.team = team;
	  nthr->ts.work_share = work_share;
	  nthr->ts.team_id = i;
	  nthr->ts.work_share_generation = 0;
	  nthr->ts.static_trip = 0;
	  nthr->fn = fn;
	  nthr->data = data;
	  team->ordered_release[i] = &nthr->release;
	}

      if (i == nthreads)
	goto do_release;

      /* If necessary, expand the size of the gomp_threads array.  It is
	 expected that changes in the number of threads is rare, thus we
	 make no effort to expand gomp_threads_size geometrically.  */
      if (nthreads >= gomp_threads_size)
	{
	  gomp_threads_size = nthreads + 1;
	  gomp_threads
	    = gomp_realloc (gomp_threads,
			    gomp_threads_size
			    * sizeof (struct gomp_thread_data *));
	}
    }

  attr = &gomp_thread_attr;
  if (gomp_cpu_affinity != NULL)
    {
      size_t stacksize;
      pthread_attr_init (&thread_attr);
      pthread_attr_setdetachstate (&thread_attr, PTHREAD_CREATE_DETACHED);
      if (! pthread_attr_getstacksize (&gomp_thread_attr, &stacksize))
	pthread_attr_setstacksize (&thread_attr, stacksize);
      attr = &thread_attr;
    }

  start_data = gomp_alloca (sizeof (struct gomp_thread_start_data)
			    * (nthreads-i));

  /* Launch new threads.  */
  for (; i < nthreads; ++i, ++start_data)
    {
      pthread_t pt;
      int err;

      start_data->ts.team = team;
      start_data->ts.work_share = work_share;
      start_data->ts.team_id = i;
      start_data->ts.work_share_generation = 0;
      start_data->ts.static_trip = 0;
      start_data->fn = fn;
      start_data->fn_data = data;
      start_data->nested = nested;

      if (gomp_cpu_affinity != NULL)
	gomp_init_thread_affinity (attr);

      err = pthread_create (&pt, attr, gomp_thread_start, start_data);
      if (err != 0)
	gomp_fatal ("Thread creation failed: %s", strerror (err));
    }

  if (gomp_cpu_affinity != NULL)
    pthread_attr_destroy (&thread_attr);

 do_release:
  gomp_barrier_wait (nested ? &team->barrier : &gomp_threads_dock);

  /* Decrease the barrier threshold to match the number of threads
     that should arrive back at the end of this team.  The extra
     threads should be exiting.  Note that we arrange for this test
     to never be true for nested teams.  */
  if (nthreads < old_threads_used)
    gomp_barrier_reinit (&gomp_threads_dock, nthreads);
}
Ejemplo n.º 19
0
static uintptr_t
isAttrOk(const create_attr_t *expected, const omrthread_attr_t actual)
{
	uintptr_t status = 0;

	/* expected should never be null */
	if (expected == NULL) {
		return BAD_TEST;
	}

	if (actual == NULL) {
		status |= NULL_ATTR;
		/* no further checks are possible */
		omrTestEnv->log(LEVEL_ERROR, "attr is NULL\n");
		return status;
	}

	/* both should refer to the same memory */
	if (expected->name != actual->name) {
		omrTestEnv->log(LEVEL_ERROR, "wrong name\n");
		status |= WRONG_NAME;
	}

	if (expected->stacksize != actual->stacksize) {
		printMismatchU("stacksize", expected->stacksize, actual->stacksize);
		status |= WRONG_STACKSIZE;
	}

	if (expected->policy != actual->schedpolicy) {
		printMismatchI("schedpolicy", expected->policy, actual->schedpolicy);
		status |= WRONG_SCHEDPOLICY;
	}

	if (expected->priority != actual->priority) {
		printMismatchU("priority", expected->priority, actual->priority);
		status |= WRONG_PRIORITY;
	}

#if defined(SPEC_PTHREAD_API)
	{
		pthread_attr_t *attr = &((unixthread_attr_t)actual)->pattr;
		size_t osStacksize;
#ifndef J9ZOS390
		struct sched_param osSchedparam;
		int osPolicy;
		int osInheritsched;
#endif
#if defined(AIXPPC) || defined(LINUX) || defined(OSX)
		int osScope;
#endif /* defined(AIXPPC) || defined(LINUX) || defined(OSX) */
#ifdef J9ZOS390
		int osThreadweight;
		int osDetachstate;
#endif

		PTHREAD_VERBOSE(pthread_attr_getstacksize(attr, &osStacksize));
		if (osStacksize != expected->osStacksize) {
			printMismatchI("os stacksize", expected->osStacksize, osStacksize);
			status |= WRONG_OS_STACKSIZE;
		}

#ifndef J9ZOS390

		PTHREAD_VERBOSE(pthread_attr_getschedpolicy(attr, &osPolicy));
#if (defined(AIXPPC) || defined(LINUX) || defined(OSX))
		/* aix and linux bug - need to set the schedpolicy to OTHER if inheritsched used */
		if (J9THREAD_SCHEDPOLICY_INHERIT == expected->policy) {
			if (osPolicy != OS_SCHED_OTHER) {
				printMismatchS("os schedpolicy", mapOSPolicy(OS_SCHED_OTHER), mapOSPolicy(osPolicy));
				status |= WRONG_OS_SCHEDPOLICY;
			}
		}
		else
#endif /* (defined(AIXPPC) || defined(LINUX) || defined(OSX)) */
		{
			if (osPolicy != expected->osPolicy) {
				printMismatchS("os schedpolicy", mapOSPolicy(expected->osPolicy), mapOSPolicy(osPolicy));
				status |= WRONG_OS_SCHEDPOLICY;
			}
		}

		PTHREAD_VERBOSE(pthread_attr_getinheritsched(attr, &osInheritsched));
		if (osInheritsched != expected->osInheritsched) {
			printMismatchS("os inheritsched", mapOSInherit(expected->osInheritsched), mapOSInherit(osInheritsched));
			status |= WRONG_OS_INHERITSCHED;
		}

		PTHREAD_VERBOSE(pthread_attr_getschedparam(attr, &osSchedparam));
		if (osSchedparam.sched_priority != expected->osPriority) {
			printMismatchI("os priority", expected->osPriority, osSchedparam.sched_priority);
			status |= WRONG_OS_PRIORITY;
		}
#endif /* not J9ZOS390 */

#if defined(AIXPPC) || defined(LINUX) || defined(OSX)
		PTHREAD_VERBOSE(pthread_attr_getscope(attr, &osScope));
		if (osScope != expected->osScope) {
			printMismatchI("os scope", expected->osScope, osScope);
			status |= WRONG_OS_SCOPE;
		}
#endif /* defined(AIXPPC) || defined(LINUX) || defined(OSX) */

#ifdef J9ZOS390
		osThreadweight = pthread_attr_getweight_np(attr);
		if (osThreadweight != expected->osThreadweight) {
			printMismatchI("os threadweight", expected->osThreadweight, osThreadweight);
			status |= WRONG_OS_THREADWEIGHT;
		}

		osDetachstate = pthread_attr_getdetachstate(attr);
		if (osDetachstate != expected->osDetachstate) {
			printMismatchI("os detachstate", expected->osDetachstate, osDetachstate);
			status |= WRONG_OS_DETACHSTATE;
		}
#endif
	}
#endif /* defined(SPEC_PTHREAD_API) */

	if (status == 0) {
		status |= canCreateThread(expected, actual);
	}
	return status;
}
Ejemplo n.º 20
0
int main(int argc, char** argv)
{
#ifdef OS_Darwin
    struct rlimit rlp;
    if (getrlimit(RLIMIT_NOFILE, &rlp) == 0) {
        if (rlp.rlim_cur < 1000) {
            rlp.rlim_cur = 1000;
            setrlimit(RLIMIT_NOFILE, &rlp);
        }
    }
#endif

    {
        pthread_attr_t attr;
        pthread_attr_init(&attr);
        pthread_attr_getstacksize(&attr, &defaultStackSize);
        pthread_attr_destroy(&attr);
        if (defaultStackSize < 1024 * 1024 * 4) { // 4 megs should be enough for everyone right?
            defaultStackSize = 1024 * 1024 * 4;
        }
    }

    Rct::findExecutablePath(*argv);

    struct option opts[] = {
        { "help", no_argument, 0, 'h' },
        { "version", no_argument, 0, 2 },
        { "include-path", required_argument, 0, 'I' },
        { "isystem", required_argument, 0, 's' },
        { "define", required_argument, 0, 'D' },
        { "log-file", required_argument, 0, 'L' },
        { "setenv", required_argument, 0, 'e' },
        { "no-Wall", no_argument, 0, 'W' },
        { "Weverything", no_argument, 0, 'u' },
        { "cache-AST", required_argument, 0, 'A' },
        { "verbose", no_argument, 0, 'v' },
        { "job-count", required_argument, 0, 'j' },
        { "header-error-job-count", required_argument, 0, 'H' },
        { "test", required_argument, 0, 't' },
        { "test-timeout", required_argument, 0, 'z' },
        { "clean-slate", no_argument, 0, 'C' },
        { "disable-sighandler", no_argument, 0, 'x' },
        { "silent", no_argument, 0, 'S' },
        { "exclude-filter", required_argument, 0, 'X' },
        { "socket-file", required_argument, 0, 'n' },
        { "config", required_argument, 0, 'c' },
        { "no-rc", no_argument, 0, 'N' },
        { "data-dir", required_argument, 0, 'd' },
        { "ignore-printf-fixits", no_argument, 0, 'F' },
        { "no-unlimited-errors", no_argument, 0, 'f' },
        { "block-argument", required_argument, 0, 'G' },
        { "no-spell-checking", no_argument, 0, 'l' },
        { "large-by-value-copy", required_argument, 0, 'r' },
        { "disallow-multiple-sources", no_argument, 0, 'm' },
        { "no-startup-project", no_argument, 0, 'o' },
        { "no-no-unknown-warnings-option", no_argument, 0, 'Y' },
        { "ignore-compiler", required_argument, 0, 'b' },
        { "watch-system-paths", no_argument, 0, 'w' },
        { "rp-visit-file-timeout", required_argument, 0, 'Z' },
        { "rp-indexer-message-timeout", required_argument, 0, 'T' },
        { "rp-connect-timeout", required_argument, 0, 'O' },
        { "rp-connect-attempts", required_argument, 0, 3 },
        { "rp-nice-value", required_argument, 0, 'a' },
        { "thread-stack-size", required_argument, 0, 'k' },
        { "suspend-rp-on-crash", no_argument, 0, 'q' },
        { "rp-log-to-syslog", no_argument, 0, 7 },
        { "start-suspended", no_argument, 0, 'Q' },
        { "separate-debug-and-release", no_argument, 0, 'E' },
        { "max-crash-count", required_argument, 0, 'K' },
        { "completion-cache-size", required_argument, 0, 'i' },
        { "completion-no-filter", no_argument, 0, 8 },
        { "extra-compilers", required_argument, 0, 'U' },
        { "allow-Wpedantic", no_argument, 0, 'P' },
        { "enable-compiler-manager", no_argument, 0, 'R' },
        { "enable-NDEBUG", no_argument, 0, 'g' },
        { "progress", no_argument, 0, 'p' },
        { "max-file-map-cache-size", required_argument, 0, 'y' },
#ifdef OS_FreeBSD
        { "filemanager-watch", no_argument, 0, 'M' },
#else
        { "no-filemanager-watch", no_argument, 0, 'M' },
#endif
        { "no-file-lock", no_argument, 0, 13 },
        { "pch-enabled", no_argument, 0, 14 },
        { "no-filesystem-watcher", no_argument, 0, 'B' },
        { "arg-transform", required_argument, 0, 'V' },
        { "no-comments", no_argument, 0, 1 },
#ifdef OS_Darwin
        { "launchd", no_argument, 0, 4 },
#endif
        { "inactivity-timeout", required_argument, 0, 5 },
        { "daemon", no_argument, 0, 6 },
        { "log-file-log-level", required_argument, 0, 9 },
        { "watch-sources-only", no_argument, 0, 10 },
        { "debug-locations", no_argument, 0, 11 },
        { "tcp-port", required_argument, 0, 12 },
        { 0, 0, 0, 0 }
    };
    const String shortOptions = Rct::shortOptions(opts);
    if (getenv("RTAGS_DUMP_UNUSED")) {
        String unused;
        for (int i=0; i<26; ++i) {
            if (!shortOptions.contains('a' + i))
                unused.append('a' + i);
            if (!shortOptions.contains('A' + i))
                unused.append('A' + i);
        }
        printf("Unused: %s\n", unused.constData());
        for (int i=0; opts[i].name; ++i) {
            if (opts[i].name) {
                if (!opts[i].val) {
                    printf("No shortoption for %s\n", opts[i].name);
                } else if (opts[i].name[0] != opts[i].val) {
                    printf("Not ideal option for %s|%c\n", opts[i].name, opts[i].val);
                }
            }
        }
        return 0;
    }

    bool daemon = false;
    List<String> argCopy;
    List<char*> argList;
    {
        bool norc = false;
        Path rcfile = Path::home() + ".rdmrc";
        opterr = 0;

        StackBuffer<128, char*> originalArgv(argc);
        memcpy(originalArgv, argv, sizeof(char*) * argc);
        /* getopt will molest argv by moving pointers around when it sees
         * fit. Their idea of an optional argument is different from ours so we
         * have to take a copy of argv before they get their sticky fingers all
         * over it.
         *
         * We think this should be okay for an optional argument:
         * -s something
         *
         * They only populate optarg if you do:
         * -ssomething.
         *
         * We don't want to copy argv into argList before processing rc files
         * since command line args should take precedence over things in rc
         * files.
         *
         */

        while (true) {
            const int c = getopt_long(argc, argv, shortOptions.constData(), opts, 0);
            if (c == -1)
                break;
            switch (c) {
            case 'N':
                norc = true;
                break;
            case 'c':
                rcfile = optarg;
                break;
            default:
                break;
            }
        }
        opterr = 1;
        argList.append(argv[0]);
        if (!norc) {
            String rc = Path("/etc/rdmrc").readAll();
            if (!rc.isEmpty()) {
                for (const String& s : rc.split('\n')) {
                    if (!s.isEmpty() && !s.startsWith('#'))
                        argCopy += s.split(' ');
                }
            }
            if (!rcfile.isEmpty()) {
                rc = rcfile.readAll();
                if (!rc.isEmpty()) {
                    for (const String& s : rc.split('\n')) {
                        if (!s.isEmpty() && !s.startsWith('#'))
                            argCopy += s.split(' ');
                    }
                }
            }
            const int s = argCopy.size();
            for (int i=0; i<s; ++i) {
                String &arg = argCopy.at(i);
                if (!arg.isEmpty())
                    argList.append(arg.data());
            }
        }

        for (int i=1; i<argc; ++i)
            argList.append(originalArgv[i]);

        optind = 1;
    }

    Server::Options serverOpts;
    serverOpts.threadStackSize = defaultStackSize;
    serverOpts.socketFile = String::format<128>("%s.rdm", Path::home().constData());
    serverOpts.jobCount = std::max(2, ThreadPool::idealThreadCount());
    serverOpts.headerErrorJobCount = -1;
    serverOpts.rpVisitFileTimeout = DEFAULT_RP_VISITFILE_TIMEOUT;
    serverOpts.rpIndexDataMessageTimeout = DEFAULT_RP_INDEXER_MESSAGE_TIMEOUT;
    serverOpts.rpConnectTimeout = DEFAULT_RP_CONNECT_TIMEOUT;
    serverOpts.rpConnectAttempts = DEFAULT_RP_CONNECT_ATTEMPTS;
    serverOpts.maxFileMapScopeCacheSize = DEFAULT_RDM_MAX_FILE_MAP_CACHE_SIZE;
    serverOpts.rpNiceValue = INT_MIN;
    serverOpts.options = Server::Wall|Server::SpellChecking;
    serverOpts.maxCrashCount = DEFAULT_MAX_CRASH_COUNT;
    serverOpts.completionCacheSize = DEFAULT_COMPLETION_CACHE_SIZE;
#ifdef OS_FreeBSD
    serverOpts.options |= Server::NoFileManagerWatch;
#endif
// #ifndef NDEBUG
//     serverOpts.options |= Server::SuspendRPOnCrash;
// #endif
    serverOpts.excludeFilters = String(EXCLUDEFILTER_DEFAULT).split(';');
    serverOpts.dataDir = String::format<128>("%s.rtags", Path::home().constData());

    const char *logFile = 0;
    Flags<LogFileFlag> logFlags = DontRotate;
    LogLevel logLevel(LogLevel::Error);
    LogLevel logFileLogLevel(LogLevel::Error);
    bool sigHandler = true;
    assert(Path::home().endsWith('/'));
    int argCount = argList.size();
    char **args = argList.data();
    bool defaultDataDir = true;
    int inactivityTimeout = 0;

    while (true) {
        const int c = getopt_long(argCount, args, shortOptions.constData(), opts, 0);
        if (c == -1)
            break;
        switch (c) {
        case 'N':
        case 'c':
            // ignored
            break;
        case 'S':
            logLevel = LogLevel::None;
            break;
        case 'X':
            serverOpts.excludeFilters += String(optarg).split(';');
            break;
        case 'G':
            serverOpts.blockedArguments << optarg;
            break;
        case 1:
            serverOpts.options |= Server::NoComments;
            break;
        case 10:
            serverOpts.options |= Server::WatchSourcesOnly;
            break;
        case 11:
            if (!strcmp(optarg, "clear") || !strcmp(optarg, "none")) {
                serverOpts.debugLocations.clear();
            } else {
                serverOpts.debugLocations << optarg;
            }
            break;
        case 12:
            serverOpts.tcpPort = atoi(optarg);
            if (!serverOpts.tcpPort) {
                fprintf(stderr, "Invalid port %s for --tcp-port\n", optarg);
                return 1;
            }
            break;
        case 13:
            serverOpts.options |= Server::NoFileLock;
            break;
        case 14:
            serverOpts.options |= Server::PCHEnabled;
            break;
        case 2:
            fprintf(stdout, "%s\n", RTags::versionString().constData());
            return 0;
        case 6:
            daemon = true;
            logLevel = LogLevel::None;
            break;
        case 9:
            if (!strcasecmp(optarg, "verbose-debug")) {
                logFileLogLevel = LogLevel::VerboseDebug;
            } else if (!strcasecmp(optarg, "debug")) {
                logFileLogLevel = LogLevel::Debug;
            } else if (!strcasecmp(optarg, "warning")) {
                logFileLogLevel = LogLevel::Warning;
            } else if (!strcasecmp(optarg, "error")) {
                logFileLogLevel = LogLevel::Error;
            } else {
                fprintf(stderr, "Unknown log level: %s options are error, warning, debug or verbose-debug\n",
                        optarg);
                return 1;
            }
            break;
        case 'U':
            serverOpts.extraCompilers.append(std::regex(optarg));
            break;
        case 'E':
            serverOpts.options |= Server::SeparateDebugAndRelease;
            break;
        case 'g':
            serverOpts.options |= Server::EnableNDEBUG;
            break;
        case 'Q':
            serverOpts.options |= Server::StartSuspended;
            break;
        case 'Z':
            serverOpts.rpVisitFileTimeout = atoi(optarg);
            if (serverOpts.rpVisitFileTimeout < 0) {
                fprintf(stderr, "Invalid argument to -Z %s\n", optarg);
                return 1;
            }
            if (!serverOpts.rpVisitFileTimeout)
                serverOpts.rpVisitFileTimeout = -1;
            break;
        case 'y':
            serverOpts.maxFileMapScopeCacheSize = atoi(optarg);
            if (serverOpts.maxFileMapScopeCacheSize <= 0) {
                fprintf(stderr, "Invalid argument to -y %s\n", optarg);
                return 1;
            }
            break;
        case 'O':
            serverOpts.rpConnectTimeout = atoi(optarg);
            if (serverOpts.rpConnectTimeout < 0) {
                fprintf(stderr, "Invalid argument to -O %s\n", optarg);
                return 1;
            }
            break;
        case 3:
            serverOpts.rpConnectAttempts = atoi(optarg);
            if (serverOpts.rpConnectAttempts <= 0) {
                fprintf(stderr, "Invalid argument to --rp-connect-attempts %s\n", optarg);
                return 1;
            }
            break;
        case 'k':
            serverOpts.threadStackSize = atoi(optarg);
            if (serverOpts.threadStackSize < 0) {
                fprintf(stderr, "Invalid argument to -k %s\n", optarg);
                return 1;
            }
            break;
        case 'b':
            serverOpts.ignoredCompilers.insert(Path::resolved(optarg));
            break;
        case 't': {
            Path test(optarg);
            if (!test.resolve() || !test.isFile()) {
                fprintf(stderr, "%s doesn't seem to be a file\n", optarg);
                return 1;
            }
            serverOpts.tests += test;
            break; }
        case 'z':
            serverOpts.testTimeout = atoi(optarg);
            if (serverOpts.testTimeout <= 0) {
                fprintf(stderr, "Invalid argument to -z %s\n", optarg);
                return 1;
            }
            break;
        case 'n':
            serverOpts.socketFile = optarg;
            break;
        case 'd':
            defaultDataDir = false;
            serverOpts.dataDir = String::format<128>("%s", Path::resolved(optarg).constData());
            break;
        case 'h':
            usage(stdout);
            return 0;
        case 'Y':
            serverOpts.options |= Server::NoNoUnknownWarningsOption;
            break;
        case 'p':
            serverOpts.options |= Server::Progress;
            break;
        case 'R':
            serverOpts.options |= Server::EnableCompilerManager;
            break;
        case 'm':
            serverOpts.options |= Server::DisallowMultipleSources;
            break;
        case 'o':
            serverOpts.options |= Server::NoStartupCurrentProject;
            break;
        case 'w':
            serverOpts.options |= Server::WatchSystemPaths;
            break;
        case 'q':
            serverOpts.options |= Server::SuspendRPOnCrash;
            break;
        case 'M':
#ifdef OS_FreeBSD
            serverOpts.options &= ~Server::NoFileManagerWatch;
#else
            serverOpts.options |= Server::NoFileManagerWatch;
#endif
            break;
        case 'B':
            serverOpts.options |= Server::NoFileSystemWatch;
            break;
        case 'V':
            serverOpts.argTransform = Process::findCommand(optarg);
            if (strlen(optarg) && serverOpts.argTransform.isEmpty()) {
                fprintf(stderr, "Invalid argument to -V. Can't resolve %s", optarg);
                return 1;
            }

            break;
      case 'F':
            serverOpts.options |= Server::IgnorePrintfFixits;
            break;
        case 'f':
            serverOpts.options |= Server::NoUnlimitedErrors;
            break;
        case 'l':
            serverOpts.options &= ~Server::SpellChecking;
            break;
        case 'W':
            serverOpts.options &= ~Server::Wall;
            break;
        case 'u':
            serverOpts.options |= Server::Weverything;
            break;
        case 'P':
            serverOpts.options |= Server::AllowPedantic;
            break;
        case 'C':
            serverOpts.options |= Server::ClearProjects;
            break;
        case 'e':
            putenv(optarg);
            break;
        case 'x':
            sigHandler = false;
            break;
        case 'K':
            serverOpts.maxCrashCount = atoi(optarg);
            if (serverOpts.maxCrashCount <= 0) {
                fprintf(stderr, "Invalid argument to -K %s\n", optarg);
                return 1;
            }
            break;
        case 'i':
            serverOpts.completionCacheSize = atoi(optarg);
            if (serverOpts.completionCacheSize <= 0) {
                fprintf(stderr, "Invalid argument to -i %s\n", optarg);
                return 1;
            }
            break;
        case 'T':
            serverOpts.rpIndexDataMessageTimeout = atoi(optarg);
            if (serverOpts.rpIndexDataMessageTimeout <= 0) {
                fprintf(stderr, "Can't parse argument to -T %s.\n", optarg);
                return 1;
            }
            break;
        case 'a': {
            bool ok;
            serverOpts.rpNiceValue = String(optarg).toLong(&ok);
            if (!ok) {
                fprintf(stderr, "Can't parse argument to -a %s.\n", optarg);
                return 1;
            }
            break; }
        case 'j':
            serverOpts.jobCount = atoi(optarg);
            if (serverOpts.jobCount < 0) {
                fprintf(stderr, "Can't parse argument to -j %s. -j must be a positive integer.\n", optarg);
                return 1;
            }
            break;
        case 'H':
            serverOpts.headerErrorJobCount = atoi(optarg);
            if (serverOpts.headerErrorJobCount < 0) {
                fprintf(stderr, "Can't parse argument to -H %s. -J must be a positive integer.\n", optarg);
                return 1;
            }
            break;
        case 'r': {
            int large = atoi(optarg);
            if (large <= 0) {
                fprintf(stderr, "Can't parse argument to -r %s\n", optarg);
                return 1;
            }
            serverOpts.defaultArguments.append("-Wlarge-by-value-copy=" + String(optarg)); // ### not quite working
            break; }
        case 'D': {
            const char *eq = strchr(optarg, '=');
            Source::Define def;
            if (!eq) {
                def.define = optarg;
            } else {
                def.define = String(optarg, eq - optarg);
                def.value = eq + 1;
            }
            serverOpts.defines.append(def);
            break; }
        case 'I':
            serverOpts.includePaths.append(Source::Include(Source::Include::Type_Include, Path::resolved(optarg)));
            break;
        case 's':
            serverOpts.includePaths.append(Source::Include(Source::Include::Type_System, Path::resolved(optarg)));
            break;
        case 'L':
            logFile = optarg;
            logLevel = LogLevel::None;
            break;
        case 'v':
            if (logLevel != LogLevel::None)
                ++logLevel;
            break;
#ifdef OS_Darwin
        case 4:
            serverOpts.options |= Server::Launchd;
            break;
#endif
        case 5:
            inactivityTimeout = atoi(optarg); // seconds.
            if (inactivityTimeout <= 0) {
                fprintf(stderr, "Invalid argument to --inactivity-timeout %s\n", optarg);
                return 1;
            }
            break;
        case 7:
            serverOpts.options |= Server::RPLogToSyslog;
            break;
        case 8:
            serverOpts.options |= Server::CompletionsNoFilter;
            break;
        case '?': {
            fprintf(stderr, "Run rdm --help for help\n");
            return 1; }
        }
    }
    if (optind < argCount) {
        fprintf(stderr, "rdm: unexpected option -- '%s'\n", args[optind]);
        return 1;
    }

    if (daemon) {
        switch (fork()) {
        case -1:
            fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno));
            return 1;
        case 0:
            setsid();
            switch (fork()) {
            case -1:
                fprintf(stderr, "Failed to fork (%d) %s\n", errno, strerror(errno));
                return 1;
            case 0:
                break;
            default:
                return 0;
            }
            break;
        default:
            return 0;
        }
    }

    if (serverOpts.headerErrorJobCount == -1) {
        serverOpts.headerErrorJobCount = std::max(1, serverOpts.jobCount / 2);
    } else {
        serverOpts.headerErrorJobCount = std::min(serverOpts.headerErrorJobCount, serverOpts.jobCount);
    }

    if (sigHandler) {
        signal(SIGSEGV, sigSegvHandler);
        signal(SIGILL, sigSegvHandler);
        signal(SIGABRT, sigSegvHandler);
    }

    // Shell-expand logFile
    Path logPath(logFile); logPath.resolve();

    if (!initLogging(argv[0], LogStderr, logLevel, logPath.constData(), logFlags, logFileLogLevel)) {
        fprintf(stderr, "Can't initialize logging with %d %s %s\n",
                logLevel.toInt(), logFile ? logFile : "", logFlags.toString().constData());
        return 1;
    }

#ifdef OS_Darwin
    if (serverOpts.options & Server::Launchd) {
        // Clamp inactivity timeout. launchd starts to worry if the
        // process runs for less than 10 seconds.

        static const int MIN_INACTIVITY_TIMEOUT = 15; // includes
                                                      // fudge factor.

        if (inactivityTimeout < MIN_INACTIVITY_TIMEOUT) {
            inactivityTimeout = MIN_INACTIVITY_TIMEOUT;
            fprintf(stderr, "launchd mode - clamped inactivity timeout to %d to avoid launchd warnings.\n", inactivityTimeout);
        }
    }
#endif

    EventLoop::SharedPtr loop(new EventLoop);
    loop->init(EventLoop::MainEventLoop|EventLoop::EnableSigIntHandler|EventLoop::EnableSigTermHandler);

    std::shared_ptr<Server> server(new Server);
    if (!serverOpts.tests.isEmpty()) {
        char buf[1024];
        Path path;
        while (true) {
            strcpy(buf, "/tmp/rtags-test-XXXXXX");
            if (!mkdtemp(buf)) {
                fprintf(stderr, "Failed to mkdtemp (%d)\n", errno);
                return 1;
            }
            path = buf;
            path.resolve();
            break;
        }
        serverOpts.dataDir = path;
        strcpy(buf, "/tmp/rtags-sock-XXXXXX");
        const int fd = mkstemp(buf);
        if (fd == -1) {
            fprintf(stderr, "Failed to mkstemp (%d)\n", errno);
            return 1;
        }
        close(fd);
        serverOpts.socketFile = buf;
        serverOpts.socketFile.resolve();
    }
    if (defaultDataDir) {
        Path migration = String::format<128>("%s.rtags-file", Path::home().constData());
        if (migration.isDir()) {
            Rct::removeDirectory(serverOpts.dataDir);
            rename(migration.constData(), serverOpts.dataDir.constData());
            error() << "Migrated datadir from ~/.rtags-file ~/.rtags";
        }
    }
    serverOpts.dataDir = serverOpts.dataDir.ensureTrailingSlash();
    if (!server->init(serverOpts)) {
        cleanupLogging();
        return 1;
    }

    if (!serverOpts.tests.isEmpty()) {
        return server->runTests() ? 0 : 1;
    }

    loop->setInactivityTimeout(inactivityTimeout * 1000);

    loop->exec();
    const int ret = server->exitCode();
    server.reset();
    cleanupLogging();
    return ret;
}
Ejemplo n.º 21
0
void my_pthread_attr_getstacksize(pthread_attr_t *connection_attrib,
				  size_t *stack_size)
{
  *stack_size= pthread_attr_getstacksize(*connection_attrib);
}
Ejemplo n.º 22
0
int main(int argc, char **argv)
{
	int i;
	int config_loaded = 0;
	int dont_fork = 0;
	size_t wanted_stacksize = 0, stacksize = 0;
	pthread_attr_t attr;

	// global initialization
	get_HZ();

	// set the name for logging
	program_name = "netdata";

	// parse  the arguments
	for(i = 1; i < argc ; i++) {
		if(strcmp(argv[i], "-c") == 0 && (i+1) < argc) {
			if(load_config(argv[i+1], 1) != 1) {
				error("Cannot load configuration file %s.", argv[i+1]);
				exit(1);
			}
			else {
				debug(D_OPTIONS, "Configuration loaded from %s.", argv[i+1]);
				config_loaded = 1;
			}
			i++;
		}
		else if(strcmp(argv[i], "-df") == 0 && (i+1) < argc) { config_set("global", "debug flags",  argv[i+1]); debug_flags = strtoull(argv[i+1], NULL, 0); i++; }
		else if(strcmp(argv[i], "-p")  == 0 && (i+1) < argc) { config_set("global", "port",         argv[i+1]); i++; }
		else if(strcmp(argv[i], "-u")  == 0 && (i+1) < argc) { config_set("global", "run as user",  argv[i+1]); i++; }
		else if(strcmp(argv[i], "-l")  == 0 && (i+1) < argc) { config_set("global", "history",      argv[i+1]); i++; }
		else if(strcmp(argv[i], "-t")  == 0 && (i+1) < argc) { config_set("global", "update every", argv[i+1]); i++; }
		else if(strcmp(argv[i], "-ch") == 0 && (i+1) < argc) { config_set("global", "host access prefix", argv[i+1]); i++; }
		else if(strcmp(argv[i], "-stacksize") == 0 && (i+1) < argc) { config_set("global", "pthread stack size", argv[i+1]); i++; }
		else if(strcmp(argv[i], "-nodaemon") == 0 || strcmp(argv[i], "-nd") == 0) dont_fork = 1;
		else if(strcmp(argv[i], "-pidfile") == 0 && (i+1) < argc) {
			i++;
			strncpy(pidfile, argv[i], FILENAME_MAX);
			pidfile[FILENAME_MAX] = '\0';
		}
		else if(strcmp(argv[i], "--unittest")  == 0) {
			rrd_update_every = 1;
			if(run_all_mockup_tests()) exit(1);
			if(unit_test_storage()) exit(1);
			fprintf(stderr, "\n\nALL TESTS PASSED\n\n");
			exit(0);
		}
		else {
			fprintf(stderr, "Cannot understand option '%s'.\n", argv[i]);
			fprintf(stderr, "\nUSAGE: %s [-d] [-l LINES_TO_SAVE] [-u UPDATE_TIMER] [-p LISTEN_PORT] [-df debug flags].\n\n", argv[0]);
			fprintf(stderr, "  -c CONFIG FILE the configuration file to load. Default: %s.\n", CONFIG_DIR "/" CONFIG_FILENAME);
			fprintf(stderr, "  -l LINES_TO_SAVE can be from 5 to %d lines in JSON data. Default: %d.\n", RRD_HISTORY_ENTRIES_MAX, RRD_DEFAULT_HISTORY_ENTRIES);
			fprintf(stderr, "  -t UPDATE_TIMER can be from 1 to %d seconds. Default: %d.\n", UPDATE_EVERY_MAX, UPDATE_EVERY);
			fprintf(stderr, "  -p LISTEN_PORT can be from 1 to %d. Default: %d.\n", 65535, LISTEN_PORT);
			fprintf(stderr, "  -u USERNAME can be any system username to run as. Default: none.\n");
			fprintf(stderr, "  -ch path to access host /proc and /sys when running in a container. Default: empty.\n");
			fprintf(stderr, "  -nd or -nodeamon to disable forking in the background. Default: unset.\n");
			fprintf(stderr, "  -df FLAGS debug options. Default: 0x%08llx.\n", debug_flags);
			fprintf(stderr, "  -stacksize BYTES to overwrite the pthread stack size.\n");
			fprintf(stderr, "  -pidfile FILENAME to save a pid while running.\n");
			exit(1);
		}
	}

	if(!config_loaded) load_config(NULL, 0);

	// prepare configuration environment variables for the plugins
	setenv("NETDATA_CONFIG_DIR" , config_get("global", "config directory"   , CONFIG_DIR) , 1);
	setenv("NETDATA_PLUGINS_DIR", config_get("global", "plugins directory"  , PLUGINS_DIR), 1);
	setenv("NETDATA_WEB_DIR"    , config_get("global", "web files directory", WEB_DIR)    , 1);
	setenv("NETDATA_CACHE_DIR"  , config_get("global", "cache directory"    , CACHE_DIR)  , 1);
	setenv("NETDATA_LOG_DIR"    , config_get("global", "log directory"      , LOG_DIR)    , 1);
	setenv("NETDATA_HOST_PREFIX", config_get("global", "host access prefix" , "")         , 1);
	setenv("HOME"               , config_get("global", "home directory"     , CACHE_DIR)  , 1);

	// avoid extended to stat(/etc/localtime)
	// http://stackoverflow.com/questions/4554271/how-to-avoid-excessive-stat-etc-localtime-calls-in-strftime-on-linux
	setenv("TZ", ":/etc/localtime", 0);

	// cd to /tmp to avoid any plugins writing files at random places
	if(chdir("/tmp")) error("netdata: ERROR: Cannot cd to /tmp");

	char *input_log_file = NULL;
	char *output_log_file = NULL;
	char *error_log_file = NULL;
	char *access_log_file = NULL;
	char *user = NULL;
	{
		char buffer[1024];

		// --------------------------------------------------------------------

		sprintf(buffer, "0x%08llx", 0ULL);
		char *flags = config_get("global", "debug flags", buffer);
		setenv("NETDATA_DEBUG_FLAGS", flags, 1);

		debug_flags = strtoull(flags, NULL, 0);
		debug(D_OPTIONS, "Debug flags set to '0x%8llx'.", debug_flags);

		if(debug_flags != 0) {
			struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
			if(setrlimit(RLIMIT_CORE, &rl) != 0)
				info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");
			prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
		}

		// --------------------------------------------------------------------

#ifdef MADV_MERGEABLE
		enable_ksm = config_get_boolean("global", "memory deduplication (ksm)", enable_ksm);
#else
#warning "Kernel memory deduplication (KSM) is not available"
#endif

		// --------------------------------------------------------------------


		global_host_prefix = config_get("global", "host access prefix", "");
		setenv("NETDATA_HOST_PREFIX", global_host_prefix, 1);

		// --------------------------------------------------------------------

		output_log_file = config_get("global", "debug log", LOG_DIR "/debug.log");
		if(strcmp(output_log_file, "syslog") == 0) {
			output_log_syslog = 1;
			output_log_file = NULL;
		}
		else if(strcmp(output_log_file, "none") == 0) {
			output_log_syslog = 0;
			output_log_file = NULL;
		}
		else output_log_syslog = 0;

		// --------------------------------------------------------------------

		error_log_file = config_get("global", "error log", LOG_DIR "/error.log");
		if(strcmp(error_log_file, "syslog") == 0) {
			error_log_syslog = 1;
			error_log_file = NULL;
		}
		else if(strcmp(error_log_file, "none") == 0) {
			error_log_syslog = 0;
			error_log_file = NULL;
			// optimization - do not even generate debug log entries
		}
		else error_log_syslog = 0;

		error_log_throttle_period = config_get_number("global", "errors flood protection period", error_log_throttle_period);
		setenv("NETDATA_ERRORS_THROTTLE_PERIOD", config_get("global", "errors flood protection period"    , ""), 1);

		error_log_errors_per_period = config_get_number("global", "errors to trigger flood protection", error_log_errors_per_period);
		setenv("NETDATA_ERRORS_PER_PERIOD"     , config_get("global", "errors to trigger flood protection", ""), 1);

		// --------------------------------------------------------------------

		access_log_file = config_get("global", "access log", LOG_DIR "/access.log");
		if(strcmp(access_log_file, "syslog") == 0) {
			access_log_syslog = 1;
			access_log_file = NULL;
		}
		else if(strcmp(access_log_file, "none") == 0) {
			access_log_syslog = 0;
			access_log_file = NULL;
		}
		else access_log_syslog = 0;

		// --------------------------------------------------------------------

		rrd_memory_mode = rrd_memory_mode_id(config_get("global", "memory mode", rrd_memory_mode_name(rrd_memory_mode)));

		// --------------------------------------------------------------------

		if(gethostname(buffer, HOSTNAME_MAX) == -1)
			error("WARNING: Cannot get machine hostname.");
		hostname = config_get("global", "hostname", buffer);
		debug(D_OPTIONS, "hostname set to '%s'", hostname);

		// --------------------------------------------------------------------

		rrd_default_history_entries = (int) config_get_number("global", "history", RRD_DEFAULT_HISTORY_ENTRIES);
		if(rrd_default_history_entries < 5 || rrd_default_history_entries > RRD_HISTORY_ENTRIES_MAX) {
			info("Invalid save lines %d given. Defaulting to %d.", rrd_default_history_entries, RRD_DEFAULT_HISTORY_ENTRIES);
			rrd_default_history_entries = RRD_DEFAULT_HISTORY_ENTRIES;
		}
		else {
			debug(D_OPTIONS, "save lines set to %d.", rrd_default_history_entries);
		}

		// --------------------------------------------------------------------

		rrd_update_every = (int) config_get_number("global", "update every", UPDATE_EVERY);
		if(rrd_update_every < 1 || rrd_update_every > 600) {
			info("Invalid update timer %d given. Defaulting to %d.", rrd_update_every, UPDATE_EVERY_MAX);
			rrd_update_every = UPDATE_EVERY;
		}
		else debug(D_OPTIONS, "update timer set to %d.", rrd_update_every);

		// let the plugins know the min update_every
		{
			char buf[50];
			snprintf(buf, 50, "%d", rrd_update_every);
			setenv("NETDATA_UPDATE_EVERY", buf, 1);
		}

		// --------------------------------------------------------------------

		// block signals while initializing threads.
		// this causes the threads to block signals.
		sigset_t sigset;
		sigfillset(&sigset);

		if(pthread_sigmask(SIG_BLOCK, &sigset, NULL) == -1) {
			error("Could not block signals for threads");
		}

		// Catch signals which we want to use to quit savely
		struct sigaction sa;
		sigemptyset(&sa.sa_mask);
		sigaddset(&sa.sa_mask, SIGHUP);
		sigaddset(&sa.sa_mask, SIGINT);
		sigaddset(&sa.sa_mask, SIGTERM);
		sa.sa_handler = sig_handler;
		sa.sa_flags = 0;
		if(sigaction(SIGHUP, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGHUP");
		}
		if(sigaction(SIGINT, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGINT");
		}
		if(sigaction(SIGTERM, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGTERM");
		}
		// Ignore SIGPIPE completely.
		// INFO: If we add signals here we have to unblock them
		// at popen.c when running a external plugin.
		sa.sa_handler = SIG_IGN;
		if(sigaction(SIGPIPE, &sa, NULL) == -1) {
			error("Failed to change signal handler for SIGTERM");
		}

		// --------------------------------------------------------------------

		i = pthread_attr_init(&attr);
		if(i != 0)
			fatal("pthread_attr_init() failed with code %d.", i);

		i = pthread_attr_getstacksize(&attr, &stacksize);
		if(i != 0)
			fatal("pthread_attr_getstacksize() failed with code %d.", i);
		else
			debug(D_OPTIONS, "initial pthread stack size is %zu bytes", stacksize);

		wanted_stacksize = config_get_number("global", "pthread stack size", stacksize);

		// --------------------------------------------------------------------

		for (i = 0; static_threads[i].name != NULL ; i++) {
			struct netdata_static_thread *st = &static_threads[i];

			if(st->config_name) st->enabled = config_get_boolean(st->config_section, st->config_name, st->enabled);
			if(st->enabled && st->init_routine) st->init_routine();
		}

		// --------------------------------------------------------------------

		// get the user we should run
		// IMPORTANT: this is required before web_files_uid()
		user = config_get("global", "run as user"    , (getuid() == 0)?NETDATA_USER:"");

		// IMPORTANT: these have to run once, while single threaded
		web_files_uid(); // IMPORTANT: web_files_uid() before web_files_gid()
		web_files_gid();

		// --------------------------------------------------------------------

		listen_backlog = (int) config_get_number("global", "http port listen backlog", LISTEN_BACKLOG);

		listen_port = (int) config_get_number("global", "port", LISTEN_PORT);
		if(listen_port < 1 || listen_port > 65535) {
			info("Invalid listen port %d given. Defaulting to %d.", listen_port, LISTEN_PORT);
			listen_port = LISTEN_PORT;
		}
		else debug(D_OPTIONS, "Listen port set to %d.", listen_port);

		int ip = 0;
		char *ipv = config_get("global", "ip version", "any");
		if(!strcmp(ipv, "any") || !strcmp(ipv, "both") || !strcmp(ipv, "all")) ip = 0;
		else if(!strcmp(ipv, "ipv4") || !strcmp(ipv, "IPV4") || !strcmp(ipv, "IPv4") || !strcmp(ipv, "4")) ip = 4;
		else if(!strcmp(ipv, "ipv6") || !strcmp(ipv, "IPV6") || !strcmp(ipv, "IPv6") || !strcmp(ipv, "6")) ip = 6;
		else info("Cannot understand ip version '%s'. Assuming 'any'.", ipv);

		if(ip == 0 || ip == 6) listen_fd = create_listen_socket6(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
		if(listen_fd < 0) {
			listen_fd = create_listen_socket4(config_get("global", "bind socket to IP", "*"), listen_port, listen_backlog);
			if(listen_fd >= 0 && ip != 4) info("Managed to open an IPv4 socket on port %d.", listen_port);
		}

		if(listen_fd < 0) fatal("Cannot listen socket.");
	}

	// never become a problem
	if(nice(20) == -1) error("Cannot lower my CPU priority.");

	if(become_daemon(dont_fork, 0, user, input_log_file, output_log_file, error_log_file, access_log_file, &access_fd, &stdaccess) == -1) {
		fatal("Cannot demonize myself.");
		exit(1);
	}

	if(debug_flags != 0) {
		struct rlimit rl = { RLIM_INFINITY, RLIM_INFINITY };
		if(setrlimit(RLIMIT_CORE, &rl) != 0)
			info("Cannot request unlimited core dumps for debugging... Proceeding anyway...");

		prctl(PR_SET_DUMPABLE, 1, 0, 0, 0);
	}

	if(output_log_syslog || error_log_syslog || access_log_syslog)
		openlog("netdata", LOG_PID, LOG_DAEMON);

	info("NetData started on pid %d", getpid());



	// ------------------------------------------------------------------------
	// get default pthread stack size

	if(stacksize < wanted_stacksize) {
		i = pthread_attr_setstacksize(&attr, wanted_stacksize);
		if(i != 0)
			fatal("pthread_attr_setstacksize() to %zu bytes, failed with code %d.", wanted_stacksize, i);
		else
			info("Successfully set pthread stacksize to %zu bytes", wanted_stacksize);
	}

	// ------------------------------------------------------------------------
	// spawn the threads

	for (i = 0; static_threads[i].name != NULL ; i++) {
		struct netdata_static_thread *st = &static_threads[i];

		if(st->enabled) {
			st->thread = malloc(sizeof(pthread_t));
			if(!st->thread)
				fatal("Cannot allocate pthread_t memory");

			info("Starting thread %s.", st->name);

			if(pthread_create(st->thread, &attr, st->start_routine, NULL))
				error("failed to create new thread for %s.", st->name);

			else if(pthread_detach(*st->thread))
				error("Cannot request detach of newly created %s thread.", st->name);
		}
		else info("Not starting thread %s.", st->name);
	}

	// ------------------------------------------------------------------------
	// block signals while initializing threads.
	sigset_t sigset;
	sigfillset(&sigset);

	if(pthread_sigmask(SIG_UNBLOCK, &sigset, NULL) == -1) {
		error("Could not unblock signals for threads");
	}

	// Handle flags set in the signal handler.
	while(1) {
		pause();
		if(netdata_exit) {
			info("Exit main loop of netdata.");
			netdata_cleanup_and_exit(0);
			exit(0);
		}
	}
}
Ejemplo n.º 23
0
//rtems_task Init(rtems_task_argument Argument)
void *POSIX_Init(void *argument)
{
    pthread_attr_t	threadAttr;
    pthread_t     	theThread;
    struct sched_param	sched_param;
    size_t		stack_size;
    int           	result;
    char		data[1000];
    

    memset(data, 1, sizeof(data));

    /* Set the TOD clock, so that gettimeofday() will work */
    rtems_time_of_day fakeTime = { 2006, 3, 15, 17, 30, 0, 0 };

    if (RTEMS_SUCCESSFUL != rtems_clock_set(&fakeTime))
    {
	assert(0);
    }	

    /* Bring up the network stack so we can run the socket tests. */
    initialize_network();

    /* Start a POSIX thread for pjlib_test_main(), since that's what it
     * thinks it is running in. 
     */

    /* Initialize attribute */
    TEST( pthread_attr_init(&threadAttr) );

    /* Looks like the rest of the attributes must be fully initialized too,
     * or otherwise pthread_create will return EINVAL.
     */

    /* Specify explicit scheduling request */
    TEST( pthread_attr_setinheritsched(&threadAttr, PTHREAD_EXPLICIT_SCHED));

    /* Timeslicing is needed by thread test, and this is accomplished by
     * SCHED_RR.
     */
    TEST( pthread_attr_setschedpolicy(&threadAttr, SCHED_RR));

    /* Set priority */
    TEST( pthread_attr_getschedparam(&threadAttr, &sched_param));
    sched_param.sched_priority = NETWORK_STACK_PRIORITY - 10;
    TEST( pthread_attr_setschedparam(&threadAttr, &sched_param));

    /* Must have sufficient stack size (large size is needed by
     * logger, because default settings for logger is to use message buffer
     * from the stack).
     */
    TEST( pthread_attr_getstacksize(&threadAttr, &stack_size));
    if (stack_size < 8192)
	TEST( pthread_attr_setstacksize(&threadAttr, 8192));


    /* Create the thread for application */
    result = pthread_create(&theThread, &threadAttr, &pjlib_test_main, NULL);
    if (result != 0) {
	my_perror(PJ_STATUS_FROM_OS(result), 
		  "Error creating pjlib_test_main thread");
	assert(!"Error creating main thread");
    } 

    return NULL;
}
Ejemplo n.º 24
0
int init_pthread_attr(pthread_attr_t *pattr, const int stack_size)
{
	size_t old_stack_size;
	size_t new_stack_size;
	int result;

	if ((result=pthread_attr_init(pattr)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"call pthread_attr_init fail, " \
			"errno: %d, error info: %s", \
			__LINE__, result, STRERROR(result));
		return result;
	}

	if ((result=pthread_attr_getstacksize(pattr, &old_stack_size)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"call pthread_attr_getstacksize fail, " \
			"errno: %d, error info: %s", \
			__LINE__, result, STRERROR(result));
		return result;
	}

	if (stack_size > 0)
	{
		if (old_stack_size != stack_size)
		{
			new_stack_size = stack_size;
		}
		else
		{
			new_stack_size = 0;
		}
	}
	else if (old_stack_size < 1 * 1024 * 1024)
	{
		new_stack_size = 1 * 1024 * 1024;
	}
	else
	{
		new_stack_size = 0;
	}

	if (new_stack_size > 0)
	{
		if ((result=pthread_attr_setstacksize(pattr, \
				new_stack_size)) != 0)
		{
			logError("file: "__FILE__", line: %d, " \
				"call pthread_attr_setstacksize fail, " \
				"errno: %d, error info: %s", \
				__LINE__, result, STRERROR(result));
			return result;
		}
	}

	if ((result=pthread_attr_setdetachstate(pattr, \
			PTHREAD_CREATE_DETACHED)) != 0)
	{
		logError("file: "__FILE__", line: %d, " \
			"call pthread_attr_setdetachstate fail, " \
			"errno: %d, error info: %s", \
			__LINE__, result, STRERROR(result));
		return result;
	}

	return 0;
}
Ejemplo n.º 25
0
int main(int argc, char* argv[])
{
  printf("Program %s Begin\n", argv[0]);
  struct tms begintime;
  clock_t begreal = times(&begintime);

  struct sigaction act, oact;
  sigemptyset(&act.sa_mask);
  act.sa_flags = SA_SIGINFO;
  act.sa_sigaction = sigaction_handle_fun;
  sigaction(SIGTERM, &act, &oact);


  pthread_t pthreadid = pthread_self();
  printf("pthreadid:%u\n", pthreadid);


  pthread_mutex_init (&(gcounter.m_mutex), NULL);
  gcounter.m_cout = 0;

  pthread_attr_t pthreadattr;
  pthread_attr_init(&pthreadattr);
  size_t pthreadstacksize;

  pthread_attr_getstacksize(&pthreadattr, &pthreadstacksize);
  printf("pthreadstacksize:%u\n", pthreadstacksize);
  printf("pthread_getconcurrency:%d\n", pthread_getconcurrency());

  pthread_t newpthreadid;
  char* charg = "000 pass to pthread";
  int pcreateret = pthread_create(&newpthreadid, NULL, pthread_fun0, charg);
  if(pcreateret != 0)
  {
    perror("pthread_create error");
  }
  else
  {
    printf("newpthreadid:%u\n", newpthreadid);
  }

  pthread_t newpthreadid1;
  char* charg1 = "100 pass to pthread";
  int pcreateret1 = pthread_create(&newpthreadid1, NULL, pthread_fun1, charg);
  if(pcreateret1 != 0)
  {
    perror("pthread_create error");
  }
  else
  {
    printf("newpthreadid:%u\n", newpthreadid1);
  }

  void* pret;
  pthread_join(newpthreadid, &pret);
  pthread_join(newpthreadid1, &pret);

  char chcwdbuf[100];
  if(getcwd (chcwdbuf, 100) == NULL)
  {
    perror("getcwd error");
  }
  else
  {
    printf("getcwd %s\n", chcwdbuf);
  }

  printf("input characters:\n");
  int c;
  while( (c = getc(stdin)) != EOF)
  {
    if(putc(c, stdout) == EOF)
    {
      perror("putc error");
    }
  }


  time_t t = time(NULL);
  struct tm* localtm = localtime(&t);
  printf("Time:%s\n", asctime(localtm));

  printf("getlogin:%s\n", getlogin());


  atexit(atexit_fun1);
  atexit(atexit_fun2);

  printf("getpid():%d\n", getpid());

  pid_t pid;

  if( (pid = fork()) < 0)
  {
    perror("fork error\n");
  }
  else if(pid == 0)
  {
    printf("great this is child process created by fork \n");
    printf("getpid():%d\n", getpid());
    printf("getppid():%d\n", getppid());
    printf("getpgrp():%d\n", getpgrp());
  }
  else
  {
    printf("parent process is here.\n");

  }

  /* extern char** environ; */

  /* char** env = environ; */
  /* while(*env) */
  /* { */
  /* ++env; */
  /* printf("%s\n", *env); */
  /* } */



  /* while(environ[]) */
  /* { */
  /* printf(""); */
  /* } */

  /* while(!GbStop) */
  /* 	/\* while(1)  //C99 define true C89 didn't define *\/ */
  /* { */

  /* } */
  struct tms endtime;
  clock_t endreal = times(&endtime);

  printf("real:%f\n"
         "user:%f\n"
         "sys:%f\n",
         (float)(endreal-begreal)/CLOCKS_PER_SEC, (float)(endtime.tms_utime-begintime.tms_utime)/CLOCKS_PER_SEC, (float)(endtime.tms_stime-begintime.tms_stime)/CLOCKS_PER_SEC );

  return 0;
}
Ejemplo n.º 26
0
struct spx_module_context *spx_module_new(\
        SpxLogDelegate *log,\
        u32_t threadsize,\
        size_t stack_size,
        SpxReceiveTriggerDelegate *receive_handler,
        err_t *err){/*{{{*/
    struct spx_module_context *mc = (struct spx_module_context *)\
                                    spx_alloc_alone(sizeof(*mc),err);
    if(NULL == mc){
        SpxLog2(log,SpxLogError,*err,\
                "alloc module context is fail.");
        return NULL;
    }

    mc->log = log;
    mc->threadpool = spx_list_init(log,\
            threadsize,\
            spx_thread_context_new,\
            log,\
            spx_thread_context_free,\
            err);
    if(NULL == mc->threadpool){
        SpxLog2(log,SpxLogError,*err,\
                "alloc threadpool for module is fail.");
        goto r2;
    }

    struct spx_recvive_context_transport rct;
    SpxZero(rct);

    rct.log = log;
    rct.event = EV_READ;
    rct.recviver = receive_handler;;
    mc->receive_triggers = spx_list_init(log,\
            threadsize,\
            spx_receiver_new,\
            &rct,\
            spx_receiver_free,\
            err);
    if(NULL == mc->receive_triggers){
        SpxLog2(log,SpxLogError,*err,\
                "alloc receive triggers are fail.");
        goto r2;
    }

    pthread_attr_t attr;
    pthread_attr_init(&attr);
    size_t ostack_size = 0;
    pthread_attr_getstacksize(&attr, &ostack_size);
    do{
        if (ostack_size != stack_size
                && (0 != (*err = pthread_attr_setstacksize(&attr,stack_size)))){
            SpxLog2(log,SpxLogError,*err,\
                    "set thread stack size is fail.");
            goto r1;
        }
        u32_t i = 0;
        struct spx_thread_pending_transport *tpt;
        for( ; i < threadsize; i++){
            tpt = spx_alloc_alone(sizeof(*tpt),err);
            tpt->mc = mc;
            tpt->idx = i;
            struct spx_thread_context *n = spx_list_get(mc->threadpool,i);
            if (0 !=(*err =  pthread_create(&(n->tid), &attr, spx_thread_listening,
                            tpt))){
                SpxLog2(log,SpxLogError,*err,\
                        "create nio thread is fail.");
                goto r1;
            }
        }
    }while(false);
    pthread_attr_destroy(&attr);
    return mc;
r1:
    pthread_attr_destroy(&attr);
r2:
    spx_module_free(&mc);
    return NULL;
}/*}}}*/
Ejemplo n.º 27
0
  void THREAD_CREATE( THREAD_T* ref, 
                      THREAD_RETURN_T (*func)( void * ),
                      void *data, int prio /* -2..+2 */ ) {
    pthread_attr_t _a;
    pthread_attr_t *a= &_a;
    struct sched_param sp;

    PT_CALL( pthread_attr_init(a) );

#ifndef PTHREAD_TIMEDJOIN
    // We create a NON-JOINABLE thread. This is mainly due to the lack of
    // 'pthread_timedjoin()', but does offer other benefits (s.a. earlier 
    // freeing of the thread's resources).
    //
    //PT_CALL( pthread_attr_setdetachstate(a,PTHREAD_CREATE_DETACHED) );
#endif

    // Use this to find a system's default stack size (DEBUG)
#if 0
  { size_t n; pthread_attr_getstacksize( a, &n );
    fprintf( stderr, "Getstack: %u\n", (unsigned int)n ); }
    	//  524288 on OS X
    	// 2097152 on Linux x86 (Ubuntu 7.04)
    	// 1048576 on FreeBSD 6.2 SMP i386
#endif

#if (defined _THREAD_STACK_SIZE) && (_THREAD_STACK_SIZE > 0)
    PT_CALL( pthread_attr_setstacksize( a, _THREAD_STACK_SIZE ) );
#endif
    
    bool_t normal= 
#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
        !sudo;          // with sudo, even normal thread must use SCHED_RR
#else
        prio == 0;      // create a default thread if
#endif
    if (!normal) {
        // NB: PThreads priority handling is about as twisty as one can get it
        //     (and then some). DON*T TRUST ANYTHING YOU READ ON THE NET!!!

        // "The specified scheduling parameters are only used if the scheduling
        //  parameter inheritance attribute is PTHREAD_EXPLICIT_SCHED."
        //
      #ifndef ANDROID  
		PT_CALL( pthread_attr_setinheritsched( a, PTHREAD_EXPLICIT_SCHED ) );
		#endif
        //---
        // "Select the scheduling policy for the thread: one of SCHED_OTHER 
        // (regular, non-real-time scheduling), SCHED_RR (real-time, 
        // round-robin) or SCHED_FIFO (real-time, first-in first-out)."
        //
        // "Using the RR policy ensures that all threads having the same
        // priority level will be scheduled equally, regardless of their activity."
        //
        // "For SCHED_FIFO and SCHED_RR, the only required member of the
        // sched_param structure is the priority sched_priority. For SCHED_OTHER,
        // the affected scheduling parameters are implementation-defined."
        //
        // "The priority of a thread is specified as a delta which is added to 
        // the priority of the process."
        //
        // ".. priority is an integer value, in the range from 1 to 127. 
        //  1 is the least-favored priority, 127 is the most-favored."
        //
        // "Priority level 0 cannot be used: it is reserved for the system."
        //
        // "When you use specify a priority of -99 in a call to 
        // pthread_setschedparam(), the priority of the target thread is 
        // lowered to the lowest possible value."
        //
        // ...

        // ** CONCLUSION **
        //
        // PThread priorities are _hugely_ system specific, and we need at
        // least OS specific settings. Hopefully, Linuxes and OS X versions
        // are uniform enough, among each other...
        //
#ifdef PLATFORM_OSX
        // AK 10-Apr-07 (OS X PowerPC 10.4.9):
        //
        // With SCHED_RR, 26 seems to be the "normal" priority, where setting
        // it does not seem to affect the order of threads processed.
        //
        // With SCHED_OTHER, the range 25..32 is normal (maybe the same 26,
        // but the difference is not so clear with OTHER).
        //
        // 'sched_get_priority_min()' and '..max()' give 15, 47 as the 
        // priority limits. This could imply, user mode applications won't
        // be able to use values outside of that range.
        //
        #define _PRIO_MODE SCHED_OTHER
        
        // OS X 10.4.9 (PowerPC) gives ENOTSUP for process scope
        //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS

        #define _PRIO_HI  32    // seems to work (_carefully_ picked!)
        #define _PRIO_0   26    // detected
        #define _PRIO_LO   1    // seems to work (tested)

#elif defined(PLATFORM_LINUX)
        // (based on Ubuntu Linux 2.6.15 kernel)
        //
        // SCHED_OTHER is the default policy, but does not allow for priorities.
        // SCHED_RR allows priorities, all of which (1..99) are higher than
        // a thread with SCHED_OTHER policy.
        //
        // <http://kerneltrap.org/node/6080>
        // <http://en.wikipedia.org/wiki/Native_POSIX_Thread_Library>
        // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
        //
        // Manuals suggest checking #ifdef _POSIX_THREAD_PRIORITY_SCHEDULING,
        // but even Ubuntu does not seem to define it.
        //
        #define _PRIO_MODE SCHED_RR
        
        // NTLP 2.5: only system scope allowed (being the basic reason why
        //           root privileges are required..)
        //#define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS

        #define _PRIO_HI 99
        #define _PRIO_0  50
        #define _PRIO_LO 1

#elif defined(PLATFORM_BSD)
        //
        // <http://www.net.in.tum.de/~gregor/docs/pthread-scheduling.html>
        //
        // "When control over the thread scheduling is desired, then FreeBSD
        //  with the libpthread implementation is by far the best choice .."
        //
        #define _PRIO_MODE SCHED_OTHER
        #define _PRIO_SCOPE PTHREAD_SCOPE_PROCESS
        #define _PRIO_HI 31
        #define _PRIO_0  15
        #define _PRIO_LO 1

#elif defined(PLATFORM_CYGWIN)
	//
	// TBD: Find right values for Cygwin
	//
#else
        #error "Unknown OS: not implemented!"
#endif

#ifdef _PRIO_SCOPE
        PT_CALL( pthread_attr_setscope( a, _PRIO_SCOPE ) );
#endif
        PT_CALL( pthread_attr_setschedpolicy( a, _PRIO_MODE ) );

#define _PRIO_AN (_PRIO_0 + ((_PRIO_HI-_PRIO_0)/2) )
#define _PRIO_BN (_PRIO_LO + ((_PRIO_0-_PRIO_LO)/2) )

        sp.sched_priority= 
            (prio == +2) ? _PRIO_HI :
            (prio == +1) ? _PRIO_AN :
#if defined(PLATFORM_LINUX) && defined(LINUX_SCHED_RR)
            (prio == 0) ? _PRIO_0 :
#endif
            (prio == -1) ? _PRIO_BN : _PRIO_LO;

        PT_CALL( pthread_attr_setschedparam( a, &sp ) );
    }

    //---
    // Seems on OS X, _POSIX_THREAD_THREADS_MAX is some kind of system
    // thread limit (not userland thread). Actual limit for us is way higher.
    // PTHREAD_THREADS_MAX is not defined (even though man page refers to it!)
    //
# ifndef THREAD_CREATE_RETRIES_MAX
    // Don't bother with retries; a failure is a failure
    //
    { 
      int rc= pthread_create( ref, a, func, data );
      if (rc) _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__-1 );
    }
# else
# error "This code deprecated"
/*
    // Wait slightly if thread creation has exchausted the system
    //
    { uint_t retries;
    for( retries=0; retries<THREAD_CREATE_RETRIES_MAX; retries++ ) {

        int rc= pthread_create( ref, a, func, data );
            //
            // OS X / Linux:
            //    EAGAIN: ".. lacked the necessary resources to create
            //             another thread, or the system-imposed limit on the
            //             total number of threads in a process 
            //             [PTHREAD_THREADS_MAX] would be exceeded."
            //    EINVAL: attr is invalid
            // Linux:
            //    EPERM: no rights for given parameters or scheduling (no sudo)
            //    ENOMEM: (known to fail with this code, too - not listed in man)
            
        if (rc==0) break;   // ok!

        // In practise, exhaustion seems to be coming from memory, not a
        // maximum number of threads. Keep tuning... ;)
        //
        if (rc==EAGAIN) {
//fprintf( stderr, "Looping (retries=%d) ", retries );    // DEBUG

            // Try again, later.

            Yield();
        } else {
            _PT_FAIL( rc, "pthread_create()", __FILE__, __LINE__ );
        }
    }
    }
*/
# endif

    if (a) {
        PT_CALL( pthread_attr_destroy(a) );
    }
  }
Ejemplo n.º 28
0
void data_init(struct ts *ts) {
	memset(ts, 0, sizeof(struct ts));
	// Stream
	ts->pat	     = ts_pat_alloc();
	ts->curpat   = ts_pat_alloc();
	ts->genpat   = ts_pat_alloc();

	ts->cat      = ts_cat_alloc();
	ts->curcat   = ts_cat_alloc();

	ts->pmt      = ts_pmt_alloc();
	ts->curpmt   = ts_pmt_alloc();

	ts->sdt      = ts_sdt_alloc();
	ts->cursdt   = ts_sdt_alloc();

	ts->emm      = ts_privsec_alloc();
	ts->last_emm = ts_privsec_alloc();
	ts->tmp_emm  = ts_privsec_alloc();

	ts->ecm      = ts_privsec_alloc();
	ts->last_ecm = ts_privsec_alloc();
	ts->tmp_ecm  = ts_privsec_alloc();

	pidmap_clear(&ts->pidmap);
	pidmap_clear(&ts->cc);
	pidmap_clear(&ts->pid_seen);

	// Key
	memset(&ts->key, 0, sizeof(ts->key));
	ts->key.csakey = csa_key_alloc();
	gettimeofday(&ts->key.ts_keyset, NULL);

	// CAMD
	memset(&ts->camd, 0, sizeof(ts->camd));
	ts->camd.server_fd    = -1;
	ts->camd.service      = "2233";
	ts->camd.key          = &ts->key;
	ts->camd.user         = "******";
	ts->camd.pass         = "******";
	strcpy(ts->camd.newcamd.hex_des_key, "0102030405060708091011121314");

	camd_proto_cs378x(&ts->camd.ops);

	// Config
	ts->syslog_port = 514;

	ts->ts_discont  = 1;
	ts->ecm_cw_log  = 1;

	ts->debug_level = 0;
	ts->req_CA_sys  = CA_CONAX;

	ts->process_ecm = 1;
	ts->process_emm = 0;
	ts->output_stream = 1;

	ts->pid_filter  = 1;

	ts->emm_report_interval = 60;
	ts->emm_last_report     = time(NULL);

	ts->ecm_report_interval = 60;
	ts->ecm_last_report     = time(NULL);

	ts->irdeto_ecm_idx         = 0;
	ts->irdeto_ecm_filter_type = IRDETO_FILTER_IDX;

	ts->cw_warn_sec = 60;
	ts->cw_last_warn= time(NULL);
	ts->cw_last_warn= ts->cw_last_warn + ts->cw_warn_sec;
	ts->key.ts      = time(NULL);

	ts->input.fd    = 0; // STDIN
	ts->input.type  = FILE_IO;

	ts->output.fd   = 1; // STDOUT
	ts->output.type = FILE_IO;
	ts->output.ttl  = 1;
	ts->output.tos  = -1;
	ts->output.v6_if_index = -1;

	ts->decode_buf  = cbuf_init((7 * csa_get_batch_size() * 188) * 16, "decode"); // ~658Kb
	ts->write_buf   = cbuf_init((7 * csa_get_batch_size() * 188) *  8, "write");  // ~324Kb

	ts->input_buffer= list_new("input");

	pthread_attr_init(&ts->thread_attr);
	size_t stack_size;
	pthread_attr_getstacksize(&ts->thread_attr, &stack_size);
	if (stack_size > THREAD_STACK_SIZE)
		pthread_attr_setstacksize(&ts->thread_attr, THREAD_STACK_SIZE);
}
Ejemplo n.º 29
0
int
TclpThreadCreate(
    Tcl_ThreadId *idPtr,	/* Return, the ID of the thread */
    Tcl_ThreadCreateProc proc,	/* Main() function of the thread */
    ClientData clientData,	/* The one argument to Main() */
    int stackSize,		/* Size of stack for the new thread */
    int flags)			/* Flags controlling behaviour of the new
				 * thread. */
{
#ifdef TCL_THREADS
    pthread_attr_t attr;
    pthread_t theThread;
    int result;

    pthread_attr_init(&attr);
    pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);

#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
    if (stackSize != TCL_THREAD_STACK_DEFAULT) {
	pthread_attr_setstacksize(&attr, (size_t) stackSize);
#ifdef TCL_THREAD_STACK_MIN
    } else {
	/*
	 * Certain systems define a thread stack size that by default is too
	 * small for many operations. The user has the option of defining
	 * TCL_THREAD_STACK_MIN to a value large enough to work for their
	 * needs. This would look like (for 128K min stack):
	 *    make MEM_DEBUG_FLAGS=-DTCL_THREAD_STACK_MIN=131072L
	 *
	 * This solution is not optimal, as we should allow the user to
	 * specify a size at runtime, but we don't want to slow this function
	 * down, and that would still leave the main thread at the default.
	 */

	size_t size;
	result = pthread_attr_getstacksize(&attr, &size);
	if (!result && (size < TCL_THREAD_STACK_MIN)) {
	    pthread_attr_setstacksize(&attr, (size_t) TCL_THREAD_STACK_MIN);
	}
#endif
    }
#endif
    if (! (flags & TCL_THREAD_JOINABLE)) {
	pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
    }


    if (pthread_create(&theThread, &attr,
	    (void * (*)(void *))proc, (void *)clientData) &&
	    pthread_create(&theThread, NULL,
		    (void * (*)(void *))proc, (void *)clientData)) {
	result = TCL_ERROR;
    } else {
	*idPtr = (Tcl_ThreadId)theThread;
	result = TCL_OK;
    }
    pthread_attr_destroy(&attr);
    return result;
#else
    return TCL_ERROR;
#endif /* TCL_THREADS */
}
Ejemplo n.º 30
0
int pthread_attr_getstacksize_ex(const pthread_attr_ex_t *attr_ex,
				 size_t *stacksize)
{
	return pthread_attr_getstacksize(&attr_ex->std, stacksize);
}