xu-schedparams-checkother.patch

aoiko, 04/30/2007 12:49 PM

Download (9.06 KB)

View differences:

thread/thr_attr.c 27 Apr 2007 21:37:04 -0000
49 49
struct pthread_attr _pthread_attr_default = {
50 50
	.sched_policy = SCHED_OTHER,
51 51
	.sched_inherit = 0,
52
	.sched_interval = TIMESLICE_USEC,
53 52
	.prio = THR_DEFAULT_PRIORITY,
54 53
	.suspend = THR_CREATE_RUNNING,
55 54
	.flags = 0,
thread/thr_getschedparam.c 28 Apr 2007 09:46:01 -0000
46 46
	struct sched_param *param)
47 47
{
48 48
	struct pthread *curthread = tls_get_curthread();
49
	int ret, tmp;
49
	int ret;
50 50

  
51
	if ((param == NULL) || (policy == NULL))
52
		/* Return an invalid argument error: */
53
		ret = EINVAL;
54
	else if (pthread == curthread) {
51
	if (policy == NULL || param == NULL)
52
		return (EINVAL);
53

  
54
	if (pthread == curthread) {
55 55
		/*
56 56
		 * Avoid searching the thread list when it is the current
57 57
		 * thread.
58 58
		 */
59
		THR_THREAD_LOCK(curthread, curthread);
60
		param->sched_priority =
61
		    THR_BASE_PRIORITY(pthread->base_priority);
62
		tmp = pthread->attr.sched_policy;
63
		THR_THREAD_UNLOCK(curthread, curthread);
64
		*policy = tmp;
59
		THR_LOCK(curthread);
60
		*policy = curthread->attr.sched_policy;
61
		param->sched_priority = curthread->attr.prio;
62
		THR_UNLOCK(curthread);
65 63
		ret = 0;
66 64
	}
67 65
	/* Find the thread in the list of active threads. */
68 66
	else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
69 67
	    == 0) {
70 68
		THR_THREAD_LOCK(curthread, pthread);
71
		param->sched_priority =
72
		    THR_BASE_PRIORITY(pthread->base_priority);
73
		tmp = pthread->attr.sched_policy;
69
		*policy = pthread->attr.sched_policy;
70
		param->sched_priority = pthread->attr.prio;
74 71
		THR_THREAD_UNLOCK(curthread, pthread);
75 72
		_thr_ref_delete(curthread, pthread);
76
		*policy = tmp;
77 73
	}
78 74
	return (ret);
79 75
}
thread/thr_kern.c 30 Apr 2007 11:17:45 -0000
29 29
#include <sys/cdefs.h>
30 30
#include <sys/types.h>
31 31
#include <sys/signalvar.h>
32
#include <sys/rtprio.h>
32 33
#include <pthread.h>
33 34
#include "thr_private.h"
34 35

  
......
103 104
{
104 105
	return (lwp_gettid());
105 106
}
107

  
108
/*
109
 * We don't use the priority for SCHED_OTHER, but
110
 * some programs may depend on getting an error when
111
 * setting a priority that is out of the range returned
112
 * by sched_get_priority_{min,max}. Not sure if this
113
 * falls into implementation defined behavior or not.
114
 */
115
int
116
_thr_set_sched_other_prio(struct pthread *pth, int prio)
117
{
118
	static int max, min, init_status;
119

  
120
	/*
121
	 * switch (init_status) {
122
	 * case 0: need initialization
123
	 * case 1: initialization successful
124
	 * case 2: initialization failed. can't happen, but if
125
	 * 	   it does, accept all and hope for the best.
126
	 * 	   It's not like we use it anyway.
127
	 */
128
	if (!init_status) {
129
		int tmp = errno;
130

  
131
		errno = 0;
132
		init_status = 1;
133
		if (((min = sched_get_priority_min(SCHED_OTHER)) == -1) &&
134
								(errno != 0))
135
			init_status = 2;
136
		if (((max = sched_get_priority_max(SCHED_OTHER)) == -1) &&
137
								(errno != 0))
138
			init_status = 2;
139
		errno = tmp;
140
	}
141
	if ((init_status == 2) || ((prio >= min) && (prio <= max))) {
142
		return 0;
143
	}
144
	errno = EINVAL;
145
	return -1;
146
}
147

  
148
int
149
_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
150
	struct sched_param *param)
151
{
152
	switch(rtp->type) {
153
	case RTP_PRIO_REALTIME:
154
		*policy = SCHED_RR;
155
		param->sched_priority = RTP_PRIO_MAX - rtp->prio;
156
		break;
157
	case RTP_PRIO_FIFO:
158
		*policy = SCHED_FIFO;
159
		param->sched_priority = RTP_PRIO_MAX - rtp->prio;
160
		break;
161
	default:
162
		*policy = SCHED_OTHER;
163
		param->sched_priority = 0;
164
		break;
165
	}
166
	return (0);
167
}
168

  
169
int
170
_schedparam_to_rtp(int policy, const struct sched_param *param,
171
	struct rtprio *rtp)
