sched-weak.c 5.64 KB
Newer Older
1
/*
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 * Copyright (C) 2013 Philippe Gerum <rpm@xenomai.org>.
 *
 * Xenomai is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.
 *
 * Xenomai is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Xenomai; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.
 */
19
#include <cobalt/kernel/sched.h>
20
#include <cobalt/uapi/sched.h>
21
22
23

static void xnsched_weak_init(struct xnsched *sched)
{
24
	xnsched_initq(&sched->weak.runnable);
25
26
27
28
}

static void xnsched_weak_requeue(struct xnthread *thread)
{
29
	xnsched_addq(&thread->sched->weak.runnable, thread);
30
31
32
33
}

static void xnsched_weak_enqueue(struct xnthread *thread)
{
34
	xnsched_addq_tail(&thread->sched->weak.runnable, thread);
35
36
37
38
}

static void xnsched_weak_dequeue(struct xnthread *thread)
{
39
	xnsched_delq(&thread->sched->weak.runnable, thread);
40
41
42
43
}

static struct xnthread *xnsched_weak_pick(struct xnsched *sched)
{
44
	return xnsched_getq(&sched->weak.runnable);
45
46
}

47
48
static bool xnsched_weak_setparam(struct xnthread *thread,
				  const union xnsched_policy_param *p)
49
50
51
{
	if (!xnthread_test_state(thread, XNBOOST))
		xnthread_set_state(thread, XNWEAK);
52
53

	return xnsched_set_effective_priority(thread, p->weak.prio);
54
55
}

56
57
static void xnsched_weak_getparam(struct xnthread *thread,
				  union xnsched_policy_param *p)
58
59
60
61
{
	p->weak.prio = thread->cprio;
}

62
63
static void xnsched_weak_trackprio(struct xnthread *thread,
				   const union xnsched_policy_param *p)
64
65
{
	if (p)
66
		thread->cprio = p->weak.prio;
67
68
69
70
	else
		thread->cprio = thread->bprio;
}

71
static void xnsched_weak_protectprio(struct xnthread *thread, int prio)
72
73
74
75
76
77
78
{
  	if (prio > XNSCHED_WEAK_MAX_PRIO)
		prio = XNSCHED_WEAK_MAX_PRIO;

	thread->cprio = prio;
}

79
80
81
82
83
84
85
86
87
88
static int xnsched_weak_declare(struct xnthread *thread,
				const union xnsched_policy_param *p)
{
	if (p->weak.prio < XNSCHED_WEAK_MIN_PRIO ||
	    p->weak.prio > XNSCHED_WEAK_MAX_PRIO)
		return -EINVAL;

	return 0;
}

89
90
91
92
93
#ifdef CONFIG_XENO_OPT_VFILE

struct xnvfile_directory sched_weak_vfroot;

struct vfile_sched_weak_priv {
94
	struct xnthread *curr;
95
96
97
98
99
100
101
102
103
104
105
106
107
108
};

struct vfile_sched_weak_data {
	int cpu;
	pid_t pid;
	char name[XNOBJECT_NAME_LEN];
	int cprio;
};

static struct xnvfile_snapshot_ops vfile_sched_weak_ops;

static struct xnvfile_snapshot vfile_sched_weak = {
	.privsz = sizeof(struct vfile_sched_weak_priv),
	.datasz = sizeof(struct vfile_sched_weak_data),
109
	.tag = &nkthreadlist_tag,
110
111
112
113
114
115
116
117
118
119
120
	.ops = &vfile_sched_weak_ops,
};

static int vfile_sched_weak_rewind(struct xnvfile_snapshot_iterator *it)
{
	struct vfile_sched_weak_priv *priv = xnvfile_iterator_priv(it);
	int nrthreads = xnsched_class_weak.nthreads;

	if (nrthreads == 0)
		return -ESRCH;

121
	priv->curr = list_first_entry(&nkthreadq, struct xnthread, glink);
122
123
124
125
126
127
128
129
130
131
132
133
134
135

	return nrthreads;
}

