1219820Sjeff/*-
2219820Sjeff * Copyright (c) 2010 Isilon Systems, Inc.
3219820Sjeff * Copyright (c) 2010 iX Systems, Inc.
4219820Sjeff * Copyright (c) 2010 Panasas, Inc.
5299526Shselasky * Copyright (c) 2013-2016 Mellanox Technologies, Ltd.
6219820Sjeff * All rights reserved.
7219820Sjeff *
8219820Sjeff * Redistribution and use in source and binary forms, with or without
9219820Sjeff * modification, are permitted provided that the following conditions
10219820Sjeff * are met:
11219820Sjeff * 1. Redistributions of source code must retain the above copyright
12219820Sjeff *    notice unmodified, this list of conditions, and the following
13219820Sjeff *    disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff *
18219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19219820Sjeff * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20219820Sjeff * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21219820Sjeff * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22219820Sjeff * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23219820Sjeff * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24219820Sjeff * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25219820Sjeff * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26219820Sjeff * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27219820Sjeff * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28289644Shselasky *
29289644Shselasky * $FreeBSD: releng/11.0/sys/compat/linuxkpi/common/include/linux/sched.h 300671 2016-05-25 09:04:06Z hselasky $
30219820Sjeff */
31219820Sjeff#ifndef	_LINUX_SCHED_H_
32219820Sjeff#define	_LINUX_SCHED_H_
33219820Sjeff
34219820Sjeff#include <sys/param.h>
35219820Sjeff#include <sys/systm.h>
36219820Sjeff#include <sys/proc.h>
37219820Sjeff#include <sys/sched.h>
38219820Sjeff#include <sys/sleepqueue.h>
39219820Sjeff
40219820Sjeff#define	MAX_SCHEDULE_TIMEOUT	LONG_MAX
41219820Sjeff
42219820Sjeff#define	TASK_RUNNING		0
43219820Sjeff#define	TASK_INTERRUPTIBLE	1
44219820Sjeff#define	TASK_UNINTERRUPTIBLE	2
45219820Sjeff#define	TASK_DEAD		64
46219820Sjeff#define	TASK_WAKEKILL		128
47219820Sjeff#define	TASK_WAKING		256
48219820Sjeff
49219820Sjeff#define	TASK_SHOULD_STOP	1
50219820Sjeff#define	TASK_STOPPED		2
51219820Sjeff
52219820Sjeff/*
53299526Shselasky * A task_struct is only provided for threads created by kthread() and
54299526Shselasky * file operation callbacks.
55299526Shselasky *
56299526Shselasky * Using these routines outside the above mentioned contexts will
57299526Shselasky * cause panics because no task_struct is assigned and td_retval[1] is
58299526Shselasky * overwritten by syscalls.
59219820Sjeff */
60219820Sjeffstruct task_struct {
61219820Sjeff	struct	thread *task_thread;
62219820Sjeff	int	(*task_fn)(void *data);
63219820Sjeff	void	*task_data;
64219820Sjeff	int	task_ret;
65219820Sjeff	int	state;
66219820Sjeff	int	should_stop;
67299526Shselasky	pid_t	pid;
68299526Shselasky	const char    *comm;
69299530Shselasky	void	*bsd_ioctl_data;
70299530Shselasky	unsigned	bsd_ioctl_len;
71219820Sjeff};
72219820Sjeff
73289993Shselasky#define	current			task_struct_get(curthread)
74289993Shselasky#define	task_struct_get(x)	((struct task_struct *)(uintptr_t)(x)->td_retval[1])
75299526Shselasky#define	task_struct_fill(x, y) do {		\
76299526Shselasky  	(y)->task_thread = (x);			\
77299526Shselasky	(y)->comm = (x)->td_name;		\
78299526Shselasky	(y)->pid = (x)->td_tid;			\
79299526Shselasky} while (0)
80289993Shselasky#define	task_struct_set(x, y)	(x)->td_retval[1] = (uintptr_t)(y)
81219820Sjeff
82289993Shselasky/* ensure the task_struct pointer fits into the td_retval[1] field */
83289993ShselaskyCTASSERT(sizeof(((struct thread *)0)->td_retval[1]) >= sizeof(uintptr_t));
84289993Shselasky
85219820Sjeff#define	set_current_state(x)						\
86219820Sjeff	atomic_store_rel_int((volatile int *)&current->state, (x))
87219820Sjeff#define	__set_current_state(x)	current->state = (x)
88219820Sjeff
89219820Sjeff
90219820Sjeff#define	schedule()							\
91219820Sjeffdo {									\
92219820Sjeff	void *c;							\
93219820Sjeff									\
94300671Shselasky	if (cold || SCHEDULER_STOPPED())				\
95219820Sjeff		break;							\
96219820Sjeff	c = curthread;							\
97219820Sjeff	sleepq_lock(c);							\
98219820Sjeff	if (current->state == TASK_INTERRUPTIBLE ||			\
99219820Sjeff	    current->state == TASK_UNINTERRUPTIBLE) {			\
100219820Sjeff		sleepq_add(c, NULL, "task", SLEEPQ_SLEEP, 0);		\
101219820Sjeff		sleepq_wait(c, 0);					\
102219820Sjeff	} else {							\
103219820Sjeff		sleepq_release(c);					\
104219820Sjeff		sched_relinquish(curthread);				\
105219820Sjeff	}								\
106219820Sjeff} while (0)
107219820Sjeff
108219820Sjeff#define	wake_up_process(x)						\
109219820Sjeffdo {									\
110219820Sjeff	int wakeup_swapper;						\
111219820Sjeff	void *c;							\
112219820Sjeff									\
113219820Sjeff	c = (x)->task_thread;						\
114219820Sjeff	sleepq_lock(c);							\
115219820Sjeff	(x)->state = TASK_RUNNING;					\
116219820Sjeff	wakeup_swapper = sleepq_signal(c, SLEEPQ_SLEEP, 0, 0);		\
117219820Sjeff	sleepq_release(c);						\
118219820Sjeff	if (wakeup_swapper)						\
119219820Sjeff		kick_proc0();						\
120219820Sjeff} while (0)
121219820Sjeff
122219820Sjeff#define	cond_resched()	if (!cold)	sched_relinquish(curthread)
123219820Sjeff
124219820Sjeff#define	sched_yield()	sched_relinquish(curthread)
125219820Sjeff
126289566Shselaskystatic inline long
127289566Shselaskyschedule_timeout(signed long timeout)
128289566Shselasky{
129289566Shselasky	if (timeout < 0)
130289566Shselasky		return 0;
131289566Shselasky
132289566Shselasky	pause("lstim", timeout);
133289566Shselasky
134289566Shselasky	return 0;
135289566Shselasky}
136289566Shselasky
137219820Sjeff#endif	/* _LINUX_SCHED_H_ */
138