172
{
173
	switch(policy) {
174
	case SCHED_RR:
175
		rtp->type = RTP_PRIO_REALTIME;
176
		rtp->prio = RTP_PRIO_MAX - param->sched_priority;
177
		break;
178
	case SCHED_FIFO:
179
		rtp->type = RTP_PRIO_FIFO;
180
		rtp->prio = RTP_PRIO_MAX - param->sched_priority;
181
		break;
182
	case SCHED_OTHER:
183
	default:
184
		rtp->type = RTP_PRIO_NORMAL;
185
		rtp->prio = 0;
186
		break;
187
	}
188
	return (0);
189
}
190

  
191
int
192
_thr_getscheduler(lwpid_t lwpid, int *policy, struct sched_param *param)
193
{
194
	struct pthread *curthread = tls_get_curthread();
195
	struct rtprio rtp;
196
	int ret;
197

  
198
	if (lwpid == curthread->tid)
199
		lwpid = -1;
200
	ret = lwp_rtprio(RTP_LOOKUP, 0, lwpid, &rtp);
201
	if (ret == -1)
202
		return (ret);
203
	_rtp_to_schedparam(&rtp, policy, param);
204
	return (0);
205
}
206

  
207
int
208
_thr_setscheduler(lwpid_t lwpid, int policy, const struct sched_param *param)
209
{
210
	struct pthread *curthread = tls_get_curthread();
211
	struct rtprio rtp;
212

  
213
	if (lwpid == curthread->tid)
214
		lwpid = -1;
215
	_schedparam_to_rtp(policy, param, &rtp);
216
	return (lwp_rtprio(RTP_SET, 0, lwpid, &rtp));
217
}
thread/thr_private.h 30 Apr 2007 10:38:54 -0000
236 236
struct pthread_attr {
237 237
	int	sched_policy;
238 238
	int	sched_inherit;
239
	int	sched_interval;
240 239
	int	prio;
241 240
	int	suspend;
242 241
#define	THR_STACK_USER		0x100	/* 0xFF reserved for <pthread.h> */
......
691 690
void	_thr_report_death(struct pthread *curthread);
692 691
void	_thread_bp_create(void);
693 692
void	_thread_bp_death(void);
693
int	_thr_getscheduler(lwpid_t, int *, struct sched_param *);
694
int	_thr_setscheduler(lwpid_t, int, const struct sched_param *);
695
int	_thr_set_sched_other_prio(struct pthread *, int);
694 696

  
695 697
/* #include <sys/aio.h> */
696 698
#ifdef _SYS_AIO_H_
thread/thr_setschedparam.c 30 Apr 2007 10:40:46 -0000
49 49
	struct pthread *curthread = tls_get_curthread();
50 50
	int	ret = 0;
51 51

  
52
	if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) {
53
		/* Return an invalid argument error: */
54
		ret = EINVAL;
55
	} else if ((param->sched_priority < THR_MIN_PRIORITY) ||
56
	    (param->sched_priority > THR_MAX_PRIORITY)) {
57
		/* Return an unsupported value error. */
58
		ret = ENOTSUP;
59

  
60
	/* Find the thread in the list of active threads: */
52
	if (pthread == curthread) {
53
		THR_LOCK(curthread);
54
		if (curthread->attr.sched_policy == policy &&
55
		     curthread->attr.prio == param->sched_priority) {
56
			THR_UNLOCK(curthread);
57
			return (0);
58
		}
59
		if (policy == SCHED_OTHER) {
60
			ret = _thr_set_sched_other_prio(curthread,
61
						param->sched_priority);
62
		} else {
63
			ret = _thr_setscheduler(curthread->tid, policy, param);
64
		}
65
		if (ret == -1)
66
			ret = errno;
67
		else {
68
			curthread->attr.sched_policy = policy;
69
			curthread->attr.prio = param->sched_priority;
70
		}
71
		THR_UNLOCK(curthread);
61 72
	} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
62
	    == 0) {
63
		/*
64
		 * Lock the threads scheduling queue while we change
65
		 * its priority:
66
		 */
73
		== 0) {
67 74
		THR_THREAD_LOCK(curthread, pthread);
68
		if (pthread->state == PS_DEAD) {
75
		if (pthread->attr.sched_policy == policy &&
76
		     pthread->attr.prio == param->sched_priority) {
69 77
			THR_THREAD_UNLOCK(curthread, pthread);
70
			_thr_ref_delete(curthread, pthread);
71
			return (ESRCH);
78
			return (0);
72 79
		}
73

  
74
		/* Set the scheduling policy: */
75
		pthread->attr.sched_policy = policy;
76

  
77
		if (param->sched_priority ==
78
		    THR_BASE_PRIORITY(pthread->base_priority))
79
			/*
80
			 * There is nothing to do; unlock the threads
81
			 * scheduling queue.
82
			 */
83
			THR_THREAD_UNLOCK(curthread, pthread);
80
		if (policy == SCHED_OTHER) {
81
			ret = _thr_set_sched_other_prio(curthread,
82
						param->sched_priority);
83
		} else {
84
			ret = _thr_setscheduler(curthread->tid, policy, param);
85
		}
86
		if (ret == -1)
87
			ret = errno;
84 88
		else {
85
			/* Set the thread base priority: */
86
			pthread->base_priority = param->sched_priority;
87

  
88
			/* Recalculate the active priority: */
89
			pthread->active_priority = MAX(pthread->base_priority,
90
			    pthread->inherited_priority);
91

  
92
			/* Unlock the threads scheduling queue: */
93
			THR_THREAD_UNLOCK(curthread, pthread);
89
			pthread->attr.sched_policy = policy;
90
			pthread->attr.prio = param->sched_priority;
94 91
		}
92
		THR_THREAD_UNLOCK(curthread, pthread);
95 93
		_thr_ref_delete(curthread, pthread);
96 94
	}
97 95
	return (ret);