/*
* 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
* or http://www.opensolaris.org/os/licensing.
* 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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdlib.h>
#include <sys/lgrp_user.h>
#include "jlgrp.h"
static lgrp_cookie_t getCookie(JNIEnv *, jclass, jobject);
static void throwException(JNIEnv *, const char *, const char *);
/*
* Return the output of the getCookie() method executed on the
* supplied instance.
*/
lgrp_cookie_t
getCookie(JNIEnv *env, jclass clazz, jobject obj)
{
jfieldID fid;
fid = (*env)->GetFieldID(env, clazz, "cookie", "J");
return ((lgrp_cookie_t)(*env)->GetLongField(env, obj, fid));
}
/*
* Throw an exception of the specified class with the specified message.
*/
void
throwException(JNIEnv *env, const char *class, const char *msg)
{
jclass clazz;
clazz = (*env)->FindClass(env, class);
(*env)->ThrowNew(env, clazz, msg);
}
/*
* Obtain an lgrp cookie for an lgrp snapshot which contains details
* about available resources that the operating system knows about.
*
* If the call fails, then throw an exception which indicates that the
* snapshot could not be obtained.
*/
/*ARGSUSED1*/
JNIEXPORT jlong JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init(JNIEnv *env,
jobject obj, jint view)
{
lgrp_cookie_t cookie;
if ((cookie = lgrp_init(view)) == LGRP_COOKIE_NONE) {
throwException(env, "java/lang/Exception",
"Could not obtain latency group cookie");
}
return ((jlong)cookie);
}
/*
* Release the snapshot in use by this instance. It is assumed that
* the cookie is held in the "cookie" field of the invoking instance
*/
JNIEXPORT jint JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini(JNIEnv *env,
jobject obj)
{
jclass clazz;
clazz = (*env)->GetObjectClass(env, obj);
return ((jint)lgrp_fini(getCookie(env, clazz, obj)));
}
/*
* Create a new LocalityGroup object which acts as a proxy for the
* root LocalityGroup.
*/
JNIEXPORT jobject JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root(JNIEnv *env,
jobject obj)
{
jclass clazz;
jmethodID mid;
jlong root;
jobject lgrp;
clazz = (*env)->GetObjectClass(env, obj);
root = (jlong) lgrp_root(getCookie(env, clazz, obj));
clazz = (*env)->FindClass(env, "com/sun/solaris/service/locality/"
"LocalityGroup");
mid = (*env)->GetMethodID(env, clazz, "<init>", "(Lcom/sun/solaris/"
"service/locality/LocalityDomain;JLcom/sun/solaris/service/"
"locality/LocalityGroup;)V");
lgrp = (*env)->NewObject(env, clazz, mid, obj, root, NULL);
return (lgrp);
}
/*
* Return a new array containing all of the child LocalityGroup ids
* for the supplied instance.
*/
JNIEXPORT jlongArray JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children(JNIEnv *env,
jobject obj)
{
jclass clazz;
jfieldID fid;
lgrp_cookie_t cookie;
jlong id;
jsize nchild0, nchild;
jlongArray children;
int i;
lgrp_id_t *native_child;
jlong *java_child;
jobject domain;
clazz = (*env)->GetObjectClass(env, obj);
fid = (*env)->GetFieldID(env, clazz, "domain",
"Lcom/sun/solaris/service/locality/LocalityDomain;");
domain = (*env)->GetObjectField(env, obj, fid);
cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
fid = (*env)->GetFieldID(env, clazz, "id", "J");
id = (*env)->GetLongField(env, obj, fid);
retry:
nchild0 = (jsize)lgrp_children(cookie, (lgrp_id_t)id, NULL, 0);
children = (*env)->NewLongArray(env, nchild0);
if ((native_child = calloc(nchild0, sizeof (lgrp_id_t))) == NULL) {
throwException(env, "java/lang/Exception",
"Could not allocate memory for native_child array");
return (NULL);
}
nchild = lgrp_children(cookie, (lgrp_id_t)id, native_child, nchild0);
if (nchild != nchild0) {
free(native_child);
goto retry;
}
if ((java_child = calloc(nchild, sizeof (jlong))) == NULL) {
throwException(env, "java/lang/Exception",
"Could not allocate memory for java_child array");
free(native_child);
return (NULL);
}
for (i = 0; i < nchild; i++)
java_child[i] = (jlong) native_child[i];
(*env)->SetLongArrayRegion(env, children, 0, nchild, java_child);
free(native_child);
free(java_child);
return (children);
}
/*
* Return a new array containing all of the cpus contained directly
* within the LocalityGroup identified by the supplied instance.
*/
JNIEXPORT jintArray JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus(JNIEnv *env,
jobject obj)
{
jclass clazz;
jfieldID fid;
lgrp_cookie_t cookie;
jlong id;
jsize ncpus0, ncpus;
jintArray cpus;
int i;
processorid_t *native_cpus;
jint *java_cpus;
jobject domain;
clazz = (*env)->GetObjectClass(env, obj);
fid = (*env)->GetFieldID(env, clazz, "domain",
"Lcom/sun/solaris/service/locality/LocalityDomain;");
domain = (*env)->GetObjectField(env, obj, fid);
cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
fid = (*env)->GetFieldID(env, clazz, "id", "J");
id = (*env)->GetLongField(env, obj, fid);
retry:
ncpus0 = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
NULL, 0, LGRP_CONTENT_DIRECT);
cpus = (*env)->NewIntArray(env, ncpus0);
if ((native_cpus = calloc(ncpus0, sizeof (processorid_t))) == NULL) {
throwException(env, "java/lang/Exception",
"Could not allocate memory for native_cpus array");
return (NULL);
}
ncpus = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
native_cpus, ncpus0, LGRP_CONTENT_DIRECT);
if (ncpus != ncpus0) {
free(native_cpus);
goto retry;
}
if ((java_cpus = calloc(ncpus, sizeof (jint))) == NULL) {
free(native_cpus);
throwException(env, "java/lang/Exception",
"Could not allocate memory for java_cpus array");
return (NULL);
}
for (i = 0; i < ncpus; i++)
java_cpus[i] = (jint)native_cpus[i];
(*env)->SetIntArrayRegion(env, cpus, 0, ncpus, java_cpus);
free(native_cpus);
free(java_cpus);
return (cpus);
}
/*
* Return the latency between two supplied latency group IDs.
*/
/*ARGSUSED*/
JNIEXPORT jint JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency(JNIEnv *env,
jobject obj, jlong from, jlong to)
{
return ((jint) lgrp_latency((lgrp_id_t)from, (lgrp_id_t)to));
}