static int vfile_sched_weak_next(struct xnvfile_snapshot_iterator *it,
				 void *data)
{
	struct vfile_sched_weak_priv *priv = xnvfile_iterator_priv(it);
	struct vfile_sched_weak_data *p = data;
	struct xnthread *thread;

	if (priv->curr == NULL)
		return 0;	/* All done. */

136
	thread = priv->curr;
137
	if (list_is_last(&thread->glink, &nkthreadq))
138
139
140
		priv->curr = NULL;
	else
		priv->curr = list_next_entry(thread, glink);
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162

	if (thread->base_class != &xnsched_class_weak)
		return VFILE_SEQ_SKIP;

	p->cpu = xnsched_cpu(thread->sched);
	p->pid = xnthread_host_pid(thread);
	memcpy(p->name, thread->name, sizeof(p->name));
	p->cprio = thread->cprio;

	return 1;
}

static int vfile_sched_weak_show(struct xnvfile_snapshot_iterator *it,
				 void *data)
{
	struct vfile_sched_weak_data *p = data;
	char pribuf[16];

	if (p == NULL)
		xnvfile_printf(it, "%-3s  %-6s %-4s %s\n",
			       "CPU", "PID", "PRI", "NAME");
	else {
163
		ksformat(pribuf, sizeof(pribuf), "%3d", p->cprio);
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
		xnvfile_printf(it, "%3u  %-6d %-4s %s\n",
			       p->cpu,
			       p->pid,
			       pribuf,
			       p->name);
	}

	return 0;
}

static struct xnvfile_snapshot_ops vfile_sched_weak_ops = {
	.rewind = vfile_sched_weak_rewind,
	.next = vfile_sched_weak_next,
	.show = vfile_sched_weak_show,
};

static int xnsched_weak_init_vfile(struct xnsched_class *schedclass,
				   struct xnvfile_directory *vfroot)
{
	int ret;

	ret = xnvfile_init_dir(schedclass->name, &sched_weak_vfroot, vfroot);
	if (ret)
		return ret;

	return xnvfile_init_snapshot("threads", &vfile_sched_weak,
				     &sched_weak_vfroot);
}

static void xnsched_weak_cleanup_vfile(struct xnsched_class *schedclass)
{
	xnvfile_destroy_snapshot(&vfile_sched_weak);
	xnvfile_destroy_dir(&sched_weak_vfroot);
}

#endif /* CONFIG_XENO_OPT_VFILE */

struct xnsched_class xnsched_class_weak = {
	.sched_init		=	xnsched_weak_init,
	.sched_enqueue		=	xnsched_weak_enqueue,
	.sched_dequeue		=	xnsched_weak_dequeue,
	.sched_requeue		=	xnsched_weak_requeue,
	.sched_pick		=	xnsched_weak_pick,
	.sched_tick		=	NULL,
	.sched_rotate		=	NULL,
	.sched_forget		=	NULL,
210
	.sched_kick		=	NULL,
211
	.sched_declare		=	xnsched_weak_declare,
212
213
	.sched_setparam		=	xnsched_weak_setparam,
	.sched_trackprio	=	xnsched_weak_trackprio,
214
	.sched_protectprio	=	xnsched_weak_protectprio,
215
216
217
218
219
220
	.sched_getparam		=	xnsched_weak_getparam,
#ifdef CONFIG_XENO_OPT_VFILE
	.sched_init_vfile	=	xnsched_weak_init_vfile,
	.sched_cleanup_vfile	=	xnsched_weak_cleanup_vfile,
#endif
	.weight			=	XNSCHED_CLASS_WEIGHT(1),
221
	.policy			=	SCHED_WEAK,
222
223
224
	.name			=	"weak"
};
EXPORT_SYMBOL_GPL(xnsched_class_weak);