// 将当前进程绑定到参数cpu_affinity对应比特位为1的位置的CPU核心。
// cpu_affinity[in]: 如果为1将绑定到第0个CPU,如果为2将绑定到第1个CPU,如果为4将绑定到第2个CPU,以此类推。
//                   同时支持绑定到多个CPU,比如为3可以绑定到第0和第1个CPU,为5可以绑定到第0和第2个CPU。
void
ngx_setaffinity(uint64_t cpu_affinity, ngx_log_t *log)
{
    cpuset_t    mask;
    ngx_uint_t  i;

    ngx_log_error(NGX_LOG_NOTICE, log, 0,
                  "cpuset_setaffinity(0x%08Xl)", cpu_affinity);

    CPU_ZERO(&mask);
    i = 0;
    do {
        if (cpu_affinity & 1) {
            CPU_SET(i, &mask);
        }
        i++;
        cpu_affinity >>= 1;
    } while (cpu_affinity);

    if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
                           sizeof(cpuset_t), &mask) == -1)
    {
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                      "cpuset_setaffinity() failed");
    }
}
Exemplo n.º 2
0
// Pins the current thread to the given cpuset ID, ie [0..cpuset_size()).
int pin_thread(unsigned aid){
	cpu_set_t mask;

	CPU_ZERO(&mask);
	CPU_SET(aid,&mask);
#ifdef TORQUE_FREEBSD
	if(cpuset_setaffinity(CPU_LEVEL_WHICH,CPU_WHICH_TID,-1,
				sizeof(mask),&mask)){
#else
	if(sched_setaffinity(0,sizeof(mask),&mask)){
#endif
		return -1;
	}
	return 0;
}

static int
block_thread(pthread_t tid){
	void *joinret = PTHREAD_CANCELED;

	// FIXME various race conditions cause NULL to emerge from
	// pthread_join(). they're not important, save being logically tidy
	// (and worth investigating)...for now, toss that check.
	if(pthread_join(tid,&joinret)/* || joinret != PTHREAD_CANCELED*/){
		return -1;
	}
	return 0;
}
Exemplo n.º 3
0
void
setclasscpumask(login_cap_t *lc)
{
	const char *maskstr;
	cpuset_t maskset;
	cpusetid_t setid;

	maskstr = login_getcapstr(lc, "cpumask", NULL, NULL);
	CPU_ZERO(&maskset);
	if (maskstr == NULL)
		return;
	if (strcasecmp("default", maskstr) == 0)
		return;
	if (!list2cpuset(maskstr, &maskset)) {
		syslog(LOG_WARNING,
		    "list2cpuset(%s) invalid mask specification", maskstr);
		return;
	}

	if (cpuset(&setid) != 0) {
		syslog(LOG_ERR, "cpuset(): %s", strerror(errno));
		return;
	}

	if (cpuset_setaffinity(CPU_LEVEL_CPUSET, CPU_WHICH_PID, -1,
	    sizeof(maskset), &maskset) != 0)
		syslog(LOG_ERR, "cpuset_setaffinity(%s): %s", maskstr,
		    strerror(errno));
}
Exemplo n.º 4
0
bool ph_thread_set_affinity(ph_thread_t *me, int affinity)
{
#ifdef HAVE_PTHREAD_SETAFFINITY_NP
# ifdef __linux__
  cpu_set_t set;
# else /* FreeBSD */
  cpuset_t set;
#endif

  CPU_ZERO(&set);
  CPU_SET(affinity, &set);

  return pthread_setaffinity_np(me->thr, sizeof(set), &set) == 0;
#elif defined(__APPLE__)
  thread_affinity_policy_data_t data;

  data.affinity_tag = affinity + 1;
  return thread_policy_set(pthread_mach_thread_np(me->thr),
      THREAD_AFFINITY_POLICY,
      (thread_policy_t)&data, THREAD_AFFINITY_POLICY_COUNT) == 0;
#elif defined(HAVE_CPUSET_SETAFFINITY)
  /* untested bsdish */
  cpuset_t set;

  CPU_ZERO(&set);
  CPU_SET(affinity, &set);
  cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(set), set);
#elif defined(HAVE_PROCESSOR_BIND)
  return processor_bind(P_LWPID, me->lwpid, affinity, NULL) == 0;
#endif
  return true;
}
Exemplo n.º 5
0
static inline void affine_to_cpu(int id, int cpu)
{
	cpuset_t set;
	CPU_ZERO(&set);
	CPU_SET(cpu, &set);
	cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_CPUSET, -1, sizeof(cpuset_t), &set);
}
Exemplo n.º 6
0
void set_affinity(int cpu)
{
#ifdef __LINUX__
	typedef cpu_set_t fg_cpuset;
#elif __FreeBSD__
	typedef cpuset_t fg_cpuset;
#endif /* __LINUX__ */
	int rc;
	int ncpu = sysconf(_SC_NPROCESSORS_ONLN);   /* number of cores */
	fg_cpuset cpuset;			    /* define cpu_set bit mask */

	/* sanity check */
	if (cpu > ncpu) {
		logging_log(LOG_WARNING, "CPU binding failed. Given cpu number "
			    "is higher then the available cores");
		return;
	}

	CPU_ZERO(&cpuset);	/* initialize to 0, i.e. no CPUs selected. */
	CPU_SET(cpu, &cpuset);	/* set bit that represents the given core */

#ifdef __LINUX__
	rc = sched_setaffinity(getpid(), sizeof(cpuset), &cpuset);
#elif __FreeBSD__
	rc = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
				sizeof(cpuset), &cpuset);
#endif /* __LINUX__ */
	if (rc)
		logging_log(LOG_WARNING, "failed to bind %s (PID %d) to "
			    "CPU %i\n", progname, getpid(), cpu);
	else
		DEBUG_MSG(LOG_WARNING, "bind %s (PID %d) to CPU %i\n",
			  progname, getpid(), cpu);
}
Exemplo n.º 7
0
static void set_affinity_mask( size_t maskSize, const basic_mask_t* threadMask ) {
#if __linux__
    if( sched_setaffinity( 0, maskSize, threadMask ) )
#else /* FreeBSD */
    if( cpuset_setaffinity( CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, maskSize, threadMask ) )
#endif
        runtime_warning( "setaffinity syscall failed" );
}
Exemplo n.º 8
0
static inline void affine_to_cpu(int id, int cpu)
{
// CB
//    applog(LOG_INFO, "Binding Linux thread %d to cpu %d", id, cpu);
	cpuset_t set;
	CPU_ZERO(&set);
	CPU_SET(cpu, &set);
	cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_CPUSET, -1, sizeof(cpuset_t), &set);
}
Exemplo n.º 9
0
void bind_cpu(unsigned int cpunr)
{
	cpuset_t mask;

	CPU_ZERO(&mask);
	CPU_SET(cpunr, &mask);
	(void) cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
	    sizeof(mask), &mask);
}
Exemplo n.º 10
0
/*
 * Set the affinity of current thread to given cpu
 */
