Пример #1
0
unsigned int
ldap_pvt_thread_sleep(
	unsigned int interval
)
{
	thread_t		mylwp;
	tl_t		*t, *nt;
	time_t		now;


	if ( lwp_self( &mylwp ) < 0 ) {
		return -1;
	}

	time( &now );

	mon_enter( &sglob->tsl_mon );

	if ( sglob->tsl_list != NULL ) {
		for ( t = sglob->tsl_list; t != NULL; t = t->tl_next ) {
			if ( SAMETHREAD( t->tl_tid, mylwp )) {
				/* We're already sleeping? */
				t->tl_wake = now + interval;
				mon_exit( &sglob->tsl_mon );
				lwp_suspend( mylwp );
				return 0;
			}
		}
	}

	nt = (tl_t *) LDAP_MALLOC( sizeof( tl_t ));

	if( nt == NULL ) return -1;

	nt->tl_next = sglob->tsl_list;
	nt->tl_wake = now + interval;
	nt->tl_tid = mylwp;
	sglob->tsl_list = nt;

	mon_exit( &sglob->tsl_mon );

	lwp_suspend( mylwp );
	return 0;
}
Пример #2
0
int
sys__lwp_suspend(struct lwp *l, const struct sys__lwp_suspend_args *uap,
    register_t *retval)
{
	/* {
		syscallarg(lwpid_t) target;
	} */
	struct proc *p = l->l_proc;
	struct lwp *t;
	int error;

	mutex_enter(p->p_lock);
	if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
		mutex_exit(p->p_lock);
		return ESRCH;
	}

	/*
	 * Check for deadlock, which is only possible when we're suspending
	 * ourself.  XXX There is a short race here, as p_nrlwps is only
	 * incremented when an LWP suspends itself on the kernel/user
	 * boundary.  It's still possible to kill -9 the process so we
	 * don't bother checking further.
	 */
	lwp_lock(t);
	if ((t == l && p->p_nrlwps == 1) ||
	    (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0) {
		lwp_unlock(t);
		mutex_exit(p->p_lock);
		return EDEADLK;
	}

	/*
	 * Suspend the LWP.  XXX If it's on a different CPU, we should wait
	 * for it to be preempted, where it will put itself to sleep. 
	 *
	 * Suspension of the current LWP will happen on return to userspace.
	 */
	error = lwp_suspend(l, t);
	if (error) {
		mutex_exit(p->p_lock);
		return error;
	}

	/*
	 * Wait for:
	 *  o process exiting
	 *  o target LWP suspended
	 *  o target LWP not suspended and L_WSUSPEND clear
	 *  o target LWP exited
	 */
	for (;;) {
		error = cv_wait_sig(&p->p_lwpcv, p->p_lock);
		if (error) {
			error = ERESTART;
			break;
		}
		if (lwp_find(p, SCARG(uap, target)) == NULL) {
			error = ESRCH;
			break;
		}
		if ((l->l_flag | t->l_flag) & (LW_WCORE | LW_WEXIT)) {
			error = ERESTART;
			break;
		}
		if (t->l_stat == LSSUSPENDED ||
		    (t->l_flag & LW_WSUSPEND) == 0)
			break;
	}
	mutex_exit(p->p_lock);

	return error;
}
Пример #3
0
int thr_suspend(int tid)
{
  return( lwp_suspend(thread_table[tid] ));
}