umem_fork.c revision 1c326e9416070828d0deab52d9d27f7fd27aef7a
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "mtlib.h"
#include "umem_base.h"
#include "vmem_base.h"
#include <unistd.h>
/*
* The following functions are for pre- and post-fork1(2) handling. See
*/
static void
{
int idx;
}
static void
{
int idx;
}
static void
{
int idx;
return;
}
static void
{
int idx;
return;
}
static void
umem_lockup(void)
{
(void) mutex_lock(&umem_init_lock);
/*
* If another thread is busy initializing the library, we must
* wait for it to complete (by calling umem_init()) before allowing
* the fork() to proceed.
*/
(void) mutex_unlock(&umem_init_lock);
(void) umem_init();
(void) mutex_lock(&umem_init_lock);
}
vmem_lockup();
(void) mutex_lock(&umem_cache_lock);
(void) mutex_lock(&umem_update_lock);
(void) mutex_lock(&umem_flags_lock);
(void) cond_broadcast(&umem_update_cv);
}
static void
umem_do_release(int as_child)
{
int cleanup_update = 0;
/*
* Clean up the update state if we are the child process and
* another thread was processing updates.
*/
if (as_child) {
if (umem_update_thr != thr_self()) {
umem_update_thr = 0;
cleanup_update = 1;
}
if (umem_st_update_thr != thr_self()) {
umem_st_update_thr = 0;
cleanup_update = 1;
}
}
if (cleanup_update) {
/*
* If the cache is active, we just re-add it to
* the update list. This will re-do any active
* updates on the cache, but that won't break
* anything.
*
* The worst that can happen is a cache has
* its magazines rescaled twice, instead of once.
*/
}
}
}
(void) mutex_unlock(&umem_flags_lock);
(void) mutex_unlock(&umem_update_lock);
(void) mutex_unlock(&umem_cache_lock);
vmem_release();
(void) mutex_unlock(&umem_init_lock);
}
static void
umem_release(void)
{
umem_do_release(0);
}
static void
umem_release_child(void)
{
umem_do_release(1);
}
void
umem_forkhandler_init(void)
{
/*
* There is no way to unregister these atfork functions,
* but we don't need to. The dynamic linker and libc take
*/
}