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