static void set_my_affinity(int cpunum)
{
  cpuset_t cpu_mask;
  CPU_ZERO(&cpu_mask);
  CPU_SET(cpunum, &cpu_mask);
  if(cpuset_setaffinity(CPU_LEVEL_WHICH ,CPU_WHICH_TID, (id_t) -1, sizeof(cpu_mask), &cpu_mask))
    err(1, "set affinity cpunum=%d", cpunum);

}
Exemplo n.º 11
0
static bool apply_affinity(ph_cpu_set_t *set, ph_thread_t *me) {
#  ifdef HAVE_CPUSET_SETAFFINITY
  ph_unused_parameter(me);
  return cpuset_setaffinity(CPU_LEVEL_WHICH,
      CPU_WHICH_TID, -1, sizeof(*set), set) == 0;
#  else
  return pthread_setaffinity_np(me->thr, sizeof(*set), set) == 0;
#endif
}
Exemplo n.º 12
0
static int ATL_setmyaffinity()
/*
 * Attempts to sets the affinity of an already-running thread.  The
 * aff_set flag is set to true whether we succeed or not (no point in
 * trying multiple times).
 * RETURNS: 0 on success, non-zero error code on error
 */
{
   int bindID;
   bindID = omp_get_thread_num();
   #ifdef ATL_RANK_IS_PROCESSORID
      bindID = bindID % ATL_AFF_NUMID;
   #else
      bindID = ATL_affinityIDs[bindID%ATL_AFF_NUMID];
   #endif
#ifdef ATL_PAFF_PLPA
   plpa_cpu_set_t cpuset;
   PLPA_CPU_ZERO(&cpuset);
   PLPA_CPU_SET(bindID, &cpuset);
   if (me->paff_set)
      return(0);
   me->paff_set = 1;
   return(plpa_sched_setaffinity((pid_t)0, sizeof(cpuset), &cpuset));
#elif defined(ATL_PAFF_PBIND)
   return(processor_bind(P_LWPID, P_MYID, bindID, NULL));
#elif defined(ATL_PAFF_SCHED)
   cpu_set_t cpuset;
   CPU_ZERO(&cpuset);
   CPU_SET(bindID, &cpuset);
   if (me->paff_set)
      return(0);
   me->paff_set = 1;
   return(sched_setaffinity(0, sizeof(cpuset), &cpuset));
#elif defined (ATL_PAFF_RUNON)
   if (me->paff_set)
      return(0);
   me->paff_set = 1;
   return(pthread_setrunon_np(bindID));
#elif defined(ATL_PAFF_BINDP)
   if (me->paff_set)
      return(0);
   me->paff_set = 1;
   return(bindprocessor(BINDTHREAD, thread_self(), bindID));
#elif defined(ATL_PAFF_CPUSET)  /* untried FreeBSD code */
   cpuset_t mycpuset;
   CPU_ZERO(&mycpuset);         /* no manpage, so guess works like linux */
   CPU_SET(bindID, &mycpuset);
   if (me->paff_set)
      return(0);
   me->paff_set = 1;
   return(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
                             sizeof(mycpuset), &mycpuset));
#endif
   return(0);
}
Exemplo n.º 13
0
int
_pthread_setaffinity_np(pthread_t td, size_t cpusetsize, const cpuset_t *cpusetp)
{
	struct pthread	*curthread = _get_curthread();
	lwpid_t		tid;
	int		error;

	if (td == curthread) {
		error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
			-1, cpusetsize, cpusetp);
		if (error == -1)
			error = errno;
	} else if ((error = _thr_find_thread(curthread, td, 0)) == 0) {
		tid = TID(td);
		error = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid,
			cpusetsize, cpusetp);
		if (error == -1)
			error = errno;
		THR_THREAD_UNLOCK(curthread, td);
	}
	return (error);
}
Exemplo n.º 14
0
void bind_thread_to_cpu(int cpuid) {
    cpuset_t mask;

    memset(&mask, 0, sizeof(mask));

    // bind this thread to a single cpu
    CPU_SET(cpuid, &mask);
    if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
                           sizeof(mask), &mask) < 0) {
      errx(1, "cpuset_setaffinity");
      return;
    }
}
Exemplo n.º 15
0
PyObject *
psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) {
    // Set process CPU affinity.
    // Reference:
    // http://sources.freebsd.org/RELENG_9/src/usr.bin/cpuset/cpuset.c
    long pid;
    int i;
    int seq_len;
    int ret;
    cpuset_t cpu_set;
    PyObject *py_cpu_set;
    PyObject *py_cpu_seq = NULL;

    if (!PyArg_ParseTuple(args, "lO", &pid, &py_cpu_set))
        return NULL;

    py_cpu_seq = PySequence_Fast(py_cpu_set, "expected a sequence or integer");
    if (!py_cpu_seq)
        return NULL;
    seq_len = PySequence_Fast_GET_SIZE(py_cpu_seq);

    // calculate the mask
    CPU_ZERO(&cpu_set);
    for (i = 0; i < seq_len; i++) {
        PyObject *item = PySequence_Fast_GET_ITEM(py_cpu_seq, i);
#if PY_MAJOR_VERSION >= 3
        long value = PyLong_AsLong(item);
#else
        long value = PyInt_AsLong(item);
#endif
        if (value == -1 && PyErr_Occurred())
            goto error;
        CPU_SET(value, &cpu_set);
    }

    // set affinity
    ret = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
                             sizeof(cpu_set), &cpu_set);
    if (ret != 0) {
        PyErr_SetFromErrno(PyExc_OSError);
        goto error;
    }

    Py_DECREF(py_cpu_seq);
    Py_RETURN_NONE;

error:
    if (py_cpu_seq != NULL)
        Py_DECREF(py_cpu_seq);
    return NULL;
}
Exemplo n.º 16
0
/*
 * This (allegedly) OS threads independent layer was initially
 * abstracted away from code that used Pthreads, so the functions
 * provided here are mostly just wrappers to the Pthreads API.
 *
 */

void
initCondition( Condition* pCond )
{
  pthread_cond_init(pCond, NULL);
  return;
}

void
closeCondition( Condition* pCond )
{
  pthread_cond_destroy(pCond);
  return;
}

rtsBool
broadcastCondition ( Condition* pCond )
{
  return (pthread_cond_broadcast(pCond) == 0);
}

rtsBool
signalCondition ( Condition* pCond )
{
  return (pthread_cond_signal(pCond) == 0);
}

rtsBool
waitCondition ( Condition* pCond, Mutex* pMut )
{
  return (pthread_cond_wait(pCond,pMut) == 0);
}

void
yieldThread(void)
{
  sched_yield();
  return;
}

void
shutdownThread(void)
{
  pthread_exit(NULL);
}

int
createOSThread (OSThreadId* pId, OSThreadProc *startProc, void *param)
{
  int result = pthread_create(pId, NULL, (void *(*)(void *))startProc, param);
  if(!result)
    pthread_detach(*pId);
  return result;
}

OSThreadId
osThreadId(void)
{
  return pthread_self();
}

rtsBool
osThreadIsAlive(OSThreadId id STG_UNUSED)
{
    // no good way to implement this on POSIX, AFAICT.  Returning true
    // is safe.
    return rtsTrue;
}

void
initMutex(Mutex* pMut)
{
#if defined(DEBUG)
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_ERRORCHECK);
    pthread_mutex_init(pMut,&attr);
#else
    pthread_mutex_init(pMut,NULL);
#endif
    return;
}
void
closeMutex(Mutex* pMut)
{
    pthread_mutex_destroy(pMut);
}

void
newThreadLocalKey (ThreadLocalKey *key)
{
    int r;
    if ((r = pthread_key_create(key, NULL)) != 0) {
	barf("newThreadLocalKey: %s", strerror(r));
    }
}

void *
getThreadLocalVar (ThreadLocalKey *key)
{
    return pthread_getspecific(*key);
    // Note: a return value of NULL can indicate that either the key
    // is not valid, or the key is valid and the data value has not
    // yet been set.  We need to use the latter case, so we cannot
    // detect errors here.
}

void
setThreadLocalVar (ThreadLocalKey *key, void *value)
{
    int r;
    if ((r = pthread_setspecific(*key,value)) != 0) {
	barf("setThreadLocalVar: %s", strerror(r));
    }
}

void
freeThreadLocalKey (ThreadLocalKey *key)
{
    int r;
    if ((r = pthread_key_delete(*key)) != 0) {
	barf("freeThreadLocalKey: %s", strerror(r));
    }
}

