1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #include <stdlib.h>
28 #include <sys/lgrp_user.h>
29 
30 #include "jlgrp.h"
31 
32 static lgrp_cookie_t getCookie(JNIEnv *, jclass, jobject);
33 static void throwException(JNIEnv *, const char *, const char *);
34 
35 /*
36  * Return the output of the getCookie() method executed on the
37  * supplied instance.
38  */
39 lgrp_cookie_t
getCookie(JNIEnv * env,jclass clazz,jobject obj)40 getCookie(JNIEnv *env, jclass clazz, jobject obj)
41 {
42 	jfieldID fid;
43 
44 	fid = (*env)->GetFieldID(env, clazz, "cookie", "J");
45 	return ((lgrp_cookie_t)(*env)->GetLongField(env, obj, fid));
46 }
47 
48 /*
49  * Throw an exception of the specified class with the specified message.
50  */
51 void
throwException(JNIEnv * env,const char * class,const char * msg)52 throwException(JNIEnv *env, const char *class, const char *msg)
53 {
54 	jclass clazz;
55 
56 	clazz = (*env)->FindClass(env, class);
57 
58 	(*env)->ThrowNew(env, clazz, msg);
59 }
60 
61 /*
62  * Obtain an lgrp cookie for an lgrp snapshot which contains details
63  * about available resources that the operating system knows about.
64  *
65  * If the call fails, then throw an exception which indicates that the
66  * snapshot could not be obtained.
67  */
68 /*ARGSUSED1*/
69 JNIEXPORT jlong JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init(JNIEnv * env,jobject obj,jint view)70 Java_com_sun_solaris_service_locality_LocalityDomain_jl_1init(JNIEnv *env,
71     jobject obj, jint view)
72 {
73 	lgrp_cookie_t cookie;
74 
75 	if ((cookie = lgrp_init(view)) == LGRP_COOKIE_NONE) {
76 		throwException(env, "java/lang/Exception",
77 		    "Could not obtain latency group cookie");
78 	}
79 
80 	return ((jlong)cookie);
81 }
82 
83 /*
84  * Release the snapshot in use by this instance. It is assumed that
85  * the cookie is held in the "cookie" field of the invoking instance
86  */
87 JNIEXPORT jint JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini(JNIEnv * env,jobject obj)88 Java_com_sun_solaris_service_locality_LocalityDomain_jl_1fini(JNIEnv *env,
89     jobject obj)
90 {
91 	jclass clazz;
92 
93 	clazz = (*env)->GetObjectClass(env, obj);
94 	return ((jint)lgrp_fini(getCookie(env, clazz, obj)));
95 }
96 
97 /*
98  * Create a new LocalityGroup object which acts as a proxy for the
99  * root LocalityGroup.
100  */
101 JNIEXPORT jobject JNICALL
Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root(JNIEnv * env,jobject obj)102 Java_com_sun_solaris_service_locality_LocalityDomain_jl_1root(JNIEnv *env,
103     jobject obj)
104 {
105 	jclass clazz;
106 	jmethodID mid;
107 	jlong root;
108 	jobject lgrp;
109 
110 	clazz = (*env)->GetObjectClass(env, obj);
111 
112 	root = (jlong) lgrp_root(getCookie(env, clazz, obj));
113 
114 	clazz = (*env)->FindClass(env, "com/sun/solaris/service/locality/"
115 	    "LocalityGroup");
116 	mid = (*env)->GetMethodID(env, clazz, "<init>", "(Lcom/sun/solaris/"
117 	    "service/locality/LocalityDomain;JLcom/sun/solaris/service/"
118 	    "locality/LocalityGroup;)V");
119 	lgrp = (*env)->NewObject(env, clazz, mid, obj, root, NULL);
120 	return (lgrp);
121 }
122 
123 /*
124  * Return a new array containing all of the child LocalityGroup ids
125  * for the supplied instance.
126  */
127 JNIEXPORT jlongArray JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children(JNIEnv * env,jobject obj)128 Java_com_sun_solaris_service_locality_LocalityGroup_jl_1children(JNIEnv *env,
129     jobject obj)
130 {
131 	jclass clazz;
132 	jfieldID fid;
133 	lgrp_cookie_t cookie;
134 	jlong id;
135 	jsize nchild0, nchild;
136 	jlongArray children;
137 	int i;
138 	lgrp_id_t *native_child;
139 	jlong *java_child;
140 	jobject domain;
141 
142 	clazz = (*env)->GetObjectClass(env, obj);
143 	fid = (*env)->GetFieldID(env, clazz, "domain",
144 	    "Lcom/sun/solaris/service/locality/LocalityDomain;");
145 	domain = (*env)->GetObjectField(env, obj, fid);
146 
147 	cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
148 	fid = (*env)->GetFieldID(env, clazz, "id", "J");
149 	id = (*env)->GetLongField(env, obj, fid);
150 retry:
151 	nchild0 = (jsize)lgrp_children(cookie, (lgrp_id_t)id, NULL, 0);
152 	children = (*env)->NewLongArray(env, nchild0);
153 	if ((native_child = calloc(nchild0, sizeof (lgrp_id_t))) == NULL) {
154 		throwException(env, "java/lang/Exception",
155 		    "Could not allocate memory for native_child array");
156 		return (NULL);
157 	}
158 	nchild = lgrp_children(cookie, (lgrp_id_t)id, native_child, nchild0);
159 	if (nchild != nchild0) {
160 		free(native_child);
161 		goto retry;
162 	}
163 
164 	if ((java_child = calloc(nchild, sizeof (jlong))) == NULL) {
165 		throwException(env, "java/lang/Exception",
166 		    "Could not allocate memory for java_child array");
167 		free(native_child);
168 		return (NULL);
169 	}
170 
171 	for (i = 0; i < nchild; i++)
172 		java_child[i] = (jlong) native_child[i];
173 	(*env)->SetLongArrayRegion(env, children, 0, nchild, java_child);
174 	free(native_child);
175 	free(java_child);
176 	return (children);
177 }
178 
179 /*
180  * Return a new array containing all of the cpus contained directly
181  * within the LocalityGroup identified by the supplied instance.
182  */
183 JNIEXPORT jintArray JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus(JNIEnv * env,jobject obj)184 Java_com_sun_solaris_service_locality_LocalityGroup_jl_1cpus(JNIEnv *env,
185     jobject obj)
186 {
187 	jclass clazz;
188 	jfieldID fid;
189 	lgrp_cookie_t cookie;
190 	jlong id;
191 	jsize ncpus0, ncpus;
192 	jintArray cpus;
193 	int i;
194 	processorid_t *native_cpus;
195 	jint *java_cpus;
196 	jobject domain;
197 
198 	clazz = (*env)->GetObjectClass(env, obj);
199 	fid = (*env)->GetFieldID(env, clazz, "domain",
200 	    "Lcom/sun/solaris/service/locality/LocalityDomain;");
201 	domain = (*env)->GetObjectField(env, obj, fid);
202 
203 	cookie = getCookie(env, (*env)->GetObjectClass(env, domain), domain);
204 
205 	fid = (*env)->GetFieldID(env, clazz, "id", "J");
206 	id = (*env)->GetLongField(env, obj, fid);
207 retry:
208 	ncpus0 = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
209 	    NULL, 0, LGRP_CONTENT_DIRECT);
210 	cpus = (*env)->NewIntArray(env, ncpus0);
211 	if ((native_cpus = calloc(ncpus0, sizeof (processorid_t))) == NULL) {
212 		throwException(env, "java/lang/Exception",
213 		    "Could not allocate memory for native_cpus array");
214 		return (NULL);
215 	}
216 	ncpus = (jsize)lgrp_cpus((lgrp_cookie_t)cookie, (lgrp_id_t)id,
217 	    native_cpus, ncpus0, LGRP_CONTENT_DIRECT);
218 	if (ncpus != ncpus0) {
219 		free(native_cpus);
220 		goto retry;
221 	}
222 
223 	if ((java_cpus = calloc(ncpus, sizeof (jint))) == NULL) {
224 		free(native_cpus);
225 		throwException(env, "java/lang/Exception",
226 		    "Could not allocate memory for java_cpus array");
227 		return (NULL);
228 	}
229 
230 	for (i = 0; i < ncpus; i++)
231 		java_cpus[i] = (jint)native_cpus[i];
232 	(*env)->SetIntArrayRegion(env, cpus, 0, ncpus, java_cpus);
233 	free(native_cpus);
234 	free(java_cpus);
235 	return (cpus);
236 }
237 
238 /*
239  * Return the latency between two supplied latency group IDs.
240  */
241 /*ARGSUSED*/
242 JNIEXPORT jint JNICALL
Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency(JNIEnv * env,jobject obj,jlong from,jlong to)243 Java_com_sun_solaris_service_locality_LocalityGroup_jl_1latency(JNIEnv *env,
244     jobject obj, jlong from, jlong to)
245 {
246 	return ((jint) lgrp_latency((lgrp_id_t)from, (lgrp_id_t)to));
247 }
248