summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys/sysdc_impl.h
blob: bbc3814361d7dec1f7957b4d5ba7c54ab6f6f63b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License (the "License").
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef	_SYS_SYSDC_IMPL_H
#define	_SYS_SYSDC_IMPL_H

#include <sys/types.h>
#include <sys/time.h>
#include <sys/list.h>

#include <sys/sysdc.h>

#ifdef	__cplusplus
extern "C" {
#endif

struct _kthread;
struct cpupart;

/*
 * Tracks per-processor-set information for SDC.  Its main use is to
 * implement per-processor-set breaks.
 */
typedef struct sysdc_pset {
	list_node_t	sdp_node;	/* node on sysdc_psets list */
	struct cpupart	*sdp_cpupart;	/* associated cpu partition */
	size_t		sdp_nthreads;	/* reference count */

	/* The remainder is only touched by sysdc_update() */
	hrtime_t	sdp_onproc_time; /* time onproc at last update */
	boolean_t	sdp_need_break;	/* threads forced to minpri */
	uint_t		sdp_should_break; /* # updates need_break is set */
	uint_t		sdp_dont_break;	/* after break, # updates until next */

	/* debugging fields */
	uint_t		sdp_onproc_threads;
	hrtime_t	sdp_vtime_last_interval;
	uint_t		sdp_DC_last_interval;
} sysdc_pset_t;

/*
 * Per-thread information, pointed to by t_cldata.
 */
typedef struct sysdc {
	uint_t		sdc_target_DC;	/* target duty cycle */
	uint_t		sdc_minpri;	/* our minimum priority */
	uint_t		sdc_maxpri;	/* our maximum priority */

	sysdc_pset_t	*sdc_pset;	/* the processor set bound to */

	/* protected by sdl_lock */
	struct _kthread	*sdc_thread;	/* back-pointer, or NULL if freeable */

	/* protected by arrangement between thread and sysdc_update() */
	struct sysdc	*sdc_next;	/* next in hash table, NULL if not in */

	/* protected by thread_lock() */
	uint_t		sdc_nupdates;	/* number of sysdc_update_times() */

	hrtime_t	sdc_base_O;	/* on-cpu time at last reset */
	hrtime_t	sdc_base_R;	/* runnable time at last reset */

	uint_t		sdc_sleep_updates; /* 0, or nupdates when we slept */
	clock_t		sdc_ticks;	/* sdc_tick() calls */
	clock_t		sdc_update_ticks; /* value of ticks for forced update */
	clock_t		sdc_pri_check;	/* lbolt when we checked our priority */
	hrtime_t	sdc_last_base_O; /* onproc time at sysdc_update() */

	uint_t		sdc_pri;	/* our last computed priority */
	uint_t		sdc_epri;	/* our actual thread priority */

	/* for debugging only */
	clock_t		sdc_reset;	/* lbolt when we reset our bases */
	hrtime_t	sdc_cur_O;	/* on-cpu time at last prio check */
	hrtime_t	sdc_cur_R;	/* runnable time at last prio check */
	hrtime_t	sdc_last_O;	/* onproc time at thread update */
	uint_t		sdc_cur_DC;	/* our actual duty cycle at last chk */
} sysdc_t;

/*
 * Hash bucket of active SDC threads.
 */
typedef struct sysdc_list {
	kmutex_t	sdl_lock;	/* lock keeping threads from exiting */
	sysdc_t	*volatile sdl_list;	/* list of active threads in bucket */
	char		sdl_pad[64 - sizeof (kmutex_t) - sizeof (sysdc_t *)];
} sysdc_list_t;

/*
 * Args to CL_ENTERCLASS().
 */
typedef struct sysdc_params {
	uint_t		sdp_minpri;
	uint_t		sdp_maxpri;
	uint_t		sdp_DC;
} sysdc_params_t;

/*
 * Duty cycles are percentages in the range [1,100].
 */
#define	SYSDC_DC_MAX		100u	/* 1 <= DC <= DC_MAX */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_SYSDC_IMPL_H */