static void *
forkOS_createThreadWrapper ( void * entry )
{
    Capability *cap;
    cap = rts_lock();
    rts_evalStableIO(&cap, (HsStablePtr) entry, NULL);
    rts_unlock(cap);
    return NULL;
}

int
forkOS_createThread ( HsStablePtr entry )
{
    pthread_t tid;
    int result = pthread_create(&tid, NULL,
				forkOS_createThreadWrapper, (void*)entry);
    if(!result)
        pthread_detach(tid);
    return result;
}

nat
getNumberOfProcessors (void)
{
    static nat nproc = 0;

    if (nproc == 0) {
#if defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
        nproc = sysconf(_SC_NPROCESSORS_ONLN);
#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_CONF)
        nproc = sysconf(_SC_NPROCESSORS_CONF);
#elif defined(darwin_HOST_OS) || defined(freebsd_HOST_OS)
        size_t size = sizeof(nat);
        if(0 != sysctlbyname("hw.ncpu",&nproc,&size,NULL,0))
            nproc = 1;
#else
        nproc = 1;
#endif
    }

    return nproc;
}

#if defined(HAVE_SCHED_H) && defined(HAVE_SCHED_SETAFFINITY)
// Schedules the thread to run on CPU n of m.  m may be less than the
// number of physical CPUs, in which case, the thread will be allowed
// to run on CPU n, n+m, n+2m etc.
void
setThreadAffinity (nat n, nat m)
{
    nat nproc;
    cpu_set_t cs;
    nat i;

    nproc = getNumberOfProcessors();
    CPU_ZERO(&cs);
    for (i = n; i < nproc; i+=m) {
        CPU_SET(i, &cs);
    }
    sched_setaffinity(0, sizeof(cpu_set_t), &cs);
}

#elif defined(darwin_HOST_OS) && defined(THREAD_AFFINITY_POLICY)
// Schedules the current thread in the affinity set identified by tag n.
void
setThreadAffinity (nat n, nat m GNUC3_ATTRIBUTE(__unused__))
{
    thread_affinity_policy_data_t policy;

    policy.affinity_tag = n;
    thread_policy_set(mach_thread_self(), 
		      THREAD_AFFINITY_POLICY,
		      (thread_policy_t) &policy,
		      THREAD_AFFINITY_POLICY_COUNT);
}

#elif defined(HAVE_SYS_CPUSET_H) /* FreeBSD 7.1+ */
void
setThreadAffinity(nat n, nat m)
{
	nat nproc;
	cpuset_t cs;
	nat i;

	nproc = getNumberOfProcessors();
	CPU_ZERO(&cs);

	for (i = n; i < nproc; i += m)
		CPU_SET(i, &cs);

	cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1, sizeof(cpuset_t), &cs);
}
Exemplo n.º 17
0
static int SetCPUAffinitySet(cpu_set_t *cs) {
#if  defined OS_FREEBSD
    int r = cpuset_setaffinity(CPU_LEVEL_WHICH,CPU_WHICH_TID,SCGetThreadIdLong(),sizeof(cpu_set_t),cs);
#elif OS_DARWIN
    int r = thread_policy_set(mach_thread_self(), THREAD_AFFINITY_POLICY, (void*)cs, THREAD_AFFINITY_POLICY_COUNT);
#else
    pid_t tid = syscall(SYS_gettid);
    int r = sched_setaffinity(tid,sizeof(cpu_set_t),cs);
#endif /* OS_FREEBSD */

    if (r != 0) {
        printf("Warning: sched_setaffinity failed (%" PRId32 "): %s\n", r, strerror(errno));
        return -1;
    }

    return 0;
}
Exemplo n.º 18
0
int slurm_setaffinity(pid_t pid, size_t size, const cpu_set_t *mask)
{
	int rval;
	char mstr[1 + CPU_SETSIZE / 4];

#ifdef __FreeBSD__
        rval = cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
				pid, size, mask);
#elif defined(SCHED_GETAFFINITY_THREE_ARGS)
	rval = sched_setaffinity(pid, size, mask);
#else
	rval = sched_setaffinity(pid, mask);
