예제 #1
0
파일: threadflow.c 프로젝트: alhazred/onarm
/* ARGSUSED */
static void
threadflow_cancel(int arg1)
{
	threadflow_t *threadflow;

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_IMPL, "Thread signal handler on tid %d",
	    _lwp_self());
#endif

	threadflow = my_procflow->pf_threads;
	my_procflow->pf_running = 0;

	while (threadflow) {
		if (threadflow->tf_tid) {
			/* make sure thread has been cleaned up */
			flowop_destruct_all_flows(threadflow);

			(void) pthread_cancel(threadflow->tf_tid);
			filebench_log(LOG_DEBUG_IMPL, "Thread %d cancelled...",
			    threadflow->tf_tid);
		}
		threadflow = threadflow->tf_next;
	}

	exit(0);
}
예제 #2
0
static void
Abort(const char *msg)
{
	ulwp_t *self;
	struct sigaction act;
	sigset_t sigmask;
	lwpid_t lwpid;

	/* to help with core file debugging */
	panicstr = msg;
	if ((self = __curthread()) != NULL) {
		panic_thread = self;
		lwpid = self->ul_lwpid;
	} else {
		lwpid = _lwp_self();
	}

	/* set SIGABRT signal handler to SIG_DFL w/o grabbing any locks */
	(void) memset(&act, 0, sizeof (act));
	act.sa_sigaction = SIG_DFL;
	(void) __sigaction(SIGABRT, &act, NULL);

	/* delete SIGABRT from the signal mask */
	(void) sigemptyset(&sigmask);
	(void) sigaddset(&sigmask, SIGABRT);
	(void) __lwp_sigmask(SIG_UNBLOCK, &sigmask);

	(void) _lwp_kill(lwpid, SIGABRT);	/* never returns */
	(void) kill(getpid(), SIGABRT);	/* if it does, try harder */
	_exit(127);
}
예제 #3
0
static void stop_other_threads() {
#if defined(__sun__)
  lwpid_t self;
  char path[PATH_MAX];
  DIR *root;
  struct dirent *de, *entry;
  int size = 0;

  self = _lwp_self();
  snprintf(path, sizeof(path), "/proc/%d/lwp", getpid());
#ifdef _PC_NAME_MAX
  size = pathconf(path, _PC_NAME_MAX);
#endif
  size = MAX(size, PATH_MAX + 128);
  de = alloca(size);
  root = opendir(path);
  if(!root) return;
  while(portable_readdir_r(root, de, &entry) == 0 && entry != NULL) {
    if(entry->d_name[0] >= '1' && entry->d_name[0] <= '9') {
      lwpid_t tgt;
      tgt = atoi(entry->d_name);
#ifdef UNSAFE_STOP
      if(tgt != self) _lwp_suspend(tgt);
#endif
    }
  }
  closedir(root);
#endif
}
예제 #4
0
파일: log.c 프로젝트: atrmat/libphenom
static void get_tname(ph_thread_t *me, char *buf, uint32_t size)
{
  uint64_t tid;

  if (me) {
    ph_snprintf(buf, size, "%s/%d", me->name, me->tid);
    return;
  }

#if defined(__linux__)
  tid = syscall(SYS_gettid);
#elif defined(__MACH__)
  pthread_threadid_np(pthread_self(), &tid);
#elif defined(__sun__)
  tid = _lwp_self();
#else
  tid = (uint64_t)(intptr_t)self;
#endif

#if defined(__linux__) || defined(__MACH__)
  if (pthread_getname_np(pthread_self(), buf, size) == 0) {
    int len = strlen(buf);
    if (len > 0) {
      ph_snprintf(buf + len, size - len, "/%" PRIu64, tid);
      return;
    }
  }
#endif

  ph_snprintf(buf, size, "lwp/%" PRIu64, tid);
}
예제 #5
0
static void zend_jit_perf_jitdump_register(const char *name, void *start, size_t size)
{
	if (jitdump_fd >= 0) {
		static uint64_t id = 1;
		zend_perf_jitdump_load_record rec;
		size_t len = strlen(name);
		uint32_t thread_id;
#if defined(__linux__)
		thread_id = syscall(SYS_gettid);
#elif defined(__FreeBSD__)
		long tid;
		thr_self(&tid);
		thread_id = (uint32_t)tid;
#elif defined(__OpenBSD__)
		thread_id = getthrid();
#elif defined(__NetBSD__)
		thread_id = _lwp_self();
#endif

		memset(&rec, 0, sizeof(rec));
		rec.hdr.event      = ZEND_PERF_JITDUMP_RECORD_LOAD;
		rec.hdr.size       = sizeof(rec) + len + 1 + size;
		rec.hdr.time_stamp = zend_perf_timestamp();
		rec.process_id     = getpid();
		rec.thread_id      = thread_id;
		rec.vma            = (uint64_t)(uintptr_t)start;
		rec.code_address   = (uint64_t)(uintptr_t)start;
		rec.code_size      = (uint64_t)size;
		rec.code_id        = id++;

		zend_quiet_write(jitdump_fd, &rec, sizeof(rec));
		zend_quiet_write(jitdump_fd, name, len + 1);
		zend_quiet_write(jitdump_fd, start, size);
	}
}
예제 #6
0
/*
 * Puts current high resolution time in start time entry
 * for threadflow and may also calculate running filebench
 * overhead statistics.
 */
