xref: /titanic_51/usr/src/uts/common/os/proc.c (revision 0baeff3d96eae184e775c1064f1836090446a7bf)
1*0baeff3dSrab /*
2*0baeff3dSrab  * CDDL HEADER START
3*0baeff3dSrab  *
4*0baeff3dSrab  * The contents of this file are subject to the terms of the
5*0baeff3dSrab  * Common Development and Distribution License, Version 1.0 only
6*0baeff3dSrab  * (the "License").  You may not use this file except in compliance
7*0baeff3dSrab  * with the License.
8*0baeff3dSrab  *
9*0baeff3dSrab  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0baeff3dSrab  * or http://www.opensolaris.org/os/licensing.
11*0baeff3dSrab  * See the License for the specific language governing permissions
12*0baeff3dSrab  * and limitations under the License.
13*0baeff3dSrab  *
14*0baeff3dSrab  * When distributing Covered Code, include this CDDL HEADER in each
15*0baeff3dSrab  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0baeff3dSrab  * If applicable, add the following below this CDDL HEADER, with the
17*0baeff3dSrab  * fields enclosed by brackets "[]" replaced with your own identifying
18*0baeff3dSrab  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0baeff3dSrab  *
20*0baeff3dSrab  * CDDL HEADER END
21*0baeff3dSrab  */
22*0baeff3dSrab /*
23*0baeff3dSrab  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24*0baeff3dSrab  * Use is subject to license terms.
25*0baeff3dSrab  */
26*0baeff3dSrab 
27*0baeff3dSrab #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0baeff3dSrab 
29*0baeff3dSrab #include <sys/proc.h>
30*0baeff3dSrab 
31*0baeff3dSrab /*
32*0baeff3dSrab  * Install process context ops for the current process.
33*0baeff3dSrab  */
34*0baeff3dSrab void
35*0baeff3dSrab installpctx(
36*0baeff3dSrab 	proc_t *p,
37*0baeff3dSrab 	void	*arg,
38*0baeff3dSrab 	void	(*save)(void *),
39*0baeff3dSrab 	void	(*restore)(void *),
40*0baeff3dSrab 	void	(*fork)(void *, void *),
41*0baeff3dSrab 	void	(*exit)(void *),
42*0baeff3dSrab 	void	(*free)(void *, int))
43*0baeff3dSrab {
44*0baeff3dSrab 	struct pctxop *pctx;
45*0baeff3dSrab 
46*0baeff3dSrab 	pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP);
47*0baeff3dSrab 	pctx->save_op = save;
48*0baeff3dSrab 	pctx->restore_op = restore;
49*0baeff3dSrab 	pctx->fork_op = fork;
50*0baeff3dSrab 	pctx->exit_op = exit;
51*0baeff3dSrab 	pctx->free_op = free;
52*0baeff3dSrab 	pctx->arg = arg;
53*0baeff3dSrab 	pctx->next = p->p_pctx;
54*0baeff3dSrab 	p->p_pctx = pctx;
55*0baeff3dSrab }
56*0baeff3dSrab 
57*0baeff3dSrab /*
58*0baeff3dSrab  * Remove a process context ops from the current process.
59*0baeff3dSrab  */
60*0baeff3dSrab int
61*0baeff3dSrab removepctx(
62*0baeff3dSrab 	proc_t *p,
63*0baeff3dSrab 	void	*arg,
64*0baeff3dSrab 	void	(*save)(void *),
65*0baeff3dSrab 	void	(*restore)(void *),
66*0baeff3dSrab 	void	(*fork)(void *, void *),
67*0baeff3dSrab 	void	(*exit)(void *),
68*0baeff3dSrab 	void	(*free)(void *, int))
69*0baeff3dSrab {
70*0baeff3dSrab 	struct pctxop *pctx, *prev_pctx;
71*0baeff3dSrab 
72*0baeff3dSrab 	prev_pctx = NULL;
73*0baeff3dSrab 	for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) {
74*0baeff3dSrab 		if (pctx->save_op == save && pctx->restore_op == restore &&
75*0baeff3dSrab 		    pctx->fork_op == fork &&
76*0baeff3dSrab 		    pctx->exit_op == exit && pctx->free_op == free &&
77*0baeff3dSrab 		    pctx->arg == arg) {
78*0baeff3dSrab 			if (prev_pctx)
79*0baeff3dSrab 				prev_pctx->next = pctx->next;
80*0baeff3dSrab 			else
81*0baeff3dSrab 				p->p_pctx = pctx->next;
82*0baeff3dSrab 			if (pctx->free_op != NULL)
83*0baeff3dSrab 				(pctx->free_op)(pctx->arg, 0);
84*0baeff3dSrab 			kmem_free(pctx, sizeof (struct pctxop));
85*0baeff3dSrab 			return (1);
86*0baeff3dSrab 		}
87*0baeff3dSrab 		prev_pctx = pctx;
88*0baeff3dSrab 	}
89*0baeff3dSrab 	return (0);
90*0baeff3dSrab }
91*0baeff3dSrab 
92*0baeff3dSrab void
93*0baeff3dSrab savepctx(proc_t *p)
94*0baeff3dSrab {
95*0baeff3dSrab 	struct pctxop *pctx;
96*0baeff3dSrab 
97*0baeff3dSrab 	ASSERT(p == curthread->t_procp);
98*0baeff3dSrab 	for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
99*0baeff3dSrab 		if (pctx->save_op != NULL)
100*0baeff3dSrab 			(pctx->save_op)(pctx->arg);
101*0baeff3dSrab }
102*0baeff3dSrab 
103*0baeff3dSrab void
104*0baeff3dSrab restorepctx(proc_t *p)
105*0baeff3dSrab {
106*0baeff3dSrab 	struct pctxop *pctx;
107*0baeff3dSrab 
108*0baeff3dSrab 	ASSERT(p == curthread->t_procp);
109*0baeff3dSrab 	for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
110*0baeff3dSrab 		if (pctx->restore_op != NULL)
111*0baeff3dSrab 			(pctx->restore_op)(pctx->arg);
112*0baeff3dSrab }
113*0baeff3dSrab 
114*0baeff3dSrab void
115*0baeff3dSrab forkpctx(proc_t *p, proc_t *cp)
116*0baeff3dSrab {
117*0baeff3dSrab 	struct pctxop *pctx;
118*0baeff3dSrab 
119*0baeff3dSrab 	for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
120*0baeff3dSrab 		if (pctx->fork_op != NULL)
121*0baeff3dSrab 			(pctx->fork_op)(p, cp);
122*0baeff3dSrab }
123*0baeff3dSrab 
124*0baeff3dSrab /*
125*0baeff3dSrab  * exitpctx is called during thread/lwp exit to perform any actions
126*0baeff3dSrab  * needed when an LWP in the process leaves the processor for the last
127*0baeff3dSrab  * time. This routine is not intended to deal with freeing memory; freepctx()
128*0baeff3dSrab  * is used for that purpose during proc_exit(). This routine is provided to
129*0baeff3dSrab  * allow for clean-up that can't wait until thread_free().
130*0baeff3dSrab  */
131*0baeff3dSrab void
132*0baeff3dSrab exitpctx(proc_t *p)
133*0baeff3dSrab {
134*0baeff3dSrab 	struct pctxop *pctx;
135*0baeff3dSrab 
136*0baeff3dSrab 	for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
137*0baeff3dSrab 		if (pctx->exit_op != NULL)
138*0baeff3dSrab 			(pctx->exit_op)(p);
139*0baeff3dSrab }
140*0baeff3dSrab 
141*0baeff3dSrab /*
142*0baeff3dSrab  * freepctx is called from proc_exit() to get rid of the actual context ops.
143*0baeff3dSrab  */
144*0baeff3dSrab void
145*0baeff3dSrab freepctx(proc_t *p, int isexec)
146*0baeff3dSrab {
147*0baeff3dSrab 	struct pctxop *pctx;
148*0baeff3dSrab 
149*0baeff3dSrab 	while ((pctx = p->p_pctx) != NULL) {
150*0baeff3dSrab 		p->p_pctx = pctx->next;
151*0baeff3dSrab 		if (pctx->free_op != NULL)
152*0baeff3dSrab 			(pctx->free_op)(pctx->arg, isexec);
153*0baeff3dSrab 		kmem_free(pctx, sizeof (struct pctxop));
154*0baeff3dSrab 	}
155*0baeff3dSrab }
156