#endif
	if (rval) {
		verbose("sched_setaffinity(%d,%zd,0x%s) failed: %m",
			pid, size, task_cpuset_to_str(mask, mstr));
	}
	return (rval);
}
Exemplo n.º 19
0
void
ngx_setaffinity(ngx_cpuset_t *cpu_affinity, ngx_log_t *log)
{
    ngx_uint_t  i;

    for (i = 0; i < CPU_SETSIZE; i++) {
        if (CPU_ISSET(i, cpu_affinity)) {
            ngx_log_error(NGX_LOG_NOTICE, log, 0,
                          "cpuset_setaffinity(): using cpu #%ui", i);
        }
    }

    if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
                           sizeof(cpuset_t), cpu_affinity) == -1)
    {
        ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
                      "cpuset_setaffinity() failed");
    }
}
Exemplo n.º 20
0
int virProcessSetAffinity(pid_t pid,
                          virBitmapPtr map)
{
    size_t i;
    cpuset_t mask;

    CPU_ZERO(&mask);
    for (i = 0; i < virBitmapSize(map); i++) {
        if (virBitmapIsBitSet(map, i))
            CPU_SET(i, &mask);
    }

    if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
                           sizeof(mask), &mask) != 0) {
        virReportSystemError(errno,
                             _("cannot set CPU affinity on process %d"), pid);
        return -1;
    }

    return 0;
}
Exemplo n.º 21
0
int virProcessSetAffinity(pid_t pid ATTRIBUTE_UNUSED,
                          virBitmapPtr map)
{
    size_t i;
    cpuset_t mask;
    bool set = false;

    CPU_ZERO(&mask);
    for (i = 0; i < virBitmapSize(map); i++) {
        if (virBitmapGetBit(map, i, &set) < 0)
            return -1;
        if (set)
            CPU_SET(i, &mask);
    }

    if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, pid,
                           sizeof(mask), &mask) != 0) {
        virReportSystemError(errno,
                             _("cannot set CPU affinity on process %d"), pid);
        return -1;
    }

    return 0;
}
Exemplo n.º 22
0
int
main(int argc, char *argv[])
{
	cpusetid_t setid;
	cpuset_t mask;
	lwpid_t tid;
	pid_t pid;
	int ch;

	CPU_ZERO(&mask);
	level = CPU_LEVEL_WHICH;
	which = CPU_WHICH_PID;
	id = pid = tid = setid = -1;
	while ((ch = getopt(argc, argv, "Ccgij:l:p:rs:t:x:")) != -1) {
		switch (ch) {
		case 'C':
			Cflag = 1;
			break;
		case 'c':
			if (rflag)
				usage();
			cflag = 1;
			level = CPU_LEVEL_CPUSET;
			break;
		case 'g':
			gflag = 1;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'j':
			jflag = 1;
			which = CPU_WHICH_JAIL;
			id = atoi(optarg);
			break;
		case 'l':
			lflag = 1;
			parselist(optarg, &mask);
			break;
		case 'p':
			pflag = 1;
			which = CPU_WHICH_PID;
			id = pid = atoi(optarg);
			break;
		case 'r':
			if (cflag)
				usage();
			level = CPU_LEVEL_ROOT;
			rflag = 1;
			break;
		case 's':
			sflag = 1;
			which = CPU_WHICH_CPUSET;
			id = setid = atoi(optarg);
			break;
		case 't':
			tflag = 1;
			which = CPU_WHICH_TID;
			id = tid = atoi(optarg);
			break;
		case 'x':
			xflag = 1;
			which = CPU_WHICH_IRQ;
			id = atoi(optarg);
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;
	if (gflag) {
		if (argc || Cflag || lflag)
			usage();
		/* Only one identity specifier. */
		if (jflag + xflag + sflag + pflag + tflag > 1)
			usage();
		if (iflag)
			printsetid();
		else
			printaffinity();
		exit(EXIT_SUCCESS);
	}
	if (iflag)
		usage();
	/*
	 * The user wants to run a command with a set and possibly cpumask.
	 */
	if (argc) {
		if (Cflag | pflag | rflag | tflag | xflag | jflag)
			usage();
		if (sflag) {
			if (cpuset_setid(CPU_WHICH_PID, -1, setid))
				err(argc, "setid");
		} else {
			if (cpuset(&setid))
				err(argc, "newid");
		}
		if (lflag) {
			if (cpuset_setaffinity(level, CPU_WHICH_PID,
			    -1, sizeof(mask), &mask) != 0)
				err(EXIT_FAILURE, "setaffinity");
		}
		errno = 0;
		execvp(*argv, argv);
		err(errno == ENOENT ? 127 : 126, "%s", *argv);
	}
	/*
	 * We're modifying something that presently exists.
	 */
	if (Cflag && (sflag || rflag || !pflag || tflag || xflag || jflag))
		usage();
	if (!lflag && (cflag || rflag))
		usage();
	if (!lflag && !(Cflag || sflag))
		usage();
	/* You can only set a mask on a thread. */
	if (tflag && (sflag | pflag | xflag | jflag))
		usage();
	/* You can only set a mask on an irq. */
	if (xflag && (jflag | pflag | sflag | tflag))
		usage();
	if (Cflag) {
		/*
		 * Create a new cpuset and move the specified process
		 * into the set.
		 */
		if (cpuset(&setid) < 0)
			err(EXIT_FAILURE, "newid");
		sflag = 1;
	}
	if (pflag && sflag) {
		if (cpuset_setid(CPU_WHICH_PID, pid, setid))
			err(EXIT_FAILURE, "setid");
		/*
		 * If the user specifies a set and a list we want the mask
		 * to effect the pid and not the set.
		 */
		which = CPU_WHICH_PID;
		id = pid;
	}
	if (lflag) {
		if (cpuset_setaffinity(level, which, id, sizeof(mask),
		    &mask) != 0)
			err(EXIT_FAILURE, "setaffinity");
	}

	exit(EXIT_SUCCESS);
}
Exemplo n.º 23
0
/**
 * Signal handler for HUP which tells us to swap the log file
 * and reload configuration file if specified
 *
 * @param sig
 */
void
do_signal_sighup(RunTimeOpts * rtOpts, PtpClock * ptpClock)
{

    NOTIFY("SIGHUP received\n");

#ifdef RUNTIME_DEBUG
    if(rtOpts->transport == UDP_IPV4 && rtOpts->ip_mode != IPMODE_UNICAST) {
        DBG("SIGHUP - running an ipv4 multicast based mode, re-sending IGMP joins\n");
        netRefreshIGMP(&ptpClock->netPath, rtOpts, ptpClock);
    }
#endif /* RUNTIME_DEBUG */


    /* if we don't have a config file specified, we're done - just reopen log files*/
    if(strlen(rtOpts->configFile) ==  0)
        goto end;

    dictionary* tmpConfig = dictionary_new(0);
    /* Try reloading the config file */
    NOTIFY("Reloading configuration file: %s\n",rtOpts->configFile);
    if(!loadConfigFile(&tmpConfig, rtOpts)) {
        dictionary_del(tmpConfig);
        goto end;
    }
    dictionary_merge(rtOpts->cliConfig, tmpConfig, 1, "from command line");
    /* Load default config to fill in the blanks in the config file */
    RunTimeOpts tmpOpts;
    loadDefaultSettings(&tmpOpts);

    /* Check the new configuration for errors, fill in the blanks from defaults */
    if( ( rtOpts->candidateConfig = parseConfig(tmpConfig,&tmpOpts)) == NULL ) {
        WARNING("Configuration file has errors, reload aborted\n");
        dictionary_del(tmpConfig);
        goto end;
    }

    /* Check for changes between old and new configuration */
    if(compareConfig(rtOpts->candidateConfig,rtOpts->currentConfig)) {
        INFO("Configuration unchanged\n");
        goto cleanup;
    }

    /*
     * Mark which subsystems have to be restarted. Most of this will be picked up by doState()
     * If there are errors past config correctness (such as non-existent NIC,
     * or lock file clashes if automatic lock files used - abort the mission
     */

    rtOpts->restartSubsystems =
        checkSubsystemRestart(rtOpts->candidateConfig, rtOpts->currentConfig);

    /* If we're told to re-check lock files, do it: tmpOpts already has what rtOpts should */
    if( (rtOpts->restartSubsystems & PTPD_CHECK_LOCKS) &&
            tmpOpts.autoLockFile && !checkOtherLocks(&tmpOpts)) {
        rtOpts->restartSubsystems = -1;
    }

    /* If the network configuration has changed, check if the interface is OK */
    if(rtOpts->restartSubsystems & PTPD_RESTART_NETWORK) {
        INFO("Network configuration changed - checking interface\n");
        if(!testInterface(tmpOpts.ifaceName, &tmpOpts)) {
            rtOpts->restartSubsystems = -1;
            ERROR("Error: Cannot use %s interface\n",tmpOpts.ifaceName);
        }

    }


#if defined(linux) && defined(HAVE_SCHED_H)
    /* Changing the CPU affinity mask */
    if(rtOpts->restartSubsystems & PTPD_CHANGE_CPUAFFINITY) {
        NOTIFY("Applying CPU binding configuration: changing selected CPU core\n");
        cpu_set_t mask;
        CPU_ZERO(&mask);
        if(tmpOpts.cpuNumber > -1) {
            CPU_SET(tmpOpts.cpuNumber,&mask);
        } else {
            int i;
            for(i = 0;  i < CPU_SETSIZE; i++) {
                CPU_SET(i, &mask);
            }
        }
        if(sched_setaffinity(0, sizeof(mask), &mask) < 0) {
            if(tmpOpts.cpuNumber == -1) {
                PERROR("Could not unbind from CPU core %d", rtOpts->cpuNumber);
            } else {
                PERROR("Could bind to CPU core %d", tmpOpts.cpuNumber);
            }
            rtOpts->restartSubsystems = -1;
        } else {
            if(tmpOpts.cpuNumber > -1)
                INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", tmpOpts.cpuNumber);
            else
                INFO("Successfully unbound "PTPD_PROGNAME" from cpu core CPU core %d\n", rtOpts->cpuNumber);
        }
    }
#endif /* linux && HAVE_SCHED_H */

#ifdef HAVE_SYS_CPUSET_H
    /* Changing the CPU affinity mask */
    if (rtOpts->restartSubsystems & PTPD_CHANGE_CPUAFFINITY) {
        NOTIFY("Applying CPU binding configuration:"
               "changing selected CPU core\n");
        cpuset_t mask;
        CPU_ZERO(&mask);
        if (tmpOpts.cpuNumber < 0) {
            if (cpuset_getaffinity(CPU_LEVEL_ROOT, CPU_WHICH_CPUSET, 1,
                                   sizeof(mask), &mask) < 0)
                PERROR("Could not get affinity.");
            if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
                                   -1, sizeof(mask), &mask) < 0)
                PERROR("Could not unbind from CPU core %d",
                       rtOpts->cpuNumber);
            else
                INFO("Successfully unbound "
                     PTPD_PROGNAME" from cpu core CPU core %d\n",
                     rtOpts->cpuNumber);
        } else {
            CPU_SET(tmpOpts.cpuNumber,&mask);
            if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
                                   -1, sizeof(mask), &mask) < 0)  {
                PERROR("Could not bind to CPU core %d",
                       tmpOpts.cpuNumber);
                rtOpts->restartSubsystems = -1;
            } else {
                INFO("Successfully bound "
                     PTPD_PROGNAME" to CPU core %d\n",
                     tmpOpts.cpuNumber);
            }
        }
    }