void
flowop_beginop(threadflow_t *threadflow, flowop_t *flowop)
{
#ifdef HAVE_PROCFS
	if ((filebench_shm->shm_mmode & FILEBENCH_MODE_NOUSAGE) == 0) {
		if ((noproc == 0) && (threadflow->tf_lwpusagefd == 0)) {
			char procname[128];

			(void) snprintf(procname, sizeof (procname),
			    "/proc/%d/lwp/%d/lwpusage", my_pid, _lwp_self());
			threadflow->tf_lwpusagefd = open(procname, O_RDONLY);
		}

		(void) pread(threadflow->tf_lwpusagefd,
		    &threadflow->tf_susage,
		    sizeof (struct prusage), 0);

		/* Compute overhead time in this thread around op */
		if (threadflow->tf_eusage.pr_stime.tv_nsec) {
			flowop->fo_stats.fs_mstate[FLOW_MSTATE_OHEAD] +=
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_utime,
			    threadflow->tf_susage.pr_utime) +
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_ttime,
			    threadflow->tf_susage.pr_ttime) +
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_stime,
			    threadflow->tf_susage.pr_stime);
		}
	}
#endif

	/* Start of op for this thread */
	threadflow->tf_stime = gethrtime();
}
예제 #7
0
파일: preempt.cpp 프로젝트: CCJY/ACE
int
High_Priority_Task::svc (void)
{
  ACE_hthread_t thr_handle;
  ACE_Thread::self (thr_handle);
  int prio;

  if (ACE_Thread::getprio (thr_handle, prio) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getprio failed"), -1);

#if defined (ACE_HAS_STHREADS)
  ACE_DEBUG ((LM_DEBUG, "(%P|%u|%t) High: prio = %d, priority_ = %d\n",
              _lwp_self (), prio, this->priority_));
#else  /* ! ACE_HAS_STHREADS */
  ACE_DEBUG ((LM_DEBUG, "(%P|%t) High: prio = %d, priority_ = %d\n",
              prio, this->priority_));
#endif /* ! ACE_HAS_STHREADS */
  ACE_ASSERT (this->priority_ == prio);

  ACE_Time_Value pause (0, read_period);

  for (u_int i = 0; i < high_iterations; ++i)
    {
      time_ [i] = (u_long) ((ACE_OS::gethrtime () - starttime)/
                            (ACE_UINT32) 1000000u);
      ACE_OS::select (0, 0, 0, 0, &pause);
    }

  done_ = 1;

  return 0;
}
예제 #8
0
/*ARGSUSED*/
long
brand_unimpl(sysret_t *rv, uintptr_t p1)
{
    sysret_t rval;

    /*
     * We'd like to print out some kind of error message here like
     * "unsupported syscall", but we can't because it's not safe to
     * assume that stderr or STDERR_FILENO actually points to something
     * that is a terminal, and if we wrote to those files we could
     * inadvertantly write to some applications open files, which would
     * be bad.
     *
     * Normally, if an application calls an invalid system call
     * it get a SIGSYS sent to it.  So we'll just go ahead and send
     * ourselves a signal here.  Note that this is far from ideal since
     * if the application has registered a signal handler, that signal
     * handler may recieve a ucontext_t as the third parameter to
     * indicate the context of the process when the signal was
     * generated, and in this case that context will not be what the
     * application is expecting.  Hence, we should probably create a
     * brandsys() kernel function that can deliver the signal to us
     * with the correct ucontext_t.
     */
    (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGSYS);
    return (ENOSYS);
}
예제 #9
0
void
__assfail(const char *assertion, const char *filename, int line_num)
{
	char buf[800];	/* no assert() message in the library is this long */
	ulwp_t *self;
	lwpid_t lwpid;

	/* avoid recursion deadlock */
	if ((self = __curthread()) != NULL) {
		if (assert_thread == self)
			_exit(127);
		enter_critical(self);
		(void) _lwp_mutex_lock(&assert_lock);
		assert_thread = self;
		lwpid = self->ul_lwpid;
	} else {
		self = NULL;
		(void) _lwp_mutex_lock(&assert_lock);
		lwpid = _lwp_self();
	}

	/*
	 * This is a hack, but since the Abort function isn't exported
	 * to outside consumers, libzpool's vpanic() function calls
	 * assfail() with a filename set to NULL. In that case, it'd be
	 * best not to print "assertion failed" since it was a panic and
	 * not an assertion failure.
	 */
	if (filename == NULL) {
		(void) strcpy(buf, "failure for thread ");
	} else {
		(void) strcpy(buf, "assertion failed for thread ");
	}

	ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf));
	(void) strcat(buf, ", thread-id ");
	ultos((uint64_t)lwpid, 10, buf + strlen(buf));
	(void) strcat(buf, ": ");
	(void) strcat(buf, assertion);

	if (filename != NULL) {
		(void) strcat(buf, ", file ");
		(void) strcat(buf, filename);
		(void) strcat(buf, ", line ");
		ultos((uint64_t)line_num, 10, buf + strlen(buf));
	}

	(void) strcat(buf, "\n");
	(void) __write(2, buf, strlen(buf));
	/*
	 * We could replace the call to Abort() with the following code
	 * if we want just to issue a warning message and not die.
	 *	assert_thread = NULL;
	 *	_lwp_mutex_unlock(&assert_lock);
	 *	if (self != NULL)
	 *		exit_critical(self);
	 */
	Abort(buf);
}
예제 #10
0
파일: flowop.c 프로젝트: blusjune/.bsrc
/*
 * Puts current high resolution time in start time entry
 * for threadflow and may also calculate running filebench
 * overhead statistics.
 */
void
flowop_beginop(threadflow_t *threadflow, flowop_t *flowop)
{
#ifdef HAVE_PROC_PID_LWP
	if ((filebench_shm->shm_mmode & FILEBENCH_MODE_NOUSAGE) == 0) {
		if (threadflow->tf_lwpusagefd == 0) {
			char procname[128];

			(void) snprintf(procname, sizeof (procname),
			    "/proc/%d/lwp/%d/lwpusage", (int)my_pid, _lwp_self());
			threadflow->tf_lwpusagefd = open(procname, O_RDONLY);
		}

		(void) pread(threadflow->tf_lwpusagefd,
		    &threadflow->tf_susage,
		    sizeof (struct prusage), 0);

		/* Compute overhead time in this thread around op */
		if (threadflow->tf_eusage.pr_stime.tv_nsec) {
			flowop->fo_stats.fs_mstate[FLOW_MSTATE_OHEAD] +=
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_utime,
			    threadflow->tf_susage.pr_utime) +
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_ttime,
			    threadflow->tf_susage.pr_ttime) +
			    TIMESPEC_TO_HRTIME(threadflow->tf_eusage.pr_stime,
			    threadflow->tf_susage.pr_stime);
		}
	}
