/*
* 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
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* plock - lock "segments" in physical memory.
*
* Supports SVID-compatible plock, taking into account dynamically linked
* objects (such as shared libraries).
*/
#include "lint.h"
#include <mtlib.h>
#include <errno.h>
#include <stddef.h>
#include <unistd.h>
#include <thread.h>
#include <synch.h>
/*
* Module-scope variables.
*/
/*
* plock
*/
int
{
int e; /* return value */
/*
* Validate state of lock's. If parent has forked, then
* the lock state needs to be reset (children do not inherit
* memory locks, and thus do not inherit their state).
*/
lock_state = 0;
}
/*
* Dispatch on operation. Note: plock and its relatives depend
* upon "op" being bit encoded.
*/
switch (op) {
/*
* UNLOCK: remove all memory locks. Requires that some be set!
*/
case UNLOCK:
if (lock_state == 0) {
return (-1);
}
e = munlockall();
if (e) {
return (-1);
} else {
lock_state = 0;
return (0);
}
/*NOTREACHED*/
/*
* TXTLOCK: locks text segments.
*/
case TXTLOCK:
/*
* If a text or process lock is already set, then fail.
*/
return (-1);
}
/*
* Try to apply the lock(s). If a failure occurs,
* memcntl backs them out automatically.
*/
if (!e)
lock_state |= TXTLOCK;
return (e);
/*NOTREACHED*/
/*
* DATLOCK: locks data segment(s), including the stack and all
* future growth in the address space.
*/
case DATLOCK:
/*
* If a data or process lock is already set, then fail.
*/
return (-1);
}
/*
* Try to lock the data and stack segments. On failure
* memcntl undoes the locks internally.
*/
if (e) {
return (-1);
}
/* try to set a lock for all future mappings. */
e = mlockall(MCL_FUTURE);
/*
* If failures have occurred, back out the locks
* and return failure.
*/
if (e) {
e = errno;
errno = e;
return (-1);
}
/*
* Data, stack, and growth have been locked. Set state
* and return success.
*/
lock_state |= DATLOCK;
return (0);
/*NOTREACHED*/
/*
* PROCLOCK: lock everything, and all future things as well.
* There should be nothing locked when this is called.
*/
case PROCLOCK:
if (lock_state) {
return (-1);
}
lock_state |= PROCLOCK;
return (0);
} else {
return (-1);
}
/*NOTREACHED*/
/*
* Invalid operation.
*/
default:
return (-1);
/*NOTREACHED*/
}
}