#endif

    if(rtOpts->restartSubsystems == -1) {
        ERROR("New configuration cannot be applied - aborting reload\n");
        rtOpts->restartSubsystems = 0;
        goto cleanup;
    }


    /* Tell parseConfig to shut up - it's had its chance already */
    dictionary_set(rtOpts->candidateConfig,"%quiet%:%quiet%","Y");

    /**
     * Commit changes to rtOpts and currentConfig
     * (this should never fail as the config has already been checked if we're here)
     * However if this DOES fail, some default has been specified out of range -
     * this is the only situation where parse will succeed but commit not:
     * disable quiet mode to show what went wrong, then die.
     */
    if (rtOpts->currentConfig) {
        dictionary_del(rtOpts->currentConfig);
    }
    if ( (rtOpts->currentConfig = parseConfig(rtOpts->candidateConfig,rtOpts)) == NULL) {
        CRITICAL("************ "PTPD_PROGNAME": parseConfig returned NULL during config commit"
                 "  - this is a BUG - report the following: \n");

        dictionary_unset(rtOpts->candidateConfig,"%quiet%:%quiet%");

        if ((rtOpts->currentConfig = parseConfig(rtOpts->candidateConfig,rtOpts)) == NULL)
            CRITICAL("*****************" PTPD_PROGNAME" shutting down **********************\n");
        /*
         * Could be assert(), but this should be done any time this happens regardless of
         * compile options. Anyhow, if we're here, the daemon will no doubt segfault soon anyway
         */
        abort();
    }

    /* clean up */
cleanup:

    dictionary_del(tmpConfig);
    dictionary_del(rtOpts->candidateConfig);

end:

    if(rtOpts->recordLog.logEnabled ||
            rtOpts->eventLog.logEnabled ||
            (rtOpts->statisticsLog.logEnabled))
        INFO("Reopening log files\n");

    restartLogging(rtOpts);

    if(rtOpts->statisticsLog.logEnabled)
        ptpClock->resetStatisticsLog = TRUE;


}
Exemplo n.º 24
0
PtpClock *
ptpdStartup(int argc, char **argv, Integer16 * ret, RunTimeOpts * rtOpts)
{
    PtpClock * ptpClock;
    int i = 0;

    /*
     * Set the default mode for all newly created files - previously
     * this was not the case for log files. This adds consistency
     * and allows to use FILE* vs. fds everywhere
     */
    umask(~DEFAULT_FILE_PERMS);

    /**
     * If a required setting, such as interface name, or a setting
     * requiring a range check is to be set via getopts_long,
     * the respective currentConfig dictionary entry should be set,
     * instead of just setting the rtOpts field.
     *
     * Config parameter evaluation priority order:
     * 	1. Any dictionary keys set in the getopt_long loop
     * 	2. CLI long section:key type options
     * 	3. Config file (parsed last), merged with 2. and 3 - will be overwritten by CLI options
     * 	4. Defaults and any rtOpts fields set in the getopt_long loop
    **/

    /**
     * Load defaults. Any options set here and further inside loadCommandLineOptions()
     * by setting rtOpts fields, will be considered the defaults
     * for config file and section:key long options.
     */
    loadDefaultSettings(rtOpts);
    /* initialise the config dictionary */
    rtOpts->candidateConfig = dictionary_new(0);
    rtOpts->cliConfig = dictionary_new(0);
    /* parse all long section:key options and clean up argv for getopt */
    loadCommandLineKeys(rtOpts->cliConfig,argc,argv);
    /* parse the normal short and long option, exit on error */
    if (!loadCommandLineOptions(rtOpts, rtOpts->cliConfig, argc, argv, ret)) {
        goto fail;
    }

    /* Display startup info and argv if not called with -? or -H */
    NOTIFY("%s version %s starting\n",USER_DESCRIPTION, USER_VERSION);
    dump_command_line_parameters(argc, argv);
    /*
     * we try to catch as many error conditions as possible, but before we call daemon().
     * the exception is the lock file, as we get a new pid when we call daemon(),
     * so this is checked twice: once to read, second to read/write
     */
    if(geteuid() != 0)
    {
        printf("Error: "PTPD_PROGNAME" daemon can only be run as root\n");
        *ret = 1;
        goto fail;
    }

    /* Have we got a config file? */
    if(strlen(rtOpts->configFile) > 0) {
        /* config file settings overwrite all others, except for empty strings */
        INFO("Loading configuration file: %s\n",rtOpts->configFile);
        if(loadConfigFile(&rtOpts->candidateConfig, rtOpts)) {
            dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
        } else {
            *ret = 1;
            dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
            goto configcheck;
        }
    } else {
        dictionary_merge(rtOpts->cliConfig, rtOpts->candidateConfig, 1, "from command line");
    }
    /**
     * This is where the final checking  of the candidate settings container happens.
     * A dictionary is returned with only the known options, explicitly set to defaults
     * if not present. NULL is returned on any config error - parameters missing, out of range,
     * etc. The getopt loop in loadCommandLineOptions() only sets keys verified here.
     */
    if( ( rtOpts->currentConfig = parseConfig(rtOpts->candidateConfig,rtOpts)) == NULL ) {
        *ret = 1;
        dictionary_del(rtOpts->candidateConfig);
        goto configcheck;
    }

    /* we've been told to print the lock file and exit cleanly */
    if(rtOpts->printLockFile) {
        printf("%s\n", rtOpts->lockFile);
        *ret = 0;
        goto fail;
    }

    /* we don't need the candidate config any more */
    dictionary_del(rtOpts->candidateConfig);

    /* Check network before going into background */
    if(!testInterface(rtOpts->ifaceName, rtOpts)) {
        ERROR("Error: Cannot use %s interface\n",rtOpts->ifaceName);
        *ret = 1;
        goto configcheck;
    }

configcheck:
    /*
     * We've been told to check config only - clean exit before checking locks
     */
    if(rtOpts->checkConfigOnly) {
        if(*ret != 0) {
            printf("Configuration has errors\n");
            *ret = 1;
        }
        else
            printf("Configuration OK\n");
        return 0;
    }

    /* Previous errors - exit */
    if(*ret !=0)
        return 0;

    /* First lock check, just to be user-friendly to the operator */
    if(!rtOpts->ignore_daemon_lock) {
        if(!writeLockFile(rtOpts)) {
            /* check and create Lock */
            ERROR("Error: file lock failed (use -L or global:ignore_lock to ignore lock file)\n");
            *ret = 3;
            return 0;
        }
        /* check for potential conflicts when automatic lock files are used */
        if(!checkOtherLocks(rtOpts)) {
            *ret = 3;
            return 0;
        }
    }

    /* Manage log files: stats, log, status and quality file */
    restartLogging(rtOpts);

    /* Allocate memory after we're done with other checks but before going into daemon */
    ptpClock = (PtpClock *) calloc(1, sizeof(PtpClock));
    if (!ptpClock) {
        PERROR("Error: Failed to allocate memory for protocol engine data");
        *ret = 2;
        return 0;
    } else {
        DBG("allocated %d bytes for protocol engine data\n",
            (int)sizeof(PtpClock));
        ptpClock->foreign = (ForeignMasterRecord *)
                            calloc(rtOpts->max_foreign_records,
                                   sizeof(ForeignMasterRecord));
        if (!ptpClock->foreign) {
            PERROR("failed to allocate memory for foreign "
                   "master data");
            *ret = 2;
            free(ptpClock);
            return 0;
        } else {
            DBG("allocated %d bytes for foreign master data\n",
                (int)(rtOpts->max_foreign_records *
                      sizeof(ForeignMasterRecord)));
        }

        ptpClock->owd_filt = FilterCreate(FILTER_EXPONENTIAL_SMOOTH, "owd");
        ptpClock->ofm_filt = FilterCreate(FILTER_MOVING_AVERAGE, "ofm");
    }

    if(rtOpts->statisticsLog.logEnabled)
        ptpClock->resetStatisticsLog = TRUE;

    /* Init to 0 net buffer */
    memset(ptpClock->msgIbuf, 0, PACKET_SIZE);
    memset(ptpClock->msgObuf, 0, PACKET_SIZE);

    /* Init user_description */
    memset(ptpClock->user_description, 0, sizeof(ptpClock->user_description));
    memcpy(ptpClock->user_description, &USER_DESCRIPTION, sizeof(USER_DESCRIPTION));

    /* Init outgoing management message */
    ptpClock->outgoingManageTmp.tlv = NULL;


    /*  DAEMON */
#ifdef PTPD_NO_DAEMON
    if(!rtOpts->nonDaemon) {
        rtOpts->nonDaemon=TRUE;
    }
#endif

    if(!rtOpts->nonDaemon) {
        /*
         * fork to daemon - nochdir non-zero to preserve the working directory:
         * allows relative paths to be used for log files, config files etc.
         * Always redirect stdout/err to /dev/null
         */
        if (daemon(1,0) == -1) {
            PERROR("Failed to start as daemon");
            *ret = 3;
            return 0;
        }
        INFO("  Info:    Now running as a daemon\n");
        /*
         * Wait for the parent process to terminate, but not forever.
         * On some systems this happened after we tried re-acquiring
         * the lock, so the lock would fail. Hence, we wait.
         */
        for (i = 0; i < 1000000; i++) {
            /* Once we've been reaped by init, parent PID will be 1 */
            if(getppid() == 1)
                break;
            usleep(1);
        }
    }

    /* Second lock check, to replace the contents with our own new PID and re-acquire the advisory lock */
    if(!rtOpts->nonDaemon && !rtOpts->ignore_daemon_lock) {
        /* check and create Lock */
        if(!writeLockFile(rtOpts)) {
            ERROR("Error: file lock failed (use -L or global:ignore_lock to ignore lock file)\n");
            *ret = 3;
            return 0;
        }
    }

#if defined(linux) && defined(HAVE_SCHED_H)
    /* Try binding to a single CPU core if configured to do so */

    if(rtOpts->cpuNumber > -1) {

        cpu_set_t mask;
        CPU_ZERO(&mask);
        CPU_SET(rtOpts->cpuNumber,&mask);
        if(sched_setaffinity(0, sizeof(mask), &mask) < 0) {
            PERROR("Could not bind to CPU core %d", rtOpts->cpuNumber);
        } else {
            INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n", rtOpts->cpuNumber);
        }
    }
#endif /* linux && HAVE_SCHED_H */

#ifdef HAVE_SYS_CPUSET_H

    /* Try binding to a single CPU core if configured to do so */

    if(rtOpts->cpuNumber > -1) {
        cpuset_t mask;
        CPU_ZERO(&mask);
        CPU_SET(rtOpts->cpuNumber,&mask);
        if(cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID,
                              -1, sizeof(mask), &mask) < 0) {
            PERROR("Could not bind to CPU core %d",
                   rtOpts->cpuNumber);
        } else {
            INFO("Successfully bound "PTPD_PROGNAME" to CPU core %d\n",
                 rtOpts->cpuNumber);
        }
    }
