lwp_rtprio.patch

aoiko, 04/30/2007 12:49 PM

Download (3.47 KB)

View differences:

kern/kern_resource.c 28 Apr 2007 20:24:55 -0000
261 261
	return (0);
262 262
}
263 263

  
264
int
265
sys_lwp_rtprio(struct lwp_rtprio_args *uap)
266
{
267
	struct proc *p = curproc;
268
	struct lwp *lp;
269
	struct rtprio rtp;
270
	struct ucred *cr = p->p_ucred;
271
	int error;
272

  
273
	error = copyin(uap->rtp, &rtp, sizeof(struct rtprio));
274
	if (error)
275
		return error;
276

  
277
	if (uap->pid < 0) {
278
		return EINVAL;
279
	} else if (uap->pid == 0) {
280
		/* curproc already loaded on p */
281
	} else {
282
		p = pfind(uap->pid);
283
	}
284

  
285
	if (p == 0) {
286
		return ESRCH;
287
	}
288

  
289
	if (uap->tid < -1) {
290
		return EINVAL;
291
	} else if (uap->tid == -1) {
292
		/*
293
		 * sadly, tid can be 0 so we can't use 0 here
294
		 * like sys_rtprio()
295
		 */
296
		lp = curthread->td_lwp;
297
	} else {
298
		FOREACH_LWP_IN_PROC(lp, p) {
299
			if (lp->lwp_tid == uap->tid) {
300
				break;
301
			}
302
		}
303
		if (!lp) {
304
			return ESRCH;
305
		}
306
	}
307

  
308
	switch (uap->function) {
309
	case RTP_LOOKUP:
310
		return (copyout(&lp->lwp_rtprio, uap->rtp,
311
				sizeof(struct rtprio)));
312
	case RTP_SET:
313
		if (cr->cr_uid && cr->cr_ruid &&
314
		    cr->cr_uid != p->p_ucred->cr_uid &&
315
		    cr->cr_ruid != p->p_ucred->cr_uid) {
316
			return EPERM;
317
		}
318
		/* disallow setting rtprio in most cases if not superuser */
319
		if (suser_cred(cr, 0)) {
320
			/* can't set someone else's */
321
			if (uap->pid) { /* XXX */
322
				return EPERM;
323
			}
324
			/* can't set realtime priority */
325
/*
326
 * Realtime priority has to be restricted for reasons which should be
327
 * obvious. However, for idle priority, there is a potential for
328
 * system deadlock if an idleprio process gains a lock on a resource
329
 * that other processes need (and the idleprio process can't run
330
 * due to a CPU-bound normal process). Fix me! XXX
331
 */
332
 			if (RTP_PRIO_IS_REALTIME(rtp.type)) {
333
				return EPERM;
334
			}
335
		}
336
		switch (rtp.type) {
337
#ifdef RTP_PRIO_FIFO
338
		case RTP_PRIO_FIFO:
339
#endif
340
		case RTP_PRIO_REALTIME:
341
		case RTP_PRIO_NORMAL:
342
		case RTP_PRIO_IDLE:
343
			if (rtp.prio > RTP_PRIO_MAX)
344
				return EINVAL;
345
			lp->lwp_rtprio = rtp;
346
			return 0;
347
		default:
348
			return EINVAL;
349
		}
350
	default:
351
		return EINVAL;
352
	}
353
	panic("can't get here");
354
}
355

  
264 356
/*
265 357
 * Set realtime priority
266 358
 */
kern/syscalls.master 28 Apr 2007 12:01:48 -0000
680 680
495	STD	BSD	{ int lwp_create(struct lwp_params *params); }
681 681
496	STD	BSD	{ lwpid_t lwp_gettid(void); }
682 682
497	STD	BSD	{ int lwp_kill(pid_t pid, lwpid_t tid, int signum); }
683
498	STD	BSD	{ int lwp_rtprio(int function, pid_t pid, lwpid_t tid, struct rtprio *rtp); }
sys/rtprio.h 28 Apr 2007 17:38:22 -0000
81 81

  
82 82
__BEGIN_DECLS
83 83
int	rtprio (int, pid_t, struct rtprio *);
84
int	lwp_rtprio (int, pid_t, lwpid_t, struct rtprio *);
84 85
__END_DECLS
85 86
#endif	/* !_KERNEL */
86 87
#endif	/* !_SYS_RTPRIO_H_ */