view j2se/src/solaris/hpi/src/system_md.c @ 4:bf1d8af0651f trunk

[svn] Load openjdk/jdk7/b16 into jdk/trunk.
author xiomara
date Fri, 20 Jul 2007 21:22:05 +0000
parents a4ed3fb96592
children
line wrap: on
line source

/*
 * Copyright 1994-2004 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include "hpi_impl.h"

#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h> /* timeval */
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <netdb.h>
#include <limits.h>
#include <errno.h>

#include <dlfcn.h>

#include "jni_md.h"
#include "mutex_md.h"

#include "hpi_init.h"

#include "interrupt.h"
#include "threads_md.h"
#include "monitor_md.h"
#include "largefile.h"


#define O_DELETE 0x10000

int sysThreadBootstrap(sys_thread_t **tidP, sys_mon_t **lockP, int nb)
{
    threadBootstrapMD(tidP, lockP, nb);

    intrInit();

#ifndef NATIVE
    /* Initialize the special case for sbrk on Solaris (see synch.c) */
    InitializeSbrk();
    /* Initialize the async io */
    InitializeAsyncIO();
    InitializeMem();
    /* Initialize Clock and Idle threads */
    InitializeHelperThreads();
#else /* if NATIVE */
    initializeContentionCountMutex();
    InitializeMem();
#endif /* NATIVE */

    return SYS_OK;
}

int sysShutdown()
{
    return SYS_OK;
}

long
sysGetMilliTicks()
{
    struct timeval tv;

    (void) gettimeofday(&tv, (void *) 0);
    return((tv.tv_sec * 1000) + (tv.tv_usec / 1000));
}

jlong
sysTimeMillis()
{
    struct timeval t;
    gettimeofday(&t, 0);
    return ((jlong)t.tv_sec) * 1000 + (jlong)(t.tv_usec/1000);
}

int
sysGetLastErrorString(char *buf, int len)
{
    if (errno == 0) {
	return 0;
    } else {
	const char *s = strerror(errno);
	int n = strlen(s);
	if (n >= len) n = len - 1;
	strncpy(buf, s, n);
	buf[n] = '\0';
	return n;
    }
}

/*
 * File system
 *
 * These are all the sys API which implement the straight POSIX
 * API. Those that do not are defined by thread-specific files
 * (i.e. io_md.c)
 */

/*
 * Open a file. Unlink the file immediately after open returns
 * if the specified oflag has the O_DELETE flag set.
 */
int sysOpen(const char *path, int oflag, int mode)
{
    int fd;
    int delete = (oflag & O_DELETE);
    oflag = oflag & ~O_DELETE;
    fd = open64_w(path, oflag, mode);
    if (delete != 0) {
        unlink(path);
    }
    return fd;
}

char *sysNativePath(char *path)
{
    return path;
}

int
sysFileSizeFD(int fd, jlong *size)
{
    struct stat64 buf64;
    int ret = fstat64(fd, &buf64);
    *size = buf64.st_size;
    return ret;
}

int
sysFfileMode(int fd, int *mode)
{
    struct stat64 buf64;
    int ret = fstat64(fd, &buf64);
    (*mode) = buf64.st_mode;
    return ret;
}

int
sysFileType(const char *path)
{
    int ret;
    struct stat buf;

    if ((ret = stat(path, &buf)) == 0) {
      mode_t mode = buf.st_mode & S_IFMT;
      if (mode == S_IFREG) return SYS_FILETYPE_REGULAR;
      if (mode == S_IFDIR) return SYS_FILETYPE_DIRECTORY;
      return SYS_FILETYPE_OTHER;
    }
    return ret;
}

/*
 * Wrapper functions for low-level I/O routines - use the 64 bit
 * version if available, else revert to the 32 bit versions.
 */

off64_t
lseek64_w(int fd, off64_t offset, int whence)
{
    return lseek64(fd, offset, whence);
}

int
ftruncate64_w(int fd, off64_t length)
{
    return ftruncate64(fd, length);
}

int
open64_w(const char *path, int oflag, int mode)
{
    int fd = open64(path, oflag, mode);
    if (fd == -1) return -1;

    /* If the open succeeded, the file might still be a directory */
    {
	int st_mode;
	if (sysFfileMode(fd, &st_mode) != -1) {
	    if ((st_mode & S_IFMT) == S_IFDIR) {
		errno = EISDIR;
		close(fd);
		return -1;
	    }
	} else {
	    close(fd);
	    return -1;
	}
    }

    /*
     * 32-bit Solaris systems suffer from:
     *
     * - an historical default soft limit of 256 per-process file
     *   descriptors that is too low for many Java programs.
     *
     * - a design flaw where file descriptors created using stdio
     *   fopen must be less than 256, _even_ when the first limit above
     *   has been raised.  This can cause calls to fopen (but not calls to
     *   open, for example) to fail mysteriously, perhaps in 3rd party
     *   native code (although the JDK itself uses fopen).  One can hardly
     *   criticize them for using this most standard of all functions.
     *
     * We attempt to make everything work anyways by:
     *
     * - raising the soft limit on per-process file descriptors beyond
     *   256 (done by hotspot)
     *
     * - As of Solaris 10u4, we can request that Solaris raise the 256
     *   stdio fopen limit by calling function enable_extended_FILE_stdio,
     *   (also done by hotspot).  We check for its availability.
     *
     * - If we are stuck on an old (pre 10u4) Solaris system, we can
     *   workaround the bug by remapping non-stdio file descriptors below
     *   256 to ones beyond 256, which is done below.
     *
     * See:
     * 1085341: 32-bit stdio routines should support file descriptors >255
     * 6533291: Work around 32-bit Solaris stdio limit of 256 open files
     * 6431278: Netbeans crash on 32 bit Solaris: need to call
     *          enable_extended_FILE_stdio() in VM initialisation
     * Giri Mandalika's blog
     * http://technopark02.blogspot.com/2005_05_01_archive.html
     */
#if defined(__solaris__) && defined(_ILP32)
    {
	static int needToWorkAroundBug1085341 = -1;
	if (needToWorkAroundBug1085341) {
	    if (needToWorkAroundBug1085341 == -1)
		needToWorkAroundBug1085341 =
		    (dlsym(RTLD_DEFAULT, "enable_extended_FILE_stdio") == NULL);
	    if (needToWorkAroundBug1085341 && fd < 256) {
		int newfd = fcntl(fd, F_DUPFD, 256);
		if (newfd != -1) {
		    close(fd);
		    fd = newfd;
		}
	    }
	}
    }
#endif /* 32-bit Solaris */

    /*
     * All file descriptors that are opened in the JVM and not
     * specifically destined for a subprocess should have the
     * close-on-exec flag set.  If we don't set it, then careless 3rd
     * party native code might fork and exec without closing all
     * appropriate file descriptors (e.g. as we do in closeDescriptors in
     * UNIXProcess.c), and this in turn might:
     *
     * - cause end-of-file to fail to be detected on some file
     *   descriptors, resulting in mysterious hangs, or
     *
     * - might cause an fopen in the subprocess to fail on a system
     *   suffering from bug 1085341.
     *
     * (Yes, the default setting of the close-on-exec flag is a Unix
     * design flaw)
     *
     * See:
     * 1085341: 32-bit stdio routines should support file descriptors >255
     * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
     * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
     */
#ifdef FD_CLOEXEC
    {
	int flags = fcntl(fd, F_GETFD);
	if (flags != -1)
	    fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
    }
#endif
    return fd;
}

void setFPMode(void)
{
#if    defined(__amd64)
    asm("        pushq   $0x1F80");
    /* ldmxcsr (%rsp) */
    asm("        .byte   0x0f,0xae,0x14,0x24");
    asm("        popq    %rax");
#elif  defined(i386)
    asm("        pushl $575");
    asm("        fldcw (%esp)");
    asm("        popl %eax");
#endif
#if defined(__linux__) && defined(__mc68000__)
    asm("        fmovel #0x80,%fpcr");
#endif
}