Index: kern/init_main.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_main.c,v
retrieving revision 1.442
diff -u -p -u -r1.442 init_main.c
--- kern/init_main.c	19 Feb 2012 21:06:47 -0000	1.442
+++ kern/init_main.c	23 May 2012 23:19:31 -0000
@@ -256,6 +256,7 @@ int	cold = 1;			/* still working on star
 struct timespec boottime;	        /* time at system startup - will only follow settime deltas */
 
 int	start_init_exec;		/* semaphore for start_init() */
+int	maxlwp;
 
 cprng_strong_t	*kern_cprng;
 
@@ -291,6 +292,12 @@ main(void)
 #endif
 	l->l_pflag |= LP_RUNNING;
 
+#ifdef __HAVE_CPU_MAXLWP
+	maxlwp = cpu_maxlwp();
+#else
+	maxlwp = 1024;
+#endif
+
 	/*
 	 * Attempt to find console and initialize
 	 * in case of early panic or other messages.
Index: kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 init_sysctl.c
--- kern/init_sysctl.c	7 Apr 2012 05:38:49 -0000	1.189
+++ kern/init_sysctl.c	23 May 2012 23:19:31 -0000
@@ -147,6 +147,7 @@ static int sysctl_kern_trigger_panic(SYS
 static int sysctl_kern_maxvnodes(SYSCTLFN_PROTO);
 static int sysctl_kern_rtc_offset(SYSCTLFN_PROTO);
 static int sysctl_kern_maxproc(SYSCTLFN_PROTO);
+static int sysctl_kern_maxlwp(SYSCTLFN_PROTO);
 static int sysctl_kern_hostid(SYSCTLFN_PROTO);
 static int sysctl_setlen(SYSCTLFN_PROTO);
 static int sysctl_kern_clockrate(SYSCTLFN_PROTO);
@@ -234,6 +235,12 @@ SYSCTL_SETUP(sysctl_kern_setup, "sysctl 
 		       CTL_KERN, KERN_MAXPROC, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+		       CTLTYPE_INT, "maxlwp",
+		       SYSCTL_DESCR("Maximum number of simultaneous threads"),
+		       sysctl_kern_maxlwp, 0, NULL, 0,
+		       CTL_KERN, KERN_MAXLWP, CTL_EOL);
+	sysctl_createv(clog, 0, NULL, NULL,
+		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
 		       CTLTYPE_INT, "maxfiles",
 		       SYSCTL_DESCR("Maximum number of open files"),
 		       NULL, 0, &maxfiles, 0,
@@ -1050,6 +1057,33 @@ sysctl_kern_maxproc(SYSCTLFN_ARGS)
 }
 
 /*
+ * sysctl helper routine for kern.maxlwp. Ensures that the new
+ * values are not too low or too high.
+ */
+static int
+sysctl_kern_maxlwp(SYSCTLFN_ARGS)
+{
+	int error, nmaxlwp;
+	struct sysctlnode node;
+
+	nmaxlwp = maxlwp;
+	node = *rnode;
+	node.sysctl_data = &nmaxlwp;
+	error = sysctl_lookup(SYSCTLFN_CALL(&node));
+	if (error || newp == NULL)
+		return error;
+
+	if (nmaxlwp < 0 || nmaxlwp >= 65536)
+		return EINVAL;
+#ifdef __HAVE_CPU_MAXLWP
+	if (nmaxlwp > cpu_maxlwp())
+		return EINVAL;
+#endif
+	maxlwp = nmaxlwp;
+
+	return 0;
+}
+/*
  * sysctl helper function for kern.hostid. The hostid is a long, but
  * we export it as an int, so we need to give it a little help.
  */
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_exec.c,v
retrieving revision 1.352
diff -u -p -u -r1.352 kern_exec.c
--- kern/kern_exec.c	2 May 2012 23:33:11 -0000	1.352
+++ kern/kern_exec.c	23 May 2012 23:19:32 -0000
@@ -2295,7 +2295,7 @@ do_posix_spawn(struct lwp *l1, pid_t *pi
 
 	/* create LWP */
 	lwp_create(l1, p2, uaddr, 0, NULL, 0, spawn_return, spawn_data,
-	    &l2, l1->l_class);
+	    &l2, l1->l_class, 0);
 	l2->l_ctxlink = NULL;	/* reset ucontext link */
 
 	/*
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_fork.c,v
retrieving revision 1.189
diff -u -p -u -r1.189 kern_fork.c
--- kern/kern_fork.c	13 Mar 2012 18:40:52 -0000	1.189
+++ kern/kern_fork.c	23 May 2012 23:19:32 -0000
@@ -426,7 +426,7 @@ fork1(struct lwp *l1, int flags, int exi
 	 */
 	lwp_create(l1, p2, uaddr, (flags & FORK_PPWAIT) ? LWP_VFORK : 0,
 	    stack, stacksize, (func != NULL) ? func : child_return, arg, &l2,
-	    l1->l_class);
+	    l1->l_class, 0);
 
 	/*
 	 * Inherit l_private from the parent.
Index: kern/kern_kthread.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_kthread.c,v
retrieving revision 1.38
diff -u -p -u -r1.38 kern_kthread.c
--- kern/kern_kthread.c	1 Nov 2011 15:39:37 -0000	1.38
+++ kern/kern_kthread.c	23 May 2012 23:19:32 -0000
@@ -81,7 +81,7 @@ kthread_create(pri_t pri, int flag, stru
 	}
 
 	error = lwp_create(&lwp0, &proc0, uaddr, LWP_DETACHED, NULL,
-	    0, func, arg, &l, lc);
+	    0, func, arg, &l, lc, 0);
 	if (error) {
 		uvm_uarea_system_free(uaddr);
 		return error;
Index: kern/kern_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_lwp.c,v
retrieving revision 1.168
diff -u -p -u -r1.168 kern_lwp.c
--- kern/kern_lwp.c	13 Apr 2012 15:32:43 -0000	1.168
+++ kern/kern_lwp.c	23 May 2012 23:19:32 -0000
@@ -239,6 +239,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v
 #include <sys/dtrace_bsd.h>
 #include <sys/sdt.h>
 #include <sys/xcall.h>
+#include <sys/uidinfo.h>
 
 #include <uvm/uvm_extern.h>
 #include <uvm/uvm_object.h>
@@ -668,15 +669,32 @@ lwp_wait1(struct lwp *l, lwpid_t lid, lw
 int
 lwp_create(lwp_t *l1, proc_t *p2, vaddr_t uaddr, int flags,
 	   void *stack, size_t stacksize, void (*func)(void *), void *arg,
-	   lwp_t **rnewlwpp, int sclass)
+	   lwp_t **rnewlwpp, int sclass, int enforce)
 {
 	struct lwp *l2, *isfree;
 	turnstile_t *ts;
 	lwpid_t lid;
+	uid_t uid;
+	int count;
 
 	KASSERT(l1 == curlwp || l1->l_proc == &proc0);
 
 	/*
+	 * Enforce limits.
+	 */
+	uid = kauth_cred_getuid(l1->l_cred);
+	count = chglwpcnt(uid, 1);
+	if (enforce &&
+	    __predict_false(count > p2->p_rlimit[RLIMIT_NTHR].rlim_cur)) {
+		if (kauth_authorize_process(l1->l_cred, KAUTH_PROCESS_RLIMIT,
+		    p2, KAUTH_ARG(KAUTH_REQ_PROCESS_RLIMIT_BYPASS),
+		    &p2->p_rlimit[RLIMIT_NTHR], KAUTH_ARG(RLIMIT_NTHR)) != 0) {
+			(void)chglwpcnt(uid, -1);
+			return EAGAIN;
+		}
+	}
+
+	/*
 	 * First off, reap any detached LWP waiting to be collected.
 	 * We can re-use its LWP structure and turnstile.
 	 */