#endif /* HAVE_SYS_CPUSET_H */

    /* use new synchronous signal handlers */
    signal(SIGINT,  catchSignals);
    signal(SIGTERM, catchSignals);
    signal(SIGHUP,  catchSignals);

    signal(SIGUSR1, catchSignals);
    signal(SIGUSR2, catchSignals);

#if defined PTPD_SNMP
    /* Start SNMP subsystem */
    if (rtOpts->snmp_enabled)
        snmpInit(rtOpts, ptpClock);
#endif



    NOTICE(USER_DESCRIPTION" started successfully on %s using \"%s\" preset (PID %d)\n",
           rtOpts->ifaceName,
           (getPtpPreset(rtOpts->selectedPreset,rtOpts)).presetName,
           getpid());
    ptpClock->resetStatisticsLog = TRUE;

#ifdef PTPD_STATISTICS
    if (rtOpts->delayMSOutlierFilterEnabled) {
        ptpClock->delayMSRawStats = createDoubleMovingStdDev(rtOpts->delayMSOutlierFilterCapacity);
        strncpy(ptpClock->delayMSRawStats->identifier, "delayMS", 10);
        ptpClock->delayMSFiltered = createDoubleMovingMean(rtOpts->delayMSOutlierFilterCapacity);
    } else {
        ptpClock->delayMSRawStats = NULL;
        ptpClock->delayMSFiltered = NULL;
    }

    if (rtOpts->delaySMOutlierFilterEnabled) {
        ptpClock->delaySMRawStats = createDoubleMovingStdDev(rtOpts->delaySMOutlierFilterCapacity);
        strncpy(ptpClock->delaySMRawStats->identifier, "delaySM", 10);
        ptpClock->delaySMFiltered = createDoubleMovingMean(rtOpts->delaySMOutlierFilterCapacity);
    } else {
        ptpClock->delaySMRawStats = NULL;
        ptpClock->delaySMFiltered = NULL;
    }
#endif

    *ret = 0;
    return ptpClock;

fail:
    dictionary_del(rtOpts->candidateConfig);
    return 0;
}
Exemplo n.º 25
0
int ATL_thread_start(ATL_thread_t *thr, int proc, int JOINABLE,
                     void *(*rout)(void*), void *arg)
/*
 * Creates a thread that will run only on processor proc.
 * RETURNS: 0 on success, non-zero on error
 * NOTE: present implementation dies on error, so 0 is always returned.
 */
{
#ifdef ATL_WINTHREADS
   #ifdef ATL_WIN32THREADS
      DWORD thrID;
   #else
      unsigned thrID;
   #endif

   #ifdef ATL_NOAFFINITY
      #ifdef ATL_WIN32THREADS
         thr->thrH = CreateThread(NULL, 0, rout, arg, 0, &thrID);
      #else
         thr->thrH = (HANDLE)_beginthreadex(NULL, 0, rout, arg, 0, &thrID);
      #endif
      ATL_assert(thr->thrH);
   #else
      thr->rank = proc;
      #ifdef ATL_WIN32THREADS
         thr->thrH = CreateThread(NULL, 0, rout, arg, CREATE_SUSPENDED, &thrID);
      #else
         thr->thrH = (HANDLE)_beginthreadex(NULL, 0, rout, arg,
                                            CREATE_SUSPENDED, &thrID);
      #endif
      ATL_assert(thr->thrH);
      #ifdef ATL_RANK_IS_PROCESSORID
         ATL_assert(SetThreadAffinityMask(thr->thrH, (1<<proc)));
      #else
         ATL_assert(SetThreadAffinityMask(thr->thrH,
                    (1<<ATL_affinityIDs[proc%ATL_AFF_NUMID])));
      #endif
      ATL_assert(ResumeThread(thr->thrH) == 1);
   #endif
#elif defined(ATL_OMP_THREADS)
   fprintf(stderr, "Should not call thread_start when using OpenMP!");
   ATL_assert(0);
#elif 0 && defined(ATL_OS_OSX)  /* unchecked special OSX code */
/* http://developer.apple.com/library/mac/#releasenotes/Performance/RN-AffinityAPI/_index.html */
   pthread_attr_t attr;
   #define ATL_OSX_AFF_SETS 2       /* should be probed for */
   thread_affinity_policy ap;

   ap.affinity_tag = proc % ATL_OSX_AFF_SETS;
   ATL_assert(!pthread_attr_init(&attr));
   if (JOINABLE)
      ATL_assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE));
   else
      ATL_assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
   pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* no chk, OK to fail */

   ATL_assert(!pthread_create(&thr->thrH, &attr, rout, arg));
   ATL_assert(!thread_policy_set(thr->thrH, THREAD_AFFINITY_POLICY,
                                 (integer_t*)&ap,
                                 THREAD_AFFINITY_POLICY_COUNT));
   ATL_assert(!pthread_attr_destroy(&attr));