#elif defined(HAVE_PROC_PID_STAT)
	int tid;
	char fname[128], dummy_str[64];
	unsigned long utime, stime;
	FILE *filep;
	int ret;
	
	tid = gettid();
	filebench_log(LOG_DEBUG_SCRIPT, "proc/pid/stat called ==> tid = %d", tid);
	sprintf(fname,"/proc/%d/stat", tid);
	filep = fopen(fname, "r");
	if (filep) {
			ret = fscanf(filep, "%s %s %s %s %s %s %s %s %s %s %s %s %s %lu %lu", \
			dummy_str, dummy_str, dummy_str,  dummy_str,
			dummy_str, dummy_str, dummy_str, dummy_str,
			dummy_str, dummy_str, dummy_str, dummy_str,
			dummy_str, &utime, &stime);
		flowop->fo_start_usage = (utime + stime) * 10000000;
		fclose(filep);
	
	} else {
		filebench_log(LOG_ERROR, "Unable to open proc/<pid>/stat file for given thread (errno=%d)", errno);
	}
#endif

	/* Start of op for this thread */
	threadflow->tf_stime = gethrtime();
}
예제 #11
0
/*ARGSUSED*/
void
_brand_abort(int err, const char *msg, const char *file, int line)
{
    sysret_t rval;

    /* Save the error message into convenient globals */
    brand_abort_err = err;
    brand_abort_msg = msg;
    brand_abort_file = file;
    brand_abort_line = line;

    /* kill ourselves */
    abort();

    /* If abort() didn't work, try something stronger. */
    (void) __systemcall(&rval, SYS_lwp_kill + 1024, _lwp_self(), SIGKILL);
}
예제 #12
0
파일: thread.c 프로젝트: atrmat/libphenom
static ph_thread_t *ph_thread_init_myself(bool booting)
{
  ph_thread_t *me;
  ck_epoch_record_t *er;

  er = ck_epoch_recycle(&misc_epoch);
  if (er) {
    me = ph_container_of(er, ph_thread_t, epoch_record);
  } else {
    me = calloc(1, sizeof(*me));
    if (!me) {
      ph_panic("fatal OOM in ph_thread_init_myself()");
    }
    ck_epoch_register(&misc_epoch, &me->epoch_record);
    ck_stack_push_mpmc(&ph_thread_all_threads, &me->thread_linkage);
    ph_counter_init_thread(me);
  }
#ifdef HAVE___THREAD
  __ph_thread_self = me;
#endif
  pthread_setspecific(__ph_thread_key, me);

  PH_STAILQ_INIT(&me->pending_nbio);
  PH_STAILQ_INIT(&me->pending_pool);

  me->tid = ck_pr_faa_32(&next_tid, 1);
  me->thr = pthread_self();
#ifdef __sun__
  me->lwpid = _lwp_self();
#endif

#if defined(__linux__) || defined(__MACH__)
  // see if we can discover our thread name from the system
  pthread_getname_np(me->thr, me->name, sizeof(me->name));
#endif

  // If we were recycled from a non-phenom thread, and are initializing
  // a non-phenom thread, it is possible that there are still deferred
  // items to reap in this record, so get them now.
  if (er && !booting) {
    ck_epoch_barrier(&misc_epoch, &me->epoch_record);
  }

  return me;
}
예제 #13
0
/*
 * Report a thread usage error.
 * Not called if _THREAD_ERROR_DETECTION=0.
 * Writes message and continues execution if _THREAD_ERROR_DETECTION=1.
 * Writes message and dumps core if _THREAD_ERROR_DETECTION=2.
 */
void
thread_error(const char *msg)
{
	char buf[800];
	uberdata_t *udp;
	ulwp_t *self;
	lwpid_t lwpid;

	/* avoid recursion deadlock */
	if ((self = __curthread()) != NULL) {
		if (assert_thread == self)
			_exit(127);
		enter_critical(self);
		(void) _lwp_mutex_lock(&assert_lock);
		assert_thread = self;
		lwpid = self->ul_lwpid;
		udp = self->ul_uberdata;
	} else {
		self = NULL;
		(void) _lwp_mutex_lock(&assert_lock);
		lwpid = _lwp_self();
		udp = &__uberdata;
	}

	(void) strcpy(buf, "\n*** _THREAD_ERROR_DETECTION: "
	    "thread usage error detected ***\n*** ");
	(void) strcat(buf, msg);

	(void) strcat(buf, "\n*** calling thread is ");
	ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf));
	(void) strcat(buf, " thread-id ");
	ultos((uint64_t)lwpid, 10, buf + strlen(buf));
	(void) strcat(buf, "\n\n");
	(void) __write(2, buf, strlen(buf));
	if (udp->uberflags.uf_thread_error_detection >= 2)
		Abort(buf);
	assert_thread = NULL;
	(void) _lwp_mutex_unlock(&assert_lock);
	if (self != NULL)
		exit_critical(self);
}
예제 #14
0
uint64_t dylan_current_thread_id(void)
{
#if defined(OPEN_DYLAN_PLATFORM_LINUX)
  return syscall(SYS_gettid);
#elif defined(OPEN_DYLAN_PLATFORM_DARWIN)
  uint64_t tid;
  pthread_threadid_np(pthread_self(), &tid);
  return tid;
#elif defined(OPEN_DYLAN_PLATFORM_FREEBSD)
  return pthread_getthreadid_np();
#elif defined(OPEN_DYLAN_PLATFORM_NETBSD)
  return _lwp_self();
#elif defined(OPEN_DYLAN_PLATFORM_OPENBSD)
  return syscall(SYS_getthrid);
#elif defined(OPEN_DYLAN_PLATFORM_WINDOWS)
  return GetCurrentThreadId();
#else
  #error dylan_current_thread_id is not yet implemented.
#endif
  return 0;
}
예제 #15
0
/* ARGSUSED */
static void
threadflow_cancel(int arg1)
{
	threadflow_t *threadflow = my_procflow->pf_threads;

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_IMPL, "Thread signal handler on tid %d",
	    _lwp_self());
#endif

	my_procflow->pf_running = 0;
	exit(0);

	while (threadflow) {
		if (threadflow->tf_tid) {
			(void) pthread_cancel(threadflow->tf_tid);
			filebench_log(LOG_DEBUG_IMPL, "Thread %d cancelled...",
			    threadflow->tf_tid);
		}
		threadflow = threadflow->tf_next;
	}
}
예제 #16
0
파일: preempt.cpp 프로젝트: CCJY/ACE
int
Low_Priority_Task::svc (void)
{
  ACE_hthread_t thr_handle;
  ACE_Thread::self (thr_handle);
  int prio;

  if (ACE_Thread::getprio (thr_handle, prio) == -1)
    ACE_ERROR_RETURN ((LM_ERROR, "%p\n", "getprio failed"), -1);

#if defined (ACE_HAS_STHREADS)
  ACE_DEBUG ((LM_DEBUG, "(%P|%u|%t) Low: prio = %d, priority_ = %d\n",
              _lwp_self (), prio, this->priority_));
#else  /* ! ACE_HAS_STHREADS */
  ACE_DEBUG ((LM_DEBUG, "(%P|%t) Low: prio = %d, priority_ = %d\n",
              prio, this->priority_));
#endif /* ! ACE_HAS_STHREADS */
  ACE_ASSERT (this->priority_ == prio);

  u_long iterations = 0;

  // Chew up CPU for the entire interval.
  for (;
       ! high_priority_task_.done () && iterations < low_iterations;
       ++iterations)
    {
      u_long n = 1279ul;  /* Takes about 40.2 usecs on a 168 MHz Ultra2. */
      ACE::is_prime (n,
                     2ul /* min_factor */,
                     n/2 /* max_factor */);

      if (low_yield)
        ACE_OS::thr_yield ();
    }

  ACE_DEBUG ((LM_INFO, "Low completed %u iterations\n", iterations));

  return 0;
}
예제 #17
0
/***********************************************************************
 *           get_unix_tid
 *
 * Retrieve the Unix tid to use on the server side for the current thread.
 */
static int get_unix_tid(void)
{
    int ret = -1;
#ifdef HAVE_PTHREAD_GETTHREADID_NP
    ret = pthread_getthreadid_np();
#elif defined(linux)
    ret = syscall( __NR_gettid );
#elif defined(__sun)
    ret = pthread_self();
#elif defined(__APPLE__)
    ret = mach_thread_self();
    mach_port_deallocate(mach_task_self(), ret);
#elif defined(__NetBSD__)
    ret = _lwp_self();
#elif defined(__FreeBSD__)
    long lwpid;
    thr_self( &lwpid );
    ret = lwpid;
#elif defined(__DragonFly__)
    ret = lwp_gettid();
#endif
    return ret;
}
예제 #18
0
파일: mttest.c 프로젝트: dhaley/dcp
/* do_work: process array's data with locking, based on array->strategy */
void *
do_work(void *v)
{
	Workblk	*array;
	struct scripttab	*k;
	int i;
	volatile double x;

#ifdef SOLARIS
	thread_t	mytid = thr_self();
#endif
#ifdef POSIX
	pthread_t	mytid = pthread_self();
#endif
#if OS(Solaris)
	/* check for signal masked */
	check_sigmask(0);
#endif /* OS(Solaris) */

	/* delay to ensure that a tick passes, so that the
	 * first profile packet doesn't show the thread startup time
	 * attributed to the accounting functions
	 */
	x = 0;
	for (i = 0; i < 2000000; i++) { x = x + 1.0; }

	for(;;) {
		/* fetch a workblk */
		array = fetch_work();
		if(array == NULL) {
			/* we're done */
			break;
		}
                array->lock = mutex_initializer;
		array->proffail = 0;
		array->tid = mytid;
#if OS(Solaris)		
		array->ilwpid = _lwp_self();
#else
		array->ilwpid = getpid() /* pthread_self()*/ ;
#endif /* OS(Solaris) */

                array->lwpid = -1; /* initialise to inappropriate value */
#if 0
		printf("thread %d, initial lwp %d, block #%d, strategy = %d\n",
		    array->tid, array->ilwpid, array->index, array->strategy);
#endif
		array->start = gethrtime();
		array->vstart = gethrvtime();

		k = &scripttab[array->strategy];
		(k->test_func)(array, k);

		array->done = gethrtime();
		array->vdone = gethrvtime();
#if OS(Solaris)
		array->lwpid = _lwp_self();
#else
		array->lwpid = getpid() /* pthread_self()*/ ;
#endif /* OS(Solaris) */
				

#if defined(BOUND)
                assert(array->lwpid == array->ilwpid);
#endif
#if OS(Solaris)
		if(check_sigmask(1) != 0) {
			/* set flag in the array */
			array->proffail = 1;
		}
#endif /* OS(Solaris) */
	}

	return NULL;
}
예제 #19
0
파일: flowop.c 프로젝트: blusjune/.bsrc
/*
 * The final initialization and main execution loop for the
 * worker threads. Sets threadflow and flowop start times,
 * waits for all process to start, then creates the runtime
 * flowops from those defined by the F language workload
 * script. It does some more initialization, then enters a
 * loop to repeatedly execute the flowops on the flowop list
 * until an abort condition is detected, at which time it exits.
 * This is the starting routine for the new worker thread
 * created by threadflow_createthread(), and is not currently
 * called from anywhere else.
 */
void
flowop_start(threadflow_t *threadflow)
{
	flowop_t *flowop;
	size_t memsize;
	int ret = FILEBENCH_OK;

	set_thread_ioprio(threadflow);

#ifdef HAVE_PROC_PID_LWP
	char procname[128];
	long ctl[2] = {PCSET, PR_MSACCT};
	int pfd;

	(void) snprintf(procname, sizeof (procname),
	    "/proc/%d/lwp/%d/lwpctl", (int)my_pid, _lwp_self());
	pfd = open(procname, O_WRONLY);
	(void) pwrite(pfd, &ctl, sizeof (ctl), 0);
	(void) close(pfd);
#endif

	(void) ipc_mutex_lock(&controlstats_lock);
	if (!controlstats_zeroed) {
		(void) memset(&controlstats, 0, sizeof (controlstats));
		controlstats_zeroed = 1;
	}
	(void) ipc_mutex_unlock(&controlstats_lock);

	flowop = threadflow->tf_thrd_fops;

	/* Hold the flowop find lock as reader to prevent lookups */
	(void) pthread_rwlock_rdlock(&filebench_shm->shm_flowop_find_lock);

	/* Create the runtime flowops from those defined by the script */
	(void) ipc_mutex_lock(&filebench_shm->shm_flowop_lock);
	if (flowop_create_runtime_flowops(threadflow, &threadflow->tf_thrd_fops)
	    != FILEBENCH_OK) {
		(void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);
		filebench_shutdown(1);
		return;
	}
	(void) ipc_mutex_unlock(&filebench_shm->shm_flowop_lock);

	/* Release the find lock as reader to allow lookups */
	(void) pthread_rwlock_unlock(&filebench_shm->shm_flowop_find_lock);

	/* Set to the start of the new flowop list */
	flowop = threadflow->tf_thrd_fops;

	memsize = (size_t)threadflow->tf_constmemsize;

	/* If we are going to use ISM, allocate later */
	if (threadflow->tf_attrs & THREADFLOW_USEISM) {
		threadflow->tf_mem =
		    ipc_ismmalloc(memsize);
	} else {
		threadflow->tf_mem =
		    malloc(memsize);
	}

	(void) memset(threadflow->tf_mem, 0, memsize);
	filebench_log(LOG_DEBUG_SCRIPT, "Thread allocated %d bytes", memsize);

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_SCRIPT, "Thread %zx (%d) started",
	    threadflow,
	    _lwp_self());
#endif

	/* 
	 * Now we set tf_running flag to indicate to the main process
	 * that the worker thread is running. However, the thread is
	 * still not executing the workload, as it is blocked by the
	 * shm_run_lock. Main thread will release this lock when all
	 * threads set their tf_running flag to 1.
	 */ 
	threadflow->tf_abort = 0;
	threadflow->tf_running = 1;

	/*
	 * Block until all processes have started, acting like
	 * a barrier. The original filebench process initially
	 * holds the run_lock as a reader, preventing any of the
	 * threads from obtaining the writer lock, and hence
	 * passing this point. Once all processes and threads
	 * have been created, the original process unlocks
	 * run_lock, allowing each waiting thread to lock
	 * and then immediately unlock it, then begin running.
	 */
	(void) pthread_rwlock_wrlock(&filebench_shm->shm_run_lock);
	(void) pthread_rwlock_unlock(&filebench_shm->shm_run_lock);

	/* Main filebench worker loop */
	while (ret == FILEBENCH_OK) {
		int i, count;

		/* Abort if asked */
		if (threadflow->tf_abort || filebench_shm->shm_f_abort)
			break;

		/* Be quiet while stats are gathered */
		if (filebench_shm->shm_bequiet) {
			(void) sleep(1);
			continue;
		}

		/* Take it easy until everyone is ready to go */
		if (!filebench_shm->shm_procs_running) {
			(void) sleep(1);
			continue;
		}

		if (flowop == NULL) {
			filebench_log(LOG_ERROR, "flowop_read null flowop");
			return;
		}

		/* Execute the flowop for fo_iters times */
		count = (int)avd_get_int(flowop->fo_iters);
		for (i = 0; i < count; i++) {

			filebench_log(LOG_DEBUG_SCRIPT, "%s: executing flowop "
			    "%s-%d", threadflow->tf_name, flowop->fo_name,
			    flowop->fo_instance);

			ret = (*flowop->fo_func)(threadflow, flowop);

			/*
			 * Return value FILEBENCH_ERROR means "flowop
			 * failed, stop the filebench run"
			 */
			if (ret == FILEBENCH_ERROR) {
				filebench_log(LOG_ERROR,
				    "%s-%d: flowop %s-%d failed",
				    threadflow->tf_name,
				    threadflow->tf_instance,
				    flowop->fo_name,
				    flowop->fo_instance);
				(void) ipc_mutex_lock(&threadflow->tf_lock);
				threadflow->tf_abort = 1;
				filebench_shm->shm_f_abort =
				    FILEBENCH_ABORT_ERROR;
				(void) ipc_mutex_unlock(&threadflow->tf_lock);
				break;
			}

			/*
			 * Return value of FILEBENCH_NORSC means "stop
			 * the filebench run" if in "end on no work mode",
			 * otherwise it indicates an error
			 */
			if (ret == FILEBENCH_NORSC) {
				(void) ipc_mutex_lock(&threadflow->tf_lock);
				threadflow->tf_abort = FILEBENCH_DONE;
				if (filebench_shm->shm_rmode ==
				    FILEBENCH_MODE_Q1STDONE) {
					filebench_shm->shm_f_abort =
					    FILEBENCH_ABORT_RSRC;
				} else if (filebench_shm->shm_rmode !=
				    FILEBENCH_MODE_QALLDONE) {
					filebench_log(LOG_ERROR1,
					    "WARNING! Run stopped early:\n   "
					    "             flowop %s-%d could "
					    "not obtain a file. Please\n      "
					    "          reduce runtime, "
					    "increase fileset entries "
					    "($nfiles), or switch modes.",
					    flowop->fo_name,
					    flowop->fo_instance);
					filebench_shm->shm_f_abort =
					    FILEBENCH_ABORT_ERROR;
				}
				(void) ipc_mutex_unlock(&threadflow->tf_lock);
				break;
			}

			/*
			 * Return value of FILEBENCH_DONE means "stop
			 * the filebench run without error"
			 */
			if (ret == FILEBENCH_DONE) {
				(void) ipc_mutex_lock(&threadflow->tf_lock);
				threadflow->tf_abort = FILEBENCH_DONE;
				filebench_shm->shm_f_abort =
				    FILEBENCH_ABORT_DONE;
				(void) ipc_mutex_unlock(&threadflow->tf_lock);
				break;
			}

			/*
			 * If we get here and the return is something other
			 * than FILEBENCH_OK, it means a spurious code
			 * was returned, so treat as major error. This
			 * probably indicates a bug in the flowop.
			 */
			if (ret != FILEBENCH_OK) {
				filebench_log(LOG_ERROR,
				    "Flowop %s unexpected return value = %d\n",
				    flowop->fo_name, ret);
				filebench_shm->shm_f_abort =
				    FILEBENCH_ABORT_ERROR;
				break;
			}
		}

		/* advance to next flowop */
		flowop = flowop->fo_exec_next;

		/* but if at end of list, start over from the beginning */
		if (flowop == NULL) {
			flowop = threadflow->tf_thrd_fops;
			threadflow->tf_stats.fs_count++;
		}
	}

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_SCRIPT, "Thread %d exiting",
	    _lwp_self());
#endif

	/* Tell flowops to destroy locally acquired state */
	flowop_destruct_all_flows(threadflow);

	pthread_exit(&threadflow->tf_abort);
}
예제 #20
0
/*
 * The final initialization and main execution loop for the
 * worker threads. Sets threadflow and flowop start times,
 * waits for all process to start, then creates the runtime
 * flowops from those defined by the F language workload
 * script. It does some more initialization, then enters a
 * loop to repeatedly execute the flowops on the flowop list
 * until an abort condition is detected, at which time it exits.
 * This is the starting routine for the new worker thread
 * created by threadflow_createthread(), and is not currently
 * called from anywhere else.
 */
void
flowop_start(threadflow_t *threadflow)
{
	flowop_t *flowop;
	size_t memsize;
	int ret = 0;

	pid = getpid();

#ifdef HAVE_PROCFS
	if (noproc == 0) {
		char procname[128];
		long ctl[2] = {PCSET, PR_MSACCT};
		int pfd;

		(void) snprintf(procname, sizeof (procname),
		    "/proc/%d/lwp/%d/lwpctl", pid, _lwp_self());
		pfd = open(procname, O_WRONLY);
		(void) pwrite(pfd, &ctl, sizeof (ctl), 0);
		(void) close(pfd);
	}
#endif

	if (!controlstats_zeroed) {
		(void) memset(&controlstats, 0, sizeof (controlstats));
		controlstats_zeroed = 1;
	}

	flowop = threadflow->tf_ops;
	threadflow->tf_stats.fs_stime = gethrtime();
	flowop->fo_stats.fs_stime = gethrtime();

	/* Hold the flowop find lock as reader to prevent lookups */
	(void) pthread_rwlock_rdlock(&filebench_shm->flowop_find_lock);

	/*
	 * Block until all processes have started, acting like
	 * a barrier. The original filebench process initially
	 * holds the run_lock as a reader, preventing any of the
	 * threads from obtaining the writer lock, and hence
	 * passing this point. Once all processes and threads
	 * have been created, the original process unlocks
	 * run_lock, allowing each waiting thread to lock
	 * and then immediately unlock it, then begin running.
	 */
	(void) pthread_rwlock_wrlock(&filebench_shm->run_lock);
	(void) pthread_rwlock_unlock(&filebench_shm->run_lock);

	/* Create the runtime flowops from those defined by the script */
	(void) ipc_mutex_lock(&filebench_shm->flowop_lock);
	while (flowop) {
		flowop_t *newflowop;

		if (flowop == threadflow->tf_ops)
			threadflow->tf_ops = NULL;
		newflowop = flowop_define_common(threadflow, flowop->fo_name,
		    flowop, 1, 0);
		if (newflowop == NULL)
			return;
		if (flowop_initflow(newflowop) < 0) {
			filebench_log(LOG_ERROR, "Flowop init of %s failed",
			    newflowop->fo_name);
		}
		flowop = flowop->fo_threadnext;
	}
	(void) ipc_mutex_unlock(&filebench_shm->flowop_lock);

	filebench_log(LOG_DEBUG_SCRIPT, "Thread started");

	/* Release the find lock as reader to allow lookups */
	(void) pthread_rwlock_unlock(&filebench_shm->flowop_find_lock);

	/* Set to the start of the new flowop list */
	flowop = threadflow->tf_ops;

	threadflow->tf_abort = 0;
	threadflow->tf_running = 1;


	/* If we are going to use ISM, allocate later */
	if (threadflow->tf_attrs & THREADFLOW_USEISM) {
		threadflow->tf_mem =
		    ipc_ismmalloc((size_t)*threadflow->tf_memsize);
	} else {
		threadflow->tf_mem = malloc((size_t)*threadflow->tf_memsize);
	}

	if (threadflow->tf_mem == NULL) {
		filebench_log(LOG_ERROR,
			"Thread failed to allocate %zd bytes", 
			threadflow->tf_memsize);
		return;
	}

	memsize = *threadflow->tf_memsize;
	filebench_log(LOG_DEBUG_SCRIPT, "Thread allocated %lld bytes at %llx",
		memsize, threadflow->tf_mem);

	(void) memset(threadflow->tf_mem, 0, memsize);
	filebench_log(LOG_DEBUG_SCRIPT, "Thread zeroed %lld bytes", memsize);

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_SCRIPT, "Thread %zx (%d) started",
	    threadflow,
	    _lwp_self());
#else
	filebench_log(LOG_DEBUG_SCRIPT, "Thread %zx started", threadflow);
#endif

	/* Main filebench worker loop */
	/* CONSTCOND */
	while (1) {
		int i;

		/* Abort if asked */
		if (threadflow->tf_abort || filebench_shm->f_abort) {
			(void) ipc_mutex_lock(&threadflow->tf_lock);
			threadflow->tf_running = 0;
			(void) ipc_mutex_unlock(&threadflow->tf_lock);
			filebench_log(LOG_DEBUG_SCRIPT, 
				"%s: aborting thread %s on request of a flowop",
			    	threadflow->tf_name);
			break;
		}

		/* Be quiet while stats are gathered */
		if (filebench_shm->bequiet) {
			(void) sleep(1);
			continue;
		}

		/* Take it easy until everyone is ready to go */
		if (!filebench_shm->allrunning)
			(void) sleep(1);

		if (flowop->fo_stats.fs_stime == 0)
			flowop->fo_stats.fs_stime = gethrtime();

		if (flowop == NULL) {
			filebench_log(LOG_ERROR, "flowop_read null flowop");
			return;
		}

		if (threadflow->tf_memsize == 0) {
			filebench_log(LOG_ERROR,
			    "Zero memory size for thread %s",
			    threadflow->tf_name);
			return;
		}

		/* Execute the flowop for fo_iters times */
		for (i = 0; i < *flowop->fo_iters; i++) {
			filebench_log(LOG_DEBUG_SCRIPT, "%s: executing flowop "
			    "%s-%d", threadflow->tf_name, flowop->fo_name,
			    flowop->fo_instance);
			ret = (*flowop->fo_func)(threadflow, flowop);
			filebench_log(LOG_DEBUG_SCRIPT, "%s: finished flowop "
			    "%s-%d", threadflow->tf_name, flowop->fo_name,
			    flowop->fo_instance);

			/* Return value > 0 means "stop the filebench run" */
			if (ret > 0) {
				filebench_log(LOG_VERBOSE,
				    "%s: exiting flowop %s-%d",
				    threadflow->tf_name, flowop->fo_name,
				    flowop->fo_instance);
				(void) ipc_mutex_lock(&threadflow->tf_lock);
				threadflow->tf_abort = 1;
				filebench_shm->f_abort = 1;
				threadflow->tf_running = 0;
				(void) ipc_mutex_unlock(&threadflow->tf_lock);
				break;
			}
			/*
			 * Return value < 0 means "flowop failed, stop the
			 * filebench run"
			 */
			if (ret < 0) {
				filebench_log(LOG_ERROR, "flowop %s failed",
				    flowop->fo_name);
				(void) ipc_mutex_lock(&threadflow->tf_lock);
				threadflow->tf_abort = 1;
				filebench_shm->f_abort = 1;
				threadflow->tf_running = 0;
				(void) ipc_mutex_unlock(&threadflow->tf_lock);
				break;
			}
		}

		/* advance to next flowop */
		flowop = flowop->fo_threadnext;

		/* but if at end of list, start over from the beginning */
		if (flowop == NULL) {
			flowop = threadflow->tf_ops;
			threadflow->tf_stats.fs_count++;
		}
	}

#ifdef HAVE_LWPS
	filebench_log(LOG_DEBUG_SCRIPT, "Thread %d exiting",
	    _lwp_self());
#else
	filebench_log(LOG_DEBUG_SCRIPT, "Thread exiting");
#endif

	pthread_exit(&ret);
}
예제 #21
0
static void *my_server_thread(void *arg)
{
   server_lwpid = _lwp_self();
   door_return(NULL, 0, NULL, 0);
   return NULL;
}
예제 #22
0
파일: ctx.c 프로젝트: paulofaria/libdill
static int dill_ismain() {
    return _lwp_self() == 1;
}
예제 #23
0
/*
 * Report application lock usage error for mutexes and condvars.
 * Not called if _THREAD_ERROR_DETECTION=0.
 * Continue execution if _THREAD_ERROR_DETECTION=1.
 * Dump core if _THREAD_ERROR_DETECTION=2.
 */
void
lock_error(const mutex_t *mp, const char *who, void *cv, const char *msg)
{
	mutex_t mcopy;
	char buf[800];
	uberdata_t *udp;
	ulwp_t *self;
	lwpid_t lwpid;
	pid_t pid;

	/*
	 * Take a snapshot of the mutex before it changes (we hope!).
	 * Use memcpy() rather than 'mcopy = *mp' in case mp is unaligned.
	 */
	(void) memcpy(&mcopy, mp, sizeof (mcopy));

	/* avoid recursion deadlock */
	if ((self = __curthread()) != NULL) {
		if (assert_thread == self)
			_exit(127);
		enter_critical(self);
		(void) _lwp_mutex_lock(&assert_lock);
		assert_thread = self;
		lwpid = self->ul_lwpid;
		udp = self->ul_uberdata;
		pid = udp->pid;
	} else {
		self = NULL;
		(void) _lwp_mutex_lock(&assert_lock);
		lwpid = _lwp_self();
		udp = &__uberdata;
		pid = getpid();
	}

	(void) strcpy(buf,
	    "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
	(void) strcat(buf, who);
	(void) strcat(buf, "(");
	if (cv != NULL) {
		ultos((uint64_t)(uintptr_t)cv, 16, buf + strlen(buf));
		(void) strcat(buf, ", ");
	}
	ultos((uint64_t)(uintptr_t)mp, 16, buf + strlen(buf));
	(void) strcat(buf, ")");
	if (msg != NULL) {
		(void) strcat(buf, ": ");
		(void) strcat(buf, msg);
	} else if (!mutex_held(&mcopy)) {
		(void) strcat(buf, ": calling thread does not own the lock");
	} else if (mcopy.mutex_rcount) {
		(void) strcat(buf, ": mutex rcount = ");
		ultos((uint64_t)mcopy.mutex_rcount, 10, buf + strlen(buf));
	} else {
		(void) strcat(buf, ": calling thread already owns the lock");
	}
	(void) strcat(buf, "\ncalling thread is ");
	ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf));
	(void) strcat(buf, " thread-id ");
	ultos((uint64_t)lwpid, 10, buf + strlen(buf));
	if (msg != NULL || mutex_held(&mcopy))
		/* EMPTY */;
	else if (mcopy.mutex_lockw == 0)
		(void) strcat(buf, "\nthe lock is unowned");
	else if (!(mcopy.mutex_type & USYNC_PROCESS)) {
		(void) strcat(buf, "\nthe lock owner is ");
		ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf));
	} else {
		(void) strcat(buf, " in process ");
		ultos((uint64_t)pid, 10, buf + strlen(buf));
		(void) strcat(buf, "\nthe lock owner is ");
		ultos((uint64_t)mcopy.mutex_owner, 16, buf + strlen(buf));
		(void) strcat(buf, " in process ");
		ultos((uint64_t)mcopy.mutex_ownerpid, 10, buf + strlen(buf));
	}
	(void) strcat(buf, "\n\n");
	(void) __write(2, buf, strlen(buf));
	if (udp->uberflags.uf_thread_error_detection >= 2)
		Abort(buf);
	assert_thread = NULL;
	(void) _lwp_mutex_unlock(&assert_lock);
	if (self != NULL)
		exit_critical(self);
}
예제 #24
0
/*
 * Report application lock usage error for rwlocks.
 * Not called if _THREAD_ERROR_DETECTION=0.
 * Continue execution if _THREAD_ERROR_DETECTION=1.
 * Dump core if _THREAD_ERROR_DETECTION=2.
 */
void
rwlock_error(const rwlock_t *rp, const char *who, const char *msg)
{
	rwlock_t rcopy;
	uint32_t rwstate;
	char buf[800];
	uberdata_t *udp;
	ulwp_t *self;
	lwpid_t lwpid;
	pid_t pid;
	int process;

	/*
	 * Take a snapshot of the rwlock before it changes (we hope!).
	 * Use memcpy() rather than 'rcopy = *rp' in case rp is unaligned.
	 */
	(void) memcpy(&rcopy, rp, sizeof (rcopy));

	/* avoid recursion deadlock */
	if ((self = __curthread()) != NULL) {
		if (assert_thread == self)
			_exit(127);
		enter_critical(self);
		(void) _lwp_mutex_lock(&assert_lock);
		assert_thread = self;
		lwpid = self->ul_lwpid;
		udp = self->ul_uberdata;
		pid = udp->pid;
	} else {
		self = NULL;
		(void) _lwp_mutex_lock(&assert_lock);
		lwpid = _lwp_self();
		udp = &__uberdata;
		pid = getpid();
	}

	rwstate = (uint32_t)rcopy.rwlock_readers;
	process = (rcopy.rwlock_type & USYNC_PROCESS);

	(void) strcpy(buf,
	    "\n*** _THREAD_ERROR_DETECTION: lock usage error detected ***\n");
	(void) strcat(buf, who);
	(void) strcat(buf, "(");
	ultos((uint64_t)(uintptr_t)rp, 16, buf + strlen(buf));
	(void) strcat(buf, "): ");
	(void) strcat(buf, msg);
	(void) strcat(buf, "\ncalling thread is ");
	ultos((uint64_t)(uintptr_t)self, 16, buf + strlen(buf));
	(void) strcat(buf, " thread-id ");
	ultos((uint64_t)lwpid, 10, buf + strlen(buf));
	if (process) {
		(void) strcat(buf, " in process ");
		ultos((uint64_t)pid, 10, buf + strlen(buf));
	}
	if (rwstate & URW_WRITE_LOCKED) {
		(void) strcat(buf, "\nthe writer lock owner is ");
		ultos((uint64_t)rcopy.rwlock_owner, 16,
		    buf + strlen(buf));
		if (process) {
			(void) strcat(buf, " in process ");
			ultos((uint64_t)rcopy.rwlock_ownerpid, 10,
			    buf + strlen(buf));
		}
	} else if (rwstate & URW_READERS_MASK) {
		(void) strcat(buf, "\nthe reader lock is held by ");
		ultos((uint64_t)(rwstate & URW_READERS_MASK), 10,
		    buf + strlen(buf));
		(void) strcat(buf, " readers");
	} else {
		(void) strcat(buf, "\nthe lock is unowned");
	}
	if (rwstate & URW_HAS_WAITERS)
		(void) strcat(buf, "\nand the lock appears to have waiters");
	(void) strcat(buf, "\n\n");
	(void) __write(2, buf, strlen(buf));
	if (udp->uberflags.uf_thread_error_detection >= 2)
		Abort(buf);
	assert_thread = NULL;
	(void) _lwp_mutex_unlock(&assert_lock);
	if (self != NULL)
		exit_critical(self);
}