@@ -898,6 +916,7 @@ lwp_exit(struct lwp *l)
 
 	SDT_PROBE(proc,,,lwp_exit, l, 0,0,0,0);
 
+	chglwpcnt(kauth_cred_getuid(l->l_cred), -1);
 	/*
 	 * Verify that we hold no locks other than the kernel lock.
 	 */
Index: kern/kern_proc.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_proc.c,v
retrieving revision 1.183
diff -u -p -u -r1.183 kern_proc.c
--- kern/kern_proc.c	13 Apr 2012 15:32:15 -0000	1.183
+++ kern/kern_proc.c	23 May 2012 23:19:33 -0000
@@ -460,6 +460,9 @@ proc0_init(void)
 	rlim[RLIMIT_MEMLOCK].rlim_max = lim;
 	rlim[RLIMIT_MEMLOCK].rlim_cur = lim / 3;
 
+	rlim[RLIMIT_NTHR].rlim_max = maxlwp;
+	rlim[RLIMIT_NTHR].rlim_cur = maxlwp < maxuprc ? maxlwp : maxuprc;
+
 	/* Note that default core name has zero length. */
 	limit0.pl_corename = defcorename;
 	limit0.pl_cnlen = 0;
Index: kern/kern_prot.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_prot.c,v
retrieving revision 1.114
diff -u -p -u -r1.114 kern_prot.c
--- kern/kern_prot.c	19 Mar 2012 06:04:19 -0000	1.114
+++ kern/kern_prot.c	23 May 2012 23:19:33 -0000
@@ -346,6 +346,11 @@ do_setresuid(struct lwp *l, uid_t r, uid
 		/* Update count of processes for this user */
 		(void)chgproccnt(kauth_cred_getuid(ncred), -1);
 		(void)chgproccnt(r, 1);
+
+		int nlwps = p->p_nlwps;
+		(void)chglwpcnt(kauth_cred_getuid(ncred), -nlwps);
+		(void)chglwpcnt(r, nlwps);
+
 		kauth_cred_setuid(ncred, r);
 	}
 	if (sv != -1)
Index: kern/kern_resource.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_resource.c,v
retrieving revision 1.168
diff -u -p -u -r1.168 kern_resource.c
--- kern/kern_resource.c	2 Dec 2011 12:33:12 -0000	1.168
+++ kern/kern_resource.c	23 May 2012 23:19:33 -0000
@@ -439,6 +439,13 @@ dosetrlimit(struct lwp *l, struct proc *
 		if (limp->rlim_max > maxproc)
 			limp->rlim_max = maxproc;
 		break;
+
+	case RLIMIT_NTHR:
+		if (limp->rlim_cur > maxlwp)
+			limp->rlim_cur = maxlwp;
+		if (limp->rlim_max > maxlwp)
+			limp->rlim_max = maxlwp;
+		break;
 	}
 
 	mutex_enter(&p->p_limit->pl_lock);
@@ -1082,6 +1089,7 @@ sysctl_proc_setup(void)
 	create_proc_plimit("descriptors",	PROC_PID_LIMIT_NOFILE);
 	create_proc_plimit("sbsize",		PROC_PID_LIMIT_SBSIZE);
 	create_proc_plimit("vmemoryuse",	PROC_PID_LIMIT_AS);
+	create_proc_plimit("maxlwp",		PROC_PID_LIMIT_NTHR);
 
 #undef create_proc_plimit
 
Index: kern/kern_synch.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
retrieving revision 1.301
diff -u -p -u -r1.301 kern_synch.c
--- kern/kern_synch.c	21 Apr 2012 22:38:25 -0000	1.301
+++ kern/kern_synch.c	23 May 2012 23:19:34 -0000
@@ -96,6 +96,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_synch.c
 #include <sys/lwpctl.h>
 #include <sys/atomic.h>
 #include <sys/simplelock.h>
+#include <sys/uidinfo.h>
+#include <sys/kauth.h>
 #include <sys/syslog.h>
 
 #include <uvm/uvm_extern.h>
@@ -805,6 +807,7 @@ lwp_exit_switchaway(lwp_t *l)
 	LOCKDEBUG_BARRIER(NULL, 0);
 
 	kstack_check_magic(l);
+	chglwpcnt(kauth_cred_geteuid(l->l_cred), -1);
 
 	/* Count time spent in current system call */
 	SYSCALL_TIME_SLEEP(l);
Index: kern/kern_uidinfo.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_uidinfo.c,v
retrieving revision 1.5
diff -u -p -u -r1.5 kern_uidinfo.c
--- kern/kern_uidinfo.c	22 Mar 2009 00:49:13 -0000	1.5
+++ kern/kern_uidinfo.c	23 May 2012 23:19:34 -0000
@@ -43,6 +43,8 @@ __KERNEL_RCSID(0, "$NetBSD: kern_uidinfo
 #include <sys/proc.h>
 #include <sys/atomic.h>
 #include <sys/uidinfo.h>
+#include <sys/sysctl.h>
+#include <sys/kauth.h>
 #include <sys/cpu.h>
 
 static SLIST_HEAD(uihashhead, uidinfo) *uihashtbl;
@@ -50,6 +52,79 @@ static u_long 		uihash;
 
 #define	UIHASH(uid)	(&uihashtbl[(uid) & uihash])
 
+static int
+sysctl_kern_uidinfo_cnt(SYSCTLFN_ARGS)
+{  
+	static const struct {
+		const char *name;
+		u_int value;
+	} nv[] = {
+#define _MEM(n) { # n, offsetof(struct uidinfo, ui_ ## n) }
+		_MEM(proccnt),
+		_MEM(lwpcnt),
+		_MEM(lockcnt),
+		_MEM(sbsize),
+#undef _MEM
+	};
+
+	for (size_t i = 0; i < __arraycount(nv); i++)
+		if (strcmp(nv[i].name, rnode->sysctl_name) == 0) {
+			uint64_t cnt;
+			struct sysctlnode node = *rnode;
+			struct uidinfo *uip;
+
+			node.sysctl_data = &cnt;
+			uip = uid_find(kauth_cred_geteuid(l->l_cred));
+
+			*(uint64_t *)node.sysctl_data = 
+			    *(u_long *)((char *)uip + nv[i].value);
+
+			return sysctl_lookup(SYSCTLFN_CALL(&node));
+		}
+
+	return EINVAL;
+}
+
+static void
+sysctl_kern_uidinfo_setup(void)
+{
+	const struct sysctlnode *rnode, *cnode;
+	struct sysctllog *kern_uidinfo_sysctllog;
+
+	kern_uidinfo_sysctllog = NULL;
+	sysctl_createv(&kern_uidinfo_sysctllog, 0, NULL, &rnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_NODE, "uidinfo",
+		       SYSCTL_DESCR("Resource usage per uid"),
+		       NULL, 0, NULL, 0,
+		       CTL_KERN, CTL_CREATE, CTL_EOL);
+
+	sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_QUAD, "proccnt",
+		       SYSCTL_DESCR("Number of processes for the current user"),
+		       sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_QUAD, "lwpcnt",
+		       SYSCTL_DESCR("Number of lwps for the current user"),
+		       sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_QUAD, "lockcnt",
+		       SYSCTL_DESCR("Number of locks for the current user"),
+		       sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+	sysctl_createv(&kern_uidinfo_sysctllog, 0, &rnode, &cnode,
+		       CTLFLAG_PERMANENT,
+		       CTLTYPE_QUAD, "sbsize",
+		       SYSCTL_DESCR("Socket buffers used for the current user"),
+		       sysctl_kern_uidinfo_cnt, 0, NULL, 0,
+		       CTL_CREATE, CTL_EOL);
+}
+
 void
 uid_init(void)
 {
@@ -68,6 +143,7 @@ uid_init(void)
 	 * sbreserve() expects it available from interrupt context.
 	 */
 	(void)uid_find(0);
+	sysctl_kern_uidinfo_setup();
 }
 
 struct uidinfo *
@@ -126,6 +202,22 @@ chgproccnt(uid_t uid, int diff)
 	return proccnt;
 }
 
+/*
+ * Change the count associated with number of lwps
+ * a given user is using.
+ */
+int
+chglwpcnt(uid_t uid, int diff)
+{
+	struct uidinfo *uip;
+	long lwpcnt;
+
+	uip = uid_find(uid);
+	lwpcnt = atomic_add_long_nv(&uip->ui_lwpcnt, diff);
+	KASSERT(lwpcnt >= 0);
+	return lwpcnt;
+}
+
 int
 chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t xmax)
 {
Index: kern/sys_aio.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_aio.c,v
retrieving revision 1.37
diff -u -p -u -r1.37 sys_aio.c
--- kern/sys_aio.c	17 Feb 2011 19:02:50 -0000	1.37
+++ kern/sys_aio.c	23 May 2012 23:19:34 -0000
@@ -211,7 +211,7 @@ aio_procinit(struct proc *p)
 		return EAGAIN;
 	}
 	error = lwp_create(curlwp, p, uaddr, 0, NULL, 0, aio_worker,
-	    NULL, &l, curlwp->l_class);
+	    NULL, &l, curlwp->l_class, 1);
 	if (error != 0) {
 		uvm_uarea_free(uaddr);
 		aio_exit(p, aio);
Index: kern/sys_lwp.c
===================================================================
RCS file: /cvsroot/src/sys/kern/sys_lwp.c,v
retrieving revision 1.53
diff -u -p -u -r1.53 sys_lwp.c
--- kern/sys_lwp.c	19 Feb 2012 21:06:56 -0000	1.53
+++ kern/sys_lwp.c	23 May 2012 23:19:34 -0000
@@ -101,7 +101,7 @@ sys__lwp_create(struct lwp *l, const str
 	}
 
 	error = lwp_create(l, p, uaddr, SCARG(uap, flags) & LWP_DETACHED,
-	    NULL, 0, p->p_emul->e_startlwp, newuc, &l2, l->l_class);
+	    NULL, 0, p->p_emul->e_startlwp, newuc, &l2, l->l_class, 1);
 	if (__predict_false(error)) {
 		uvm_uarea_free(uaddr);
 		kmem_free(newuc, sizeof(ucontext_t));
Index: sys/lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.160
diff -u -p -u -r1.160 lwp.h
--- sys/lwp.h	19 Feb 2012 21:06:58 -0000	1.160
+++ sys/lwp.h	23 May 2012 23:19:35 -0000
@@ -210,6 +210,7 @@ LIST_HEAD(lwplist, lwp);		/* A list of L
 #ifdef _KERNEL
 extern struct lwplist	alllwp;		/* List of all LWPs. */
 extern lwp_t		lwp0;		/* LWP for proc0. */
+extern int		maxlwp;		/* max number of lwps */
 #endif
 
 /* These flags are kept in l_flag. */
@@ -409,7 +410,7 @@ lwp_eprio(lwp_t *l)
 }
 
 int lwp_create(lwp_t *, struct proc *, vaddr_t, int,
-    void *, size_t, void (*)(void *), void *, lwp_t **, int);
+    void *, size_t, void (*)(void *), void *, lwp_t **, int, int);
 
 /*
  * XXX _MODULE
Index: sys/resource.h
===================================================================
RCS file: /cvsroot/src/sys/sys/resource.h,v
retrieving revision 1.32
diff -u -p -u -r1.32 resource.h
--- sys/resource.h	14 May 2011 17:57:05 -0000	1.32
+++ sys/resource.h	23 May 2012 23:19:35 -0000
@@ -90,9 +90,10 @@ struct	rusage {
 #define	RLIMIT_SBSIZE	9		/* maximum size of all socket buffers */
 #define	RLIMIT_AS	10		/* virtual process size (inclusive of mmap) */
 #define	RLIMIT_VMEM	RLIMIT_AS	/* common alias */
+#define	RLIMIT_NTHR	11		/* number of threads */
 
 #if defined(_NETBSD_SOURCE)
-#define	RLIM_NLIMITS	11		/* number of resource limits */
+#define	RLIM_NLIMITS	12		/* number of resource limits */
 #endif
 
 #define	RLIM_INFINITY	(~((u_quad_t)1 << 63))	/* no limit */
Index: sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.199
diff -u -p -u -r1.199 sysctl.h
--- sys/sysctl.h	27 Jan 2012 19:48:41 -0000	1.199
+++ sys/sysctl.h	23 May 2012 23:19:36 -0000
@@ -266,7 +266,8 @@ struct ctlname {
 #define	KERN_SYSVIPC		82	/* node: SysV IPC parameters */
 #define	KERN_BOOTTIME		83	/* struct: time kernel was booted */
 #define	KERN_EVCNT		84	/* struct: evcnts */
-#define	KERN_MAXID		85	/* number of valid kern ids */
+#define	KERN_MAXLWP		85	/* int: maxlwp */
+#define	KERN_MAXID		86	/* number of valid kern ids */
 
 
 #define	CTL_KERN_NAMES { \
@@ -355,6 +356,7 @@ struct ctlname {
 	{ "sysvipc", CTLTYPE_STRUCT }, \
 	{ "boottime", CTLTYPE_STRUCT }, \
 	{ "evcnt", CTLTYPE_STRUCT }, \
+	{ "maxlwp", CTLTYPE_INT }, \
 }
 
 /*
@@ -975,6 +977,7 @@ struct evcnt_sysctl {
 #define	PROC_PID_LIMIT_NOFILE	(RLIMIT_NOFILE+1)
 #define	PROC_PID_LIMIT_SBSIZE	(RLIMIT_SBSIZE+1)
 #define	PROC_PID_LIMIT_AS	(RLIMIT_AS+1)
+#define	PROC_PID_LIMIT_NTHR	(RLIMIT_NTHR+1)
 #define	PROC_PID_LIMIT_MAXID 	(RLIM_NLIMITS+1)
 
 #define	PROC_PID_LIMIT_NAMES { \
@@ -990,6 +993,7 @@ struct evcnt_sysctl {
 	{ "descriptors", CTLTYPE_NODE }, \
 	{ "sbsize", CTLTYPE_NODE }, \
 	{ "vmemoryuse", CTLTYPE_NODE }, \
+	{ "maxlwp", CTLTYPE_NODE }, \
 }
 /* for each type, either hard or soft value */
 #define	PROC_PID_LIMIT_TYPE_SOFT	1
Index: sys/uidinfo.h
===================================================================
RCS file: /cvsroot/src/sys/sys/uidinfo.h,v
retrieving revision 1.2
diff -u -p -u -r1.2 uidinfo.h
--- sys/uidinfo.h	14 Oct 2008 09:16:32 -0000	1.2
+++ sys/uidinfo.h	23 May 2012 23:19:36 -0000
@@ -43,11 +43,13 @@ struct uidinfo {
 	SLIST_ENTRY(uidinfo) ui_hash;
 	uid_t	ui_uid;
 	u_long	ui_proccnt;	/* Number of processes */
+	u_long	ui_lwpcnt;	/* Number of lwps */
 	u_long	ui_lockcnt;	/* Number of locks */
 	u_long	ui_sbsize;	/* Socket buffer size */
 };
 
 int	chgproccnt(uid_t, int);
+int	chglwpcnt(uid_t, int);
 int	chgsbsize(struct uidinfo *, u_long *, u_long, rlim_t);
 struct uidinfo *uid_find(uid_t);
 void	uid_init(void);