#else
   pthread_attr_t attr;
   #ifndef ATL_NOAFFINITY
      #if defined(ATL_PAFF_SETAFFNP) || defined(ATL_PAFF_SCHED)
         cpu_set_t cpuset;
      #elif defined(ATL_PAFF_PLPA)
         plpa_cpu_set_t cpuset;
      #elif defined(ATL_PAFF_CPUSET) /* untried FreeBSD code */
         cpuset_t mycpuset;
      #endif
      #ifdef ATL_RANK_IS_PROCESSORID
         const int affID = proc;
      #else
         const int affID = ATL_affinityIDs[proc%ATL_AFF_NUMID];
      #endif
      #ifdef ATL_PAFF_SELF
         thr->paff_set = 0;  /* affinity must be set by created thread */
      #endif
   #endif
   thr->rank = proc;
   ATL_assert(!pthread_attr_init(&attr));
   if (JOINABLE)
   {
      #ifdef IBM_PT_ERROR
         ATL_assert(!pthread_attr_setdetachstate(&attr,
                                                 PTHREAD_CREATE_UNDETACHED));
      #else
         ATL_assert(!pthread_attr_setdetachstate(&attr,
                                                 PTHREAD_CREATE_JOINABLE));
      #endif
   }
   else
      ATL_assert(!pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED));
   pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); /* no chk, OK to fail */
   #ifdef ATL_PAFF_SETAFFNP
      CPU_ZERO(&cpuset);
      CPU_SET(affID, &cpuset);
      ATL_assert(!pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset));
   #elif defined(ATL_PAFF_SETPROCNP)
      ATL_assert(!pthread_attr_setprocessor_np(&attr, (pthread_spu_t)affID,
                                               PTHREAD_BIND_FORCED_NP));
   #endif
   ATL_assert(!pthread_create(&thr->thrH, &attr, rout, arg));
   #if defined(ATL_PAFF_PBIND)
      ATL_assert(!processor_bind(P_LWPID, thr->thrH, affID, NULL));
      thr->paff_set = 0;  /* affinity set by spawner */
   #elif defined(ATL_PAFF_BINDP)
      ATL_assert(!bindprocessor(BINDTHREAD, thr->thrH, bindID));
      thr->paff_set = 0;  /* affinity set by spawner */
   #elif defined(ATL_PAFF_CPUSET)  /* untried FreeBSD code */
      CPU_ZERO(&mycpuset);         /* no manpage, so guess works like linux */
      CPU_SET(bindID, &mycpuset);
      if (!cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, thr->thrH,
                              sizeof(mycpuset), &mycpuset));
         thr->paff_set = 0;  /* affinity set by spawner */
   #endif
   ATL_assert(!pthread_attr_destroy(&attr));
#endif
   return(0);
}
Exemplo n.º 26
0
int bpf_thread(struct bpf_thread_instance *instance)
{
	struct bpf_zbuf bz;
	struct ifreq ifr;
	int opt;

	CPU_ZERO(&instance->cpuset);
	CPU_SET(instance->cpu, &instance->cpuset);
	if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,
		sizeof(cpuset_t), &instance->cpuset) < 0) {
		perror("cpuset_setaffinity");
		exit(-1);
	}

	bzero(&ifr, sizeof(ifr));
	strlcpy(ifr.ifr_name, iflag, sizeof(ifr.ifr_name));
	instance->bpffd = bpf_open();
	if (instance->bpffd < 0) {
		(void) fprintf(stderr, "bpfnull: no bpf device available\n");
		exit(-1);
	}
	if (vflag)
		(void) fprintf(stderr,
		    "DEBUG: obtained bpf fd=%d\n", instance->bpffd);
	if (fflag)
		bpf_init_dumpfile(instance);
#ifdef BPF_BUFMODE_ZBUF
	if (zflag) {
		if (vflag)
			(void) fprintf(stderr,
			    "DEBUG: bufmode=zerocopy\n");
		bzero(&bz, sizeof(bz));
		bpf_zbuf_init(instance, &bz);
		if (ioctl(instance->bpffd, BIOCSETIF, &ifr) < 0)
			err(1, "ioctl(BIOCSETIF)");
	} else {
#endif
		if (vflag)
			(void) fprintf(stderr,
			    "DEBUG: bufmode=buffer\n");
		bpf_rbuf_init(instance);
#ifdef BPF_BUFMODE_ZBUF
	}
#endif
	if (Iflag) {
		if (vflag)
			(void) fprintf(stderr,
			    "DEBUG: setting BIOCIMMEDIATE\n");
		opt = 1;
		if (ioctl(instance->bpffd, BIOCIMMEDIATE, &opt) < 0)
			err(1, "BIOCIMMEDIATE");
	}
	if (Pflag) {
		if (vflag)
			(void) fprintf(stderr,
			    "DEBUG: putting card into promiscuous "
			    "mode\n");
		if (ioctl(instance->bpffd, BIOCPROMISC, NULL) < 0)
			err(1, "BIOCPROMISC");
	}
	if (vflag)
		(void) fprintf(stderr,
		    "DEBUG: attaching to %s\n", iflag);

	if (ioctl(instance->bpffd, BIOCENAQMASK, NULL) < 0) {
		perror("enable qmask");
		return -1;
	}

	if (instance->rxqueue > -1) {
		if (ioctl(instance->bpffd, BIOCSTRXQMASK, &instance->rxqueue) < 0) {
			perror("rx qmask");
			return -1;
		}
	}

	if (instance->txqueue > -1) {
		if (ioctl(instance->bpffd, BIOCSTTXQMASK, &instance->txqueue) < 0) {
			perror("tx qmask");
			return -1;
		}
	}
	if (instance->other > -1) {
		if (ioctl(instance->bpffd, BIOCSTOTHERMASK, &instance->other) < 0) {
			perror("other qmask");
			return -1;
		}
	}

	instance->wrote = 0;


	bpf_wait_for_fullbuf(instance);
	return 0;
}
Exemplo n.º 27
0
int
_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
	       void *(*start_routine) (void *), void *arg)
{
	struct pthread *curthread, *new_thread;
	struct thr_param param;
	struct sched_param sched_param;
	struct rtprio rtp;
	sigset_t set, oset;
	cpuset_t *cpusetp;
	int i, cpusetsize, create_suspended, locked, old_stack_prot, ret;

	cpusetp = NULL;
	ret = cpusetsize = 0;
	_thr_check_init();

	/*
	 * Tell libc and others now they need lock to protect their data.
	 */
	if (_thr_isthreaded() == 0) {
		_malloc_first_thread();
		if (_thr_setthreaded(1))
			return (EAGAIN);
	}

	curthread = _get_curthread();
	if ((new_thread = _thr_alloc(curthread)) == NULL)
		return (EAGAIN);

	memset(&param, 0, sizeof(param));

	if (attr == NULL || *attr == NULL)
		/* Use the default thread attributes: */
		new_thread->attr = _pthread_attr_default;
	else {
		new_thread->attr = *(*attr);
		cpusetp = new_thread->attr.cpuset;
		cpusetsize = new_thread->attr.cpusetsize;
		new_thread->attr.cpuset = NULL;
		new_thread->attr.cpusetsize = 0;
	}
	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
		/* inherit scheduling contention scope */
		if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)
			new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
		else
			new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;

		new_thread->attr.prio = curthread->attr.prio;
		new_thread->attr.sched_policy = curthread->attr.sched_policy;
	}

	new_thread->tid = TID_TERMINATED;

	old_stack_prot = _rtld_get_stack_prot();
	if (create_stack(&new_thread->attr) != 0) {
		/* Insufficient memory to create a stack: */
		_thr_free(curthread, new_thread);
		return (EAGAIN);
	}
	/*
	 * Write a magic value to the thread structure
	 * to help identify valid ones:
	 */
	new_thread->magic = THR_MAGIC;
	new_thread->start_routine = start_routine;
	new_thread->arg = arg;
	new_thread->cancel_enable = 1;
	new_thread->cancel_async = 0;
	/* Initialize the mutex queue: */
	for (i = 0; i < TMQ_NITEMS; i++)
		TAILQ_INIT(&new_thread->mq[i]);

	/* Initialise hooks in the thread structure: */
	if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) {
		new_thread->flags = THR_FLAGS_NEED_SUSPEND;
		create_suspended = 1;
	} else {
		create_suspended = 0;
	}

	new_thread->state = PS_RUNNING;

	if (new_thread->attr.flags & PTHREAD_CREATE_DETACHED)
		new_thread->flags |= THR_FLAGS_DETACHED;

	/* Add the new thread. */
	new_thread->refcount = 1;
	_thr_link(curthread, new_thread);

	/*
	 * Handle the race between __pthread_map_stacks_exec and
	 * thread linkage.
	 */
	if (old_stack_prot != _rtld_get_stack_prot())
		_thr_stack_fix_protection(new_thread);

	/* Return thread pointer eariler so that new thread can use it. */
	(*thread) = new_thread;
	if (SHOULD_REPORT_EVENT(curthread, TD_CREATE) || cpusetp != NULL) {
		THR_THREAD_LOCK(curthread, new_thread);
		locked = 1;
	} else
		locked = 0;
	param.start_func = (void (*)(void *)) thread_start;
	param.arg = new_thread;
	param.stack_base = new_thread->attr.stackaddr_attr;
	param.stack_size = new_thread->attr.stacksize_attr;
	param.tls_base = (char *)new_thread->tcb;
	param.tls_size = sizeof(struct tcb);
	param.child_tid = &new_thread->tid;
	param.parent_tid = &new_thread->tid;
	param.flags = 0;
	if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM)
		param.flags |= THR_SYSTEM_SCOPE;
	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED)
		param.rtp = NULL;
	else {
		sched_param.sched_priority = new_thread->attr.prio;
		_schedparam_to_rtp(new_thread->attr.sched_policy,
			&sched_param, &rtp);
		param.rtp = &rtp;
	}

	/* Schedule the new thread. */
	if (create_suspended) {
		SIGFILLSET(set);
		SIGDELSET(set, SIGTRAP);
		__sys_sigprocmask(SIG_SETMASK, &set, &oset);
		new_thread->sigmask = oset;
		SIGDELSET(new_thread->sigmask, SIGCANCEL);
	}

	ret = thr_new(&param, sizeof(param));

	if (ret != 0) {
		ret = errno;
		/*
		 * Translate EPROCLIM into well-known POSIX code EAGAIN.
		 */
		if (ret == EPROCLIM)
			ret = EAGAIN;
	}

	if (create_suspended)
		__sys_sigprocmask(SIG_SETMASK, &oset, NULL);

	if (ret != 0) {
		if (!locked)
			THR_THREAD_LOCK(curthread, new_thread);
		new_thread->state = PS_DEAD;
		new_thread->tid = TID_TERMINATED;
		new_thread->flags |= THR_FLAGS_DETACHED;
		new_thread->refcount--;
		if (new_thread->flags & THR_FLAGS_NEED_SUSPEND) {
			new_thread->cycle++;
			_thr_umtx_wake(&new_thread->cycle, INT_MAX, 0);
		}
		_thr_try_gc(curthread, new_thread); /* thread lock released */
		atomic_add_int(&_thread_active_threads, -1);
	} else if (locked) {
		if (cpusetp != NULL) {
			if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID,
				TID(new_thread), cpusetsize, cpusetp)) {
				ret = errno;
				/* kill the new thread */
				new_thread->force_exit = 1;
				new_thread->flags |= THR_FLAGS_DETACHED;
				_thr_try_gc(curthread, new_thread);
				 /* thread lock released */
				goto out;
			}
		}

		_thr_report_creation(curthread, new_thread);
		THR_THREAD_UNLOCK(curthread, new_thread);
	}
out:
	if (ret)
		(*thread) = 0;
	return (ret);
}
Exemplo n.º 28
0
void test_netmap(usn_mbuf_t *m)
{
   int tosend = 0;
   int n, i;
   int rate_limit = 0;
   int sent = 0;
   struct pollfd pfd = { .fd = g_nmd->fd, .events = POLLOUT };
   struct netmap_if *nifp = g_nmd->nifp;
   struct timeval stime, etime;
   struct nm_desc nmd = *g_nmd;
   struct nm_desc *t_nmd;
   uint64_t nmd_flags = 0;

   // re-open netmap device.
   nmd.req.nr_flags = NR_REG_ONE_NIC;
   nmd.req.nr_ringid = 0;  
   printf("interface name:%s,len=%d\n",g_interface, m->mlen);
   t_nmd = nm_open(g_interface, NULL, nmd_flags 
                   | NM_OPEN_IFNAME | NM_OPEN_NO_MMAP, &nmd);

   if (t_nmd == NULL) {
      printf("Unable to open %s: %s", g_interface, strerror(errno));
      return;
   }
   nifp =t_nmd->nifp;
   pfd.fd =t_nmd->fd;
   pfd.events = POLLOUT;

   n = 10000;
   sent = 0;
   g_config.burst = 512;
   printf("g_config.burst=%d\n", g_config.burst);
   gettimeofday(&stime, 0);
   while ( sent < n ) {
      /*
       * wait for available room in the send queue(s)
       */
      if (poll(&pfd, 1, 1000) <= 0) {
         D("poll error/timeout on queue: %s", strerror(errno));
         // goto quit;
      }
      if (pfd.revents & POLLERR) {
         D("poll error");
         goto quit;
      }
      for (i = g_nmd->first_tx_ring; i <= g_nmd->last_tx_ring; i++) {
         int limit = rate_limit ?  tosend : g_config.burst;
         int cnt = 0;
         if (n > 0 && n - sent < limit)
            limit = n - sent;
         struct netmap_ring *txring = NETMAP_TXRING(nifp, i);
         if (nm_ring_empty(txring))
            continue;

         cnt = test_send(txring, m, limit);
         DEBUG("limit %d tail %d  cnt %d",
            limit, txring->tail, cnt);
         sent += cnt;
      }
   }
   // print info stats
   gettimeofday(&etime, 0);
   timersub(&etime,&stime,&etime);
   printf("num of sent pkts: %d\n", n);
   printf("total time: %lu (seconds) %lu (microseconds) \n", 
              etime.tv_sec, etime.tv_usec);

   /* flush any remaining packets */
   ioctl(pfd.fd, NIOCTXSYNC, NULL);

   /* final part: wait all the TX queues to be empty. */
   for (i = g_nmd->first_tx_ring; i <= g_nmd->last_tx_ring; i++) {
      struct netmap_ring *txring = NETMAP_TXRING(nifp, i);
      while (nm_tx_pending(txring)) {
         ioctl(pfd.fd, NIOCTXSYNC, NULL);
         usleep(1); /* wait 1 tick */
      }
   }

quit:
  return;
}

/* set the thread affinity. */
int
setaffinity( int i)
{
   cpuset_t cpumask;

   if (i == -1)
      return 0;

   /* Set thread affinity affinity.*/
   CPU_ZERO(&cpumask);
   CPU_SET(i, &cpumask);

   if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_CPUSET, 
          -1, sizeof(cpuset_t), &cpumask) != 0) { 
      DEBUG("Unable to set affinity: %s", strerror(errno));
      return 1;
   }
   return 0;
}