├── .gitignore ├── Build.md ├── LICENSE ├── Makefile ├── README.md ├── bin └── sbt ├── include ├── jni.h └── jni_md.h ├── project ├── Build.scala └── plugins.sbt ├── src ├── main │ ├── java │ │ └── xerial │ │ │ └── jnuma │ │ │ ├── NoNuma.java │ │ │ ├── Numa.java │ │ │ ├── NumaInterface.java │ │ │ ├── NumaJNILoader.java │ │ │ ├── NumaNative.c │ │ │ ├── NumaNative.h │ │ │ └── NumaNative.java │ └── resources │ │ └── xerial │ │ └── jnuma │ │ └── native │ │ └── libjnuma.so └── test │ └── scala │ └── xerial │ └── jnuma │ ├── MySpec.scala │ └── NumaTest.scala └── version.sbt /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | *~ 4 | 5 | # sbt specific 6 | bin/.lib 7 | dist/* 8 | target/ 9 | lib_managed/ 10 | src_managed/ 11 | project/boot/ 12 | project/plugins/project/ 13 | 14 | # Scala-IDE specific 15 | .scala_dependencies 16 | 17 | # IntelliJ specific 18 | .idea* 19 | -------------------------------------------------------------------------------- /Build.md: -------------------------------------------------------------------------------- 1 | 2 | # Building jnuma 3 | 4 | ## Requirements 5 | 6 | * libnuma (install by `yum numactl-devel`) 7 | * GCC (glibc 2.5 or higher) 8 | * JDK (1.5 or higher) 9 | 10 | ## Building a native library 11 | 12 | $ make native 13 | 14 | ## Create a JAR package 15 | 16 | $ bin/sbt package 17 | 18 | 19 | ## Install jnuma to local package directory 20 | 21 | $ bin/sbt publish-local 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | 3 | SRC:=src/main/java 4 | TARGET:=target 5 | 6 | CC:=gcc 7 | 8 | jniheader: $(SRC)/xerial/jnuma/NumaNative.h 9 | 10 | compile: $(wildcard $(SRC)/xerial/jnuma/*.java) 11 | bin/sbt compile 12 | 13 | native: src/main/resources/xerial/jnuma/native/libjnuma.so 14 | 15 | $(SRC)/xerial/jnuma/NumaNative.h: $(SRC)/xerial/jnuma/NumaNative.java compile 16 | javah -classpath $(TARGET)/classes -o $@ xerial.jnuma.NumaNative 17 | 18 | $(TARGET)/lib/NumaNative.o : $(SRC)/xerial/jnuma/NumaNative.c 19 | @mkdir -p $(@D) 20 | $(CC) -O2 -fPIC -m64 -I include -I $(SRC)/xerial/jnuma -c $< -o $@ 21 | 22 | $(TARGET)/lib/libjnuma.so : $(TARGET)/lib/NumaNative.o 23 | $(CC) -Wl -O2 -fPIC -m64 -L/usr/lib64 -lnuma -o $@ $+ -shared -static-libgcc 24 | strip $@ 25 | 26 | src/main/resources/xerial/jnuma/native/libjnuma.so : $(TARGET)/lib/libjnuma.so 27 | @mkdir -p $(@D) 28 | cp $< $@ 29 | 30 | clean-native: 31 | rm -f $(TARGET)/lib/* 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jnuma 2 | ========= 3 | 4 | A Java library for accessing NUMA (Non Uniform Memory Access) API. 5 | 6 | ## Usage 7 | 8 | (Scala) Add depedency settings to your sbt project file (e.g., `project/build.sbt`) : 9 | 10 | libraryDependencies += "org.xerial" % "jnuma" % "0.1.3" 11 | 12 | (Java) Add maven dependency settings for using `org.xerial, jnuma, 0.1.3` 13 | 14 | #### Using snapshot versions 15 | Add a resolver setting to your project file: 16 | 17 | resolvers += "Sonatype snapshot repo" at "https://oss.sonatype.org/content/repositories/snapshots/" 18 | 19 | ## API 20 | 21 | Call static methods defined in [xerial.jnuma.Numa](https://oss.sonatype.org/service/local/repositories/releases/archive/org/xerial/jnuma/0.1.3/jnuma-0.1.3-javadoc.jar/!/xerial/jnuma/Numa.html) 22 | 23 | ## limitation 24 | 25 | Currenty jnuma supports 64-bit Linux only. For the other operating systems, standard memory allocation in JVM will be used. 26 | 27 | 28 | -------------------------------------------------------------------------------- /bin/sbt: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # 3 | # A more capable sbt runner, coincidentally also called sbt. 4 | # Author: Paul Phillips 5 | 6 | # this seems to cover the bases on OSX, and someone will 7 | # have to tell me about the others. 8 | get_script_path () { 9 | local path="$1" 10 | [[ -L "$path" ]] || { echo "$path" ; return; } 11 | 12 | local target=$(readlink "$path") 13 | if [[ "${target:0:1}" == "/" ]]; then 14 | echo "$target" 15 | else 16 | echo "$path/$target" 17 | fi 18 | } 19 | 20 | # a ham-fisted attempt to move some memory settings in concert 21 | # so they need not be dicked around with individually. 22 | get_mem_opts () { 23 | local mem=${1:-1536} 24 | local perm=$(( $mem / 4 )) 25 | (( $perm > 256 )) || perm=256 26 | (( $perm < 1024 )) || perm=1024 27 | local codecache=$(( $perm / 2 )) 28 | 29 | echo "-Xms${mem}m -Xmx${mem}m -XX:MaxPermSize=${perm}m -XX:ReservedCodeCacheSize=${codecache}m" 30 | } 31 | 32 | die() { 33 | echo "Aborting: $@" 34 | exit 1 35 | } 36 | 37 | # todo - make this dynamic 38 | declare -r sbt_release_version=0.12.2 39 | unset sbt_rc_version 40 | declare -r sbt_rc_version=0.12.2 41 | declare -r sbt_snapshot_version=0.13.0-SNAPSHOT 42 | declare -r sbt_snapshot_baseurl="http://typesafe.artifactoryonline.com/typesafe/ivy-snapshots/org.scala-sbt/sbt-launch/" 43 | 44 | declare default_jvm_opts="-Dfile.encoding=UTF8" 45 | declare -r default_sbt_opts="-XX:+CMSClassUnloadingEnabled " 46 | declare -r default_sbt_mem=1536 47 | declare -r noshare_opts="-Dsbt.global.base=project/.sbtboot -Dsbt.boot.directory=project/.boot -Dsbt.ivy.home=project/.ivy" 48 | declare -r sbt_opts_file=".sbtopts" 49 | declare -r jvm_opts_file=".jvmopts" 50 | declare -r latest_28="2.8.2" 51 | declare -r latest_29="2.9.2" 52 | declare -r latest_210="2.10.0" 53 | 54 | declare -r script_path=$(get_script_path "$BASH_SOURCE") 55 | 56 | 57 | declare -r script_dir="$(dirname $script_path)" 58 | declare -r script_name="$(basename $script_path)" 59 | 60 | declare java_cmd=java 61 | declare sbt_mem=$default_sbt_mem 62 | 63 | unset sbt_jar sbt_dir sbt_tmpdir sbt_create sbt_version sbt_snapshot 64 | unset scala_version 65 | unset java_home 66 | unset verbose debug quiet 67 | 68 | # pull -J and -D options to give to java. 69 | declare -a residual_args 70 | declare -a java_args 71 | declare -a scalac_args 72 | declare -a sbt_commands 73 | 74 | build_props_sbt () { 75 | if [[ -f project/build.properties ]]; then 76 | versionLine=$(grep ^sbt.version project/build.properties) 77 | versionString=${versionLine##sbt.version=} 78 | echo "$versionString" 79 | fi 80 | } 81 | build_props_scala () { 82 | if [[ -f project/build.properties ]]; then 83 | versionLine=$(grep ^build.scala.versions project/build.properties) 84 | versionString=${versionLine##build.scala.versions=} 85 | echo ${versionString%% .*} 86 | fi 87 | } 88 | 89 | isSnapshot () { 90 | [[ "$sbt_version" = *-SNAPSHOT* ]] 91 | } 92 | isRC () { 93 | [[ "$sbt_version" = *-RC* ]] 94 | } 95 | 96 | execRunner () { 97 | # print the arguments one to a line, quoting any containing spaces 98 | [[ $verbose || $debug ]] && echo "# Executing command line:" && { 99 | for arg; do 100 | if printf "%s\n" "$arg" | grep -q ' '; then 101 | printf "\"%s\"\n" "$arg" 102 | else 103 | printf "%s\n" "$arg" 104 | fi 105 | done 106 | echo "" 107 | } 108 | 109 | exec "$@" 110 | } 111 | 112 | echoerr () { 113 | echo 1>&2 "$@" 114 | } 115 | vlog () { 116 | [[ $verbose || $debug ]] && echoerr "$@" 117 | } 118 | dlog () { 119 | [[ $debug ]] && echoerr "$@" 120 | } 121 | 122 | sbtjar_07_url () { 123 | echo "http://simple-build-tool.googlecode.com/files/sbt-launch-${1}.jar" 124 | } 125 | sbtjar_release_url () { 126 | echo "http://typesafe.artifactoryonline.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/$sbt_version/sbt-launch.jar" 127 | } 128 | sbtjar_snapshot_url () { 129 | local ver="$sbt_version" 130 | echoerr "sbt version: $sbt_version" 131 | if [[ "$sbt_version" = *-SNAPSHOT ]]; then 132 | ver=$(sbt_snapshot_actual_version -SNAPSHOT) 133 | echoerr "sbt snapshot is $ver" 134 | elif [[ "$sbt_version" = *-SNAPSHOT ]]; then 135 | ver=$(sbt_snapshot_actual_version -RC) 136 | echoerr "sbt rc is $ver" 137 | fi 138 | 139 | echo "${sbt_snapshot_baseurl}${ver}/sbt-launch.jar" 140 | } 141 | jar_url () { 142 | case $sbt_version in 143 | 0.7.4*) sbtjar_07_url 0.7.4 ;; 144 | 0.7.5*) sbtjar_07_url 0.7.5 ;; 145 | 0.7.7*) sbtjar_07_url 0.7.7 ;; 146 | 0.7.*) sbtjar_07_url 0.7.7 ;; 147 | *-SNAPSHOT*) sbtjar_snapshot_url ;; 148 | *-RC*) sbtjar_release_url ;; 149 | *) sbtjar_release_url ;; 150 | esac 151 | } 152 | 153 | jar_file () { 154 | echo "$script_dir/.lib/$1/sbt-launch.jar" 155 | } 156 | 157 | sbt_artifactory_list () { 158 | local type="$1" # -RC or -SNAPSHOT 159 | local version=${sbt_version%-SNAPSHOT} 160 | 161 | curl -s --list-only "$sbt_snapshot_baseurl" | \ 162 | grep -F $version | \ 163 | perl -e 'print reverse <>' | \ 164 | perl -pe 's#^/dev/null 174 | dlog "curl returned: $?" 175 | echo "$ver" 176 | return 177 | done 178 | } 179 | 180 | download_url () { 181 | local url="$1" 182 | local jar="$2" 183 | 184 | echo "Downloading sbt launcher $sbt_version:" 185 | echo " From $url" 186 | echo " To $jar" 187 | 188 | mkdir -p $(dirname "$jar") && { 189 | if which curl >/dev/null; then 190 | curl --silent "$url" --output "$jar" 191 | elif which wget >/dev/null; then 192 | wget --quiet -O "$jar" "$url" 193 | fi 194 | } && [[ -f "$jar" ]] 195 | } 196 | 197 | acquire_sbt_jar () { 198 | if [[ $sbt_snapshot ]]; then 199 | sbt_version=$sbt_snapshot_version 200 | elif [[ ! $sbt_version ]]; then 201 | sbt_version=$sbt_release_version 202 | fi 203 | 204 | sbt_url="$(jar_url)" 205 | sbt_jar="$(jar_file $sbt_version)" 206 | 207 | [[ -f "$sbt_jar" ]] || download_url "$sbt_url" "$sbt_jar" 208 | } 209 | 210 | 211 | usage () { 212 | cat < path to global settings/plugins directory (default: ~/.sbt/) 222 | -sbt-boot path to shared boot directory (default: ~/.sbt/boot in 0.11 series) 223 | -ivy path to local Ivy repository (default: ~/.ivy2) 224 | -mem set memory options (default: $sbt_mem, which is $(get_mem_opts $sbt_mem)) 225 | -no-share use all local caches; no sharing 226 | -offline put sbt in offline mode 227 | -jvm-debug Turn on JVM debugging, open at the given port. 228 | -batch Disable interactive mode 229 | 230 | # sbt version (default: from project/build.properties if present, else latest release) 231 | -sbt-version use the specified version of sbt 232 | -sbt-jar use the specified jar as the sbt launcher 233 | -sbt-rc use an RC version of sbt 234 | -sbt-snapshot use a snapshot version of sbt 235 | 236 | # scala version (default: latest release) 237 | -28 use $latest_28 238 | -29 use $latest_29 239 | -210 use $latest_210 240 | -scala-home use the scala build at the specified directory 241 | -scala-version use the specified version of scala 242 | 243 | # java version (default: java from PATH, currently $(java -version |& grep version)) 244 | -java-home alternate JAVA_HOME 245 | 246 | # jvm options and output control 247 | JAVA_OPTS environment variable holding jvm args, if unset uses "$default_jvm_opts" 248 | SBT_OPTS environment variable holding jvm args, if unset uses "$default_sbt_opts" 249 | .jvmopts if file is in sbt root, it is prepended to the args given to the jvm 250 | .sbtopts if file is in sbt root, it is prepended to the args given to **sbt** 251 | -Dkey=val pass -Dkey=val directly to the jvm 252 | -J-X pass option -X directly to the jvm (-J is stripped) 253 | -S-X add -X to sbt's scalacOptions (-J is stripped) 254 | 255 | In the case of duplicated or conflicting options, the order above 256 | shows precedence: JAVA_OPTS lowest, command line options highest. 257 | EOM 258 | } 259 | 260 | addJava () { 261 | dlog "[addJava] arg = '$1'" 262 | java_args=( "${java_args[@]}" "$1" ) 263 | } 264 | addSbt () { 265 | dlog "[addSbt] arg = '$1'" 266 | sbt_commands=( "${sbt_commands[@]}" "$1" ) 267 | } 268 | addScalac () { 269 | dlog "[addScalac] arg = '$1'" 270 | scalac_args=( "${scalac_args[@]}" "$1" ) 271 | } 272 | addResidual () { 273 | dlog "[residual] arg = '$1'" 274 | residual_args=( "${residual_args[@]}" "$1" ) 275 | } 276 | addResolver () { 277 | addSbt "set resolvers in ThisBuild += $1" 278 | } 279 | unset addedSnapshotRepo 280 | addSnapshotRepo () { 281 | [[ -n "$addedSnapshotRepo" ]] || addResolver "ScalaToolsSnapshots" && addedSnapshotRepo=true 282 | } 283 | addDebugger () { 284 | addJava "-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=$1" 285 | } 286 | get_jvm_opts () { 287 | # echo "${JAVA_OPTS:-$default_jvm_opts}" 288 | # echo "${SBT_OPTS:-$default_sbt_opts}" 289 | 290 | [[ -f "$jvm_opts_file" ]] && cat "$jvm_opts_file" 291 | } 292 | 293 | process_args () 294 | { 295 | require_arg () { 296 | local type="$1" 297 | local opt="$2" 298 | local arg="$3" 299 | 300 | if [[ -z "$arg" ]] || [[ "${arg:0:1}" == "-" ]]; then 301 | die "$opt requires <$type> argument" 302 | fi 303 | } 304 | while [[ $# -gt 0 ]]; do 305 | case "$1" in 306 | -h|-help) usage; exit 1 ;; 307 | -v|-verbose) verbose=1 && shift ;; 308 | -d|-debug) debug=1 && shift ;; 309 | -q|-quiet) quiet=1 && shift ;; 310 | # -u|-upgrade) addSbt 'set sbt.version 0.7.7' ; addSbt reload && shift ;; 311 | 312 | -ivy) require_arg path "$1" "$2" && addJava "-Dsbt.ivy.home=$2" && shift 2 ;; 313 | -mem) require_arg integer "$1" "$2" && sbt_mem="$2" && shift 2 ;; 314 | -no-colors) addJava "-Dsbt.log.noformat=true" && shift ;; 315 | -no-share) addJava "$noshare_opts" && shift ;; 316 | -sbt-boot) require_arg path "$1" "$2" && addJava "-Dsbt.boot.directory=$2" && shift 2 ;; 317 | -sbt-dir) require_arg path "$1" "$2" && sbt_dir="$2" && shift 2 ;; 318 | -debug-inc) addJava "-Dxsbt.inc.debug=true" && shift ;; 319 | -offline) addSbt "set offline := true" && shift ;; 320 | -jvm-debug) require_arg port "$1" "$2" && addDebugger $2 && shift 2 ;; 321 | -batch) exec 0 )) || echo "Starting $script_name: invoke with -help for other options" 383 | 384 | # verify this is an sbt dir or -create was given 385 | [[ -f ./build.sbt || -d ./project || -n "$sbt_create" ]] || { 386 | cat < /dev/null 2>&1 427 | "$java_cmd" \ 428 | $(get_mem_opts $sbt_mem) \ 429 | $(get_jvm_opts) \ 430 | -Dcom.sun.management.jmxremote \ 431 | ${JAVA_OPTS:-$default_jvm_opts} \ 432 | ${extra_jvm_opts} \ 433 | ${java_args[@]} \ 434 | -jar "$sbt_jar" \ 435 | "${sbt_commands[@]}" \ 436 | "${residual_args[@]}" 437 | stty icanon echo > /dev/null 2>&1 438 | 439 | -------------------------------------------------------------------------------- /include/jni.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 2006, Oracle and/or its affiliates. All rights reserved. 3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 | * 5 | * 6 | * 7 | * 8 | * 9 | * 10 | * 11 | * 12 | * 13 | * 14 | * 15 | * 16 | * 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * 23 | * 24 | */ 25 | 26 | /* 27 | * We used part of Netscape's Java Runtime Interface (JRI) as the starting 28 | * point of our design and implementation. 29 | */ 30 | 31 | /****************************************************************************** 32 | * Java Runtime Interface 33 | * Copyright (c) 1996 Netscape Communications Corporation. All rights reserved. 34 | *****************************************************************************/ 35 | 36 | #ifndef _JAVASOFT_JNI_H_ 37 | #define _JAVASOFT_JNI_H_ 38 | 39 | #include 40 | #include 41 | 42 | /* jni_md.h contains the machine-dependent typedefs for jbyte, jint 43 | and jlong */ 44 | 45 | #include "jni_md.h" 46 | 47 | #ifdef __cplusplus 48 | extern "C" { 49 | #endif 50 | 51 | /* 52 | * JNI Types 53 | */ 54 | 55 | #ifndef JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H 56 | 57 | typedef unsigned char jboolean; 58 | typedef unsigned short jchar; 59 | typedef short jshort; 60 | typedef float jfloat; 61 | typedef double jdouble; 62 | 63 | typedef jint jsize; 64 | 65 | #ifdef __cplusplus 66 | 67 | class _jobject {}; 68 | class _jclass : public _jobject {}; 69 | class _jthrowable : public _jobject {}; 70 | class _jstring : public _jobject {}; 71 | class _jarray : public _jobject {}; 72 | class _jbooleanArray : public _jarray {}; 73 | class _jbyteArray : public _jarray {}; 74 | class _jcharArray : public _jarray {}; 75 | class _jshortArray : public _jarray {}; 76 | class _jintArray : public _jarray {}; 77 | class _jlongArray : public _jarray {}; 78 | class _jfloatArray : public _jarray {}; 79 | class _jdoubleArray : public _jarray {}; 80 | class _jobjectArray : public _jarray {}; 81 | 82 | typedef _jobject *jobject; 83 | typedef _jclass *jclass; 84 | typedef _jthrowable *jthrowable; 85 | typedef _jstring *jstring; 86 | typedef _jarray *jarray; 87 | typedef _jbooleanArray *jbooleanArray; 88 | typedef _jbyteArray *jbyteArray; 89 | typedef _jcharArray *jcharArray; 90 | typedef _jshortArray *jshortArray; 91 | typedef _jintArray *jintArray; 92 | typedef _jlongArray *jlongArray; 93 | typedef _jfloatArray *jfloatArray; 94 | typedef _jdoubleArray *jdoubleArray; 95 | typedef _jobjectArray *jobjectArray; 96 | 97 | #else 98 | 99 | struct _jobject; 100 | 101 | typedef struct _jobject *jobject; 102 | typedef jobject jclass; 103 | typedef jobject jthrowable; 104 | typedef jobject jstring; 105 | typedef jobject jarray; 106 | typedef jarray jbooleanArray; 107 | typedef jarray jbyteArray; 108 | typedef jarray jcharArray; 109 | typedef jarray jshortArray; 110 | typedef jarray jintArray; 111 | typedef jarray jlongArray; 112 | typedef jarray jfloatArray; 113 | typedef jarray jdoubleArray; 114 | typedef jarray jobjectArray; 115 | 116 | #endif 117 | 118 | typedef jobject jweak; 119 | 120 | typedef union jvalue { 121 | jboolean z; 122 | jbyte b; 123 | jchar c; 124 | jshort s; 125 | jint i; 126 | jlong j; 127 | jfloat f; 128 | jdouble d; 129 | jobject l; 130 | } jvalue; 131 | 132 | struct _jfieldID; 133 | typedef struct _jfieldID *jfieldID; 134 | 135 | struct _jmethodID; 136 | typedef struct _jmethodID *jmethodID; 137 | 138 | /* Return values from jobjectRefType */ 139 | typedef enum _jobjectType { 140 | JNIInvalidRefType = 0, 141 | JNILocalRefType = 1, 142 | JNIGlobalRefType = 2, 143 | JNIWeakGlobalRefType = 3 144 | } jobjectRefType; 145 | 146 | 147 | #endif /* JNI_TYPES_ALREADY_DEFINED_IN_JNI_MD_H */ 148 | 149 | /* 150 | * jboolean constants 151 | */ 152 | 153 | #define JNI_FALSE 0 154 | #define JNI_TRUE 1 155 | 156 | /* 157 | * possible return values for JNI functions. 158 | */ 159 | 160 | #define JNI_OK 0 /* success */ 161 | #define JNI_ERR (-1) /* unknown error */ 162 | #define JNI_EDETACHED (-2) /* thread detached from the VM */ 163 | #define JNI_EVERSION (-3) /* JNI version error */ 164 | #define JNI_ENOMEM (-4) /* not enough memory */ 165 | #define JNI_EEXIST (-5) /* VM already created */ 166 | #define JNI_EINVAL (-6) /* invalid arguments */ 167 | 168 | /* 169 | * used in ReleaseScalarArrayElements 170 | */ 171 | 172 | #define JNI_COMMIT 1 173 | #define JNI_ABORT 2 174 | 175 | /* 176 | * used in RegisterNatives to describe native method name, signature, 177 | * and function pointer. 178 | */ 179 | 180 | typedef struct { 181 | char *name; 182 | char *signature; 183 | void *fnPtr; 184 | } JNINativeMethod; 185 | 186 | /* 187 | * JNI Native Method Interface. 188 | */ 189 | 190 | struct JNINativeInterface_; 191 | 192 | struct JNIEnv_; 193 | 194 | #ifdef __cplusplus 195 | typedef JNIEnv_ JNIEnv; 196 | #else 197 | typedef const struct JNINativeInterface_ *JNIEnv; 198 | #endif 199 | 200 | /* 201 | * JNI Invocation Interface. 202 | */ 203 | 204 | struct JNIInvokeInterface_; 205 | 206 | struct JavaVM_; 207 | 208 | #ifdef __cplusplus 209 | typedef JavaVM_ JavaVM; 210 | #else 211 | typedef const struct JNIInvokeInterface_ *JavaVM; 212 | #endif 213 | 214 | struct JNINativeInterface_ { 215 | void *reserved0; 216 | void *reserved1; 217 | void *reserved2; 218 | 219 | void *reserved3; 220 | jint (JNICALL *GetVersion)(JNIEnv *env); 221 | 222 | jclass (JNICALL *DefineClass) 223 | (JNIEnv *env, const char *name, jobject loader, const jbyte *buf, 224 | jsize len); 225 | jclass (JNICALL *FindClass) 226 | (JNIEnv *env, const char *name); 227 | 228 | jmethodID (JNICALL *FromReflectedMethod) 229 | (JNIEnv *env, jobject method); 230 | jfieldID (JNICALL *FromReflectedField) 231 | (JNIEnv *env, jobject field); 232 | 233 | jobject (JNICALL *ToReflectedMethod) 234 | (JNIEnv *env, jclass cls, jmethodID methodID, jboolean isStatic); 235 | 236 | jclass (JNICALL *GetSuperclass) 237 | (JNIEnv *env, jclass sub); 238 | jboolean (JNICALL *IsAssignableFrom) 239 | (JNIEnv *env, jclass sub, jclass sup); 240 | 241 | jobject (JNICALL *ToReflectedField) 242 | (JNIEnv *env, jclass cls, jfieldID fieldID, jboolean isStatic); 243 | 244 | jint (JNICALL *Throw) 245 | (JNIEnv *env, jthrowable obj); 246 | jint (JNICALL *ThrowNew) 247 | (JNIEnv *env, jclass clazz, const char *msg); 248 | jthrowable (JNICALL *ExceptionOccurred) 249 | (JNIEnv *env); 250 | void (JNICALL *ExceptionDescribe) 251 | (JNIEnv *env); 252 | void (JNICALL *ExceptionClear) 253 | (JNIEnv *env); 254 | void (JNICALL *FatalError) 255 | (JNIEnv *env, const char *msg); 256 | 257 | jint (JNICALL *PushLocalFrame) 258 | (JNIEnv *env, jint capacity); 259 | jobject (JNICALL *PopLocalFrame) 260 | (JNIEnv *env, jobject result); 261 | 262 | jobject (JNICALL *NewGlobalRef) 263 | (JNIEnv *env, jobject lobj); 264 | void (JNICALL *DeleteGlobalRef) 265 | (JNIEnv *env, jobject gref); 266 | void (JNICALL *DeleteLocalRef) 267 | (JNIEnv *env, jobject obj); 268 | jboolean (JNICALL *IsSameObject) 269 | (JNIEnv *env, jobject obj1, jobject obj2); 270 | jobject (JNICALL *NewLocalRef) 271 | (JNIEnv *env, jobject ref); 272 | jint (JNICALL *EnsureLocalCapacity) 273 | (JNIEnv *env, jint capacity); 274 | 275 | jobject (JNICALL *AllocObject) 276 | (JNIEnv *env, jclass clazz); 277 | jobject (JNICALL *NewObject) 278 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 279 | jobject (JNICALL *NewObjectV) 280 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 281 | jobject (JNICALL *NewObjectA) 282 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 283 | 284 | jclass (JNICALL *GetObjectClass) 285 | (JNIEnv *env, jobject obj); 286 | jboolean (JNICALL *IsInstanceOf) 287 | (JNIEnv *env, jobject obj, jclass clazz); 288 | 289 | jmethodID (JNICALL *GetMethodID) 290 | (JNIEnv *env, jclass clazz, const char *name, const char *sig); 291 | 292 | jobject (JNICALL *CallObjectMethod) 293 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 294 | jobject (JNICALL *CallObjectMethodV) 295 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 296 | jobject (JNICALL *CallObjectMethodA) 297 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); 298 | 299 | jboolean (JNICALL *CallBooleanMethod) 300 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 301 | jboolean (JNICALL *CallBooleanMethodV) 302 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 303 | jboolean (JNICALL *CallBooleanMethodA) 304 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); 305 | 306 | jbyte (JNICALL *CallByteMethod) 307 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 308 | jbyte (JNICALL *CallByteMethodV) 309 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 310 | jbyte (JNICALL *CallByteMethodA) 311 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 312 | 313 | jchar (JNICALL *CallCharMethod) 314 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 315 | jchar (JNICALL *CallCharMethodV) 316 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 317 | jchar (JNICALL *CallCharMethodA) 318 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 319 | 320 | jshort (JNICALL *CallShortMethod) 321 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 322 | jshort (JNICALL *CallShortMethodV) 323 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 324 | jshort (JNICALL *CallShortMethodA) 325 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 326 | 327 | jint (JNICALL *CallIntMethod) 328 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 329 | jint (JNICALL *CallIntMethodV) 330 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 331 | jint (JNICALL *CallIntMethodA) 332 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 333 | 334 | jlong (JNICALL *CallLongMethod) 335 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 336 | jlong (JNICALL *CallLongMethodV) 337 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 338 | jlong (JNICALL *CallLongMethodA) 339 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 340 | 341 | jfloat (JNICALL *CallFloatMethod) 342 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 343 | jfloat (JNICALL *CallFloatMethodV) 344 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 345 | jfloat (JNICALL *CallFloatMethodA) 346 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 347 | 348 | jdouble (JNICALL *CallDoubleMethod) 349 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 350 | jdouble (JNICALL *CallDoubleMethodV) 351 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 352 | jdouble (JNICALL *CallDoubleMethodA) 353 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue *args); 354 | 355 | void (JNICALL *CallVoidMethod) 356 | (JNIEnv *env, jobject obj, jmethodID methodID, ...); 357 | void (JNICALL *CallVoidMethodV) 358 | (JNIEnv *env, jobject obj, jmethodID methodID, va_list args); 359 | void (JNICALL *CallVoidMethodA) 360 | (JNIEnv *env, jobject obj, jmethodID methodID, const jvalue * args); 361 | 362 | jobject (JNICALL *CallNonvirtualObjectMethod) 363 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 364 | jobject (JNICALL *CallNonvirtualObjectMethodV) 365 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 366 | va_list args); 367 | jobject (JNICALL *CallNonvirtualObjectMethodA) 368 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 369 | const jvalue * args); 370 | 371 | jboolean (JNICALL *CallNonvirtualBooleanMethod) 372 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 373 | jboolean (JNICALL *CallNonvirtualBooleanMethodV) 374 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 375 | va_list args); 376 | jboolean (JNICALL *CallNonvirtualBooleanMethodA) 377 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 378 | const jvalue * args); 379 | 380 | jbyte (JNICALL *CallNonvirtualByteMethod) 381 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 382 | jbyte (JNICALL *CallNonvirtualByteMethodV) 383 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 384 | va_list args); 385 | jbyte (JNICALL *CallNonvirtualByteMethodA) 386 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 387 | const jvalue *args); 388 | 389 | jchar (JNICALL *CallNonvirtualCharMethod) 390 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 391 | jchar (JNICALL *CallNonvirtualCharMethodV) 392 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 393 | va_list args); 394 | jchar (JNICALL *CallNonvirtualCharMethodA) 395 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 396 | const jvalue *args); 397 | 398 | jshort (JNICALL *CallNonvirtualShortMethod) 399 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 400 | jshort (JNICALL *CallNonvirtualShortMethodV) 401 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 402 | va_list args); 403 | jshort (JNICALL *CallNonvirtualShortMethodA) 404 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 405 | const jvalue *args); 406 | 407 | jint (JNICALL *CallNonvirtualIntMethod) 408 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 409 | jint (JNICALL *CallNonvirtualIntMethodV) 410 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 411 | va_list args); 412 | jint (JNICALL *CallNonvirtualIntMethodA) 413 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 414 | const jvalue *args); 415 | 416 | jlong (JNICALL *CallNonvirtualLongMethod) 417 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 418 | jlong (JNICALL *CallNonvirtualLongMethodV) 419 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 420 | va_list args); 421 | jlong (JNICALL *CallNonvirtualLongMethodA) 422 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 423 | const jvalue *args); 424 | 425 | jfloat (JNICALL *CallNonvirtualFloatMethod) 426 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 427 | jfloat (JNICALL *CallNonvirtualFloatMethodV) 428 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 429 | va_list args); 430 | jfloat (JNICALL *CallNonvirtualFloatMethodA) 431 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 432 | const jvalue *args); 433 | 434 | jdouble (JNICALL *CallNonvirtualDoubleMethod) 435 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 436 | jdouble (JNICALL *CallNonvirtualDoubleMethodV) 437 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 438 | va_list args); 439 | jdouble (JNICALL *CallNonvirtualDoubleMethodA) 440 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 441 | const jvalue *args); 442 | 443 | void (JNICALL *CallNonvirtualVoidMethod) 444 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...); 445 | void (JNICALL *CallNonvirtualVoidMethodV) 446 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 447 | va_list args); 448 | void (JNICALL *CallNonvirtualVoidMethodA) 449 | (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, 450 | const jvalue * args); 451 | 452 | jfieldID (JNICALL *GetFieldID) 453 | (JNIEnv *env, jclass clazz, const char *name, const char *sig); 454 | 455 | jobject (JNICALL *GetObjectField) 456 | (JNIEnv *env, jobject obj, jfieldID fieldID); 457 | jboolean (JNICALL *GetBooleanField) 458 | (JNIEnv *env, jobject obj, jfieldID fieldID); 459 | jbyte (JNICALL *GetByteField) 460 | (JNIEnv *env, jobject obj, jfieldID fieldID); 461 | jchar (JNICALL *GetCharField) 462 | (JNIEnv *env, jobject obj, jfieldID fieldID); 463 | jshort (JNICALL *GetShortField) 464 | (JNIEnv *env, jobject obj, jfieldID fieldID); 465 | jint (JNICALL *GetIntField) 466 | (JNIEnv *env, jobject obj, jfieldID fieldID); 467 | jlong (JNICALL *GetLongField) 468 | (JNIEnv *env, jobject obj, jfieldID fieldID); 469 | jfloat (JNICALL *GetFloatField) 470 | (JNIEnv *env, jobject obj, jfieldID fieldID); 471 | jdouble (JNICALL *GetDoubleField) 472 | (JNIEnv *env, jobject obj, jfieldID fieldID); 473 | 474 | void (JNICALL *SetObjectField) 475 | (JNIEnv *env, jobject obj, jfieldID fieldID, jobject val); 476 | void (JNICALL *SetBooleanField) 477 | (JNIEnv *env, jobject obj, jfieldID fieldID, jboolean val); 478 | void (JNICALL *SetByteField) 479 | (JNIEnv *env, jobject obj, jfieldID fieldID, jbyte val); 480 | void (JNICALL *SetCharField) 481 | (JNIEnv *env, jobject obj, jfieldID fieldID, jchar val); 482 | void (JNICALL *SetShortField) 483 | (JNIEnv *env, jobject obj, jfieldID fieldID, jshort val); 484 | void (JNICALL *SetIntField) 485 | (JNIEnv *env, jobject obj, jfieldID fieldID, jint val); 486 | void (JNICALL *SetLongField) 487 | (JNIEnv *env, jobject obj, jfieldID fieldID, jlong val); 488 | void (JNICALL *SetFloatField) 489 | (JNIEnv *env, jobject obj, jfieldID fieldID, jfloat val); 490 | void (JNICALL *SetDoubleField) 491 | (JNIEnv *env, jobject obj, jfieldID fieldID, jdouble val); 492 | 493 | jmethodID (JNICALL *GetStaticMethodID) 494 | (JNIEnv *env, jclass clazz, const char *name, const char *sig); 495 | 496 | jobject (JNICALL *CallStaticObjectMethod) 497 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 498 | jobject (JNICALL *CallStaticObjectMethodV) 499 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 500 | jobject (JNICALL *CallStaticObjectMethodA) 501 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 502 | 503 | jboolean (JNICALL *CallStaticBooleanMethod) 504 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 505 | jboolean (JNICALL *CallStaticBooleanMethodV) 506 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 507 | jboolean (JNICALL *CallStaticBooleanMethodA) 508 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 509 | 510 | jbyte (JNICALL *CallStaticByteMethod) 511 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 512 | jbyte (JNICALL *CallStaticByteMethodV) 513 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 514 | jbyte (JNICALL *CallStaticByteMethodA) 515 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 516 | 517 | jchar (JNICALL *CallStaticCharMethod) 518 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 519 | jchar (JNICALL *CallStaticCharMethodV) 520 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 521 | jchar (JNICALL *CallStaticCharMethodA) 522 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 523 | 524 | jshort (JNICALL *CallStaticShortMethod) 525 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 526 | jshort (JNICALL *CallStaticShortMethodV) 527 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 528 | jshort (JNICALL *CallStaticShortMethodA) 529 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 530 | 531 | jint (JNICALL *CallStaticIntMethod) 532 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 533 | jint (JNICALL *CallStaticIntMethodV) 534 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 535 | jint (JNICALL *CallStaticIntMethodA) 536 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 537 | 538 | jlong (JNICALL *CallStaticLongMethod) 539 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 540 | jlong (JNICALL *CallStaticLongMethodV) 541 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 542 | jlong (JNICALL *CallStaticLongMethodA) 543 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 544 | 545 | jfloat (JNICALL *CallStaticFloatMethod) 546 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 547 | jfloat (JNICALL *CallStaticFloatMethodV) 548 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 549 | jfloat (JNICALL *CallStaticFloatMethodA) 550 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 551 | 552 | jdouble (JNICALL *CallStaticDoubleMethod) 553 | (JNIEnv *env, jclass clazz, jmethodID methodID, ...); 554 | jdouble (JNICALL *CallStaticDoubleMethodV) 555 | (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args); 556 | jdouble (JNICALL *CallStaticDoubleMethodA) 557 | (JNIEnv *env, jclass clazz, jmethodID methodID, const jvalue *args); 558 | 559 | void (JNICALL *CallStaticVoidMethod) 560 | (JNIEnv *env, jclass cls, jmethodID methodID, ...); 561 | void (JNICALL *CallStaticVoidMethodV) 562 | (JNIEnv *env, jclass cls, jmethodID methodID, va_list args); 563 | void (JNICALL *CallStaticVoidMethodA) 564 | (JNIEnv *env, jclass cls, jmethodID methodID, const jvalue * args); 565 | 566 | jfieldID (JNICALL *GetStaticFieldID) 567 | (JNIEnv *env, jclass clazz, const char *name, const char *sig); 568 | jobject (JNICALL *GetStaticObjectField) 569 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 570 | jboolean (JNICALL *GetStaticBooleanField) 571 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 572 | jbyte (JNICALL *GetStaticByteField) 573 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 574 | jchar (JNICALL *GetStaticCharField) 575 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 576 | jshort (JNICALL *GetStaticShortField) 577 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 578 | jint (JNICALL *GetStaticIntField) 579 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 580 | jlong (JNICALL *GetStaticLongField) 581 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 582 | jfloat (JNICALL *GetStaticFloatField) 583 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 584 | jdouble (JNICALL *GetStaticDoubleField) 585 | (JNIEnv *env, jclass clazz, jfieldID fieldID); 586 | 587 | void (JNICALL *SetStaticObjectField) 588 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jobject value); 589 | void (JNICALL *SetStaticBooleanField) 590 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jboolean value); 591 | void (JNICALL *SetStaticByteField) 592 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jbyte value); 593 | void (JNICALL *SetStaticCharField) 594 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jchar value); 595 | void (JNICALL *SetStaticShortField) 596 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jshort value); 597 | void (JNICALL *SetStaticIntField) 598 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jint value); 599 | void (JNICALL *SetStaticLongField) 600 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jlong value); 601 | void (JNICALL *SetStaticFloatField) 602 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jfloat value); 603 | void (JNICALL *SetStaticDoubleField) 604 | (JNIEnv *env, jclass clazz, jfieldID fieldID, jdouble value); 605 | 606 | jstring (JNICALL *NewString) 607 | (JNIEnv *env, const jchar *unicode, jsize len); 608 | jsize (JNICALL *GetStringLength) 609 | (JNIEnv *env, jstring str); 610 | const jchar *(JNICALL *GetStringChars) 611 | (JNIEnv *env, jstring str, jboolean *isCopy); 612 | void (JNICALL *ReleaseStringChars) 613 | (JNIEnv *env, jstring str, const jchar *chars); 614 | 615 | jstring (JNICALL *NewStringUTF) 616 | (JNIEnv *env, const char *utf); 617 | jsize (JNICALL *GetStringUTFLength) 618 | (JNIEnv *env, jstring str); 619 | const char* (JNICALL *GetStringUTFChars) 620 | (JNIEnv *env, jstring str, jboolean *isCopy); 621 | void (JNICALL *ReleaseStringUTFChars) 622 | (JNIEnv *env, jstring str, const char* chars); 623 | 624 | 625 | jsize (JNICALL *GetArrayLength) 626 | (JNIEnv *env, jarray array); 627 | 628 | jobjectArray (JNICALL *NewObjectArray) 629 | (JNIEnv *env, jsize len, jclass clazz, jobject init); 630 | jobject (JNICALL *GetObjectArrayElement) 631 | (JNIEnv *env, jobjectArray array, jsize index); 632 | void (JNICALL *SetObjectArrayElement) 633 | (JNIEnv *env, jobjectArray array, jsize index, jobject val); 634 | 635 | jbooleanArray (JNICALL *NewBooleanArray) 636 | (JNIEnv *env, jsize len); 637 | jbyteArray (JNICALL *NewByteArray) 638 | (JNIEnv *env, jsize len); 639 | jcharArray (JNICALL *NewCharArray) 640 | (JNIEnv *env, jsize len); 641 | jshortArray (JNICALL *NewShortArray) 642 | (JNIEnv *env, jsize len); 643 | jintArray (JNICALL *NewIntArray) 644 | (JNIEnv *env, jsize len); 645 | jlongArray (JNICALL *NewLongArray) 646 | (JNIEnv *env, jsize len); 647 | jfloatArray (JNICALL *NewFloatArray) 648 | (JNIEnv *env, jsize len); 649 | jdoubleArray (JNICALL *NewDoubleArray) 650 | (JNIEnv *env, jsize len); 651 | 652 | jboolean * (JNICALL *GetBooleanArrayElements) 653 | (JNIEnv *env, jbooleanArray array, jboolean *isCopy); 654 | jbyte * (JNICALL *GetByteArrayElements) 655 | (JNIEnv *env, jbyteArray array, jboolean *isCopy); 656 | jchar * (JNICALL *GetCharArrayElements) 657 | (JNIEnv *env, jcharArray array, jboolean *isCopy); 658 | jshort * (JNICALL *GetShortArrayElements) 659 | (JNIEnv *env, jshortArray array, jboolean *isCopy); 660 | jint * (JNICALL *GetIntArrayElements) 661 | (JNIEnv *env, jintArray array, jboolean *isCopy); 662 | jlong * (JNICALL *GetLongArrayElements) 663 | (JNIEnv *env, jlongArray array, jboolean *isCopy); 664 | jfloat * (JNICALL *GetFloatArrayElements) 665 | (JNIEnv *env, jfloatArray array, jboolean *isCopy); 666 | jdouble * (JNICALL *GetDoubleArrayElements) 667 | (JNIEnv *env, jdoubleArray array, jboolean *isCopy); 668 | 669 | void (JNICALL *ReleaseBooleanArrayElements) 670 | (JNIEnv *env, jbooleanArray array, jboolean *elems, jint mode); 671 | void (JNICALL *ReleaseByteArrayElements) 672 | (JNIEnv *env, jbyteArray array, jbyte *elems, jint mode); 673 | void (JNICALL *ReleaseCharArrayElements) 674 | (JNIEnv *env, jcharArray array, jchar *elems, jint mode); 675 | void (JNICALL *ReleaseShortArrayElements) 676 | (JNIEnv *env, jshortArray array, jshort *elems, jint mode); 677 | void (JNICALL *ReleaseIntArrayElements) 678 | (JNIEnv *env, jintArray array, jint *elems, jint mode); 679 | void (JNICALL *ReleaseLongArrayElements) 680 | (JNIEnv *env, jlongArray array, jlong *elems, jint mode); 681 | void (JNICALL *ReleaseFloatArrayElements) 682 | (JNIEnv *env, jfloatArray array, jfloat *elems, jint mode); 683 | void (JNICALL *ReleaseDoubleArrayElements) 684 | (JNIEnv *env, jdoubleArray array, jdouble *elems, jint mode); 685 | 686 | void (JNICALL *GetBooleanArrayRegion) 687 | (JNIEnv *env, jbooleanArray array, jsize start, jsize l, jboolean *buf); 688 | void (JNICALL *GetByteArrayRegion) 689 | (JNIEnv *env, jbyteArray array, jsize start, jsize len, jbyte *buf); 690 | void (JNICALL *GetCharArrayRegion) 691 | (JNIEnv *env, jcharArray array, jsize start, jsize len, jchar *buf); 692 | void (JNICALL *GetShortArrayRegion) 693 | (JNIEnv *env, jshortArray array, jsize start, jsize len, jshort *buf); 694 | void (JNICALL *GetIntArrayRegion) 695 | (JNIEnv *env, jintArray array, jsize start, jsize len, jint *buf); 696 | void (JNICALL *GetLongArrayRegion) 697 | (JNIEnv *env, jlongArray array, jsize start, jsize len, jlong *buf); 698 | void (JNICALL *GetFloatArrayRegion) 699 | (JNIEnv *env, jfloatArray array, jsize start, jsize len, jfloat *buf); 700 | void (JNICALL *GetDoubleArrayRegion) 701 | (JNIEnv *env, jdoubleArray array, jsize start, jsize len, jdouble *buf); 702 | 703 | void (JNICALL *SetBooleanArrayRegion) 704 | (JNIEnv *env, jbooleanArray array, jsize start, jsize l, const jboolean *buf); 705 | void (JNICALL *SetByteArrayRegion) 706 | (JNIEnv *env, jbyteArray array, jsize start, jsize len, const jbyte *buf); 707 | void (JNICALL *SetCharArrayRegion) 708 | (JNIEnv *env, jcharArray array, jsize start, jsize len, const jchar *buf); 709 | void (JNICALL *SetShortArrayRegion) 710 | (JNIEnv *env, jshortArray array, jsize start, jsize len, const jshort *buf); 711 | void (JNICALL *SetIntArrayRegion) 712 | (JNIEnv *env, jintArray array, jsize start, jsize len, const jint *buf); 713 | void (JNICALL *SetLongArrayRegion) 714 | (JNIEnv *env, jlongArray array, jsize start, jsize len, const jlong *buf); 715 | void (JNICALL *SetFloatArrayRegion) 716 | (JNIEnv *env, jfloatArray array, jsize start, jsize len, const jfloat *buf); 717 | void (JNICALL *SetDoubleArrayRegion) 718 | (JNIEnv *env, jdoubleArray array, jsize start, jsize len, const jdouble *buf); 719 | 720 | jint (JNICALL *RegisterNatives) 721 | (JNIEnv *env, jclass clazz, const JNINativeMethod *methods, 722 | jint nMethods); 723 | jint (JNICALL *UnregisterNatives) 724 | (JNIEnv *env, jclass clazz); 725 | 726 | jint (JNICALL *MonitorEnter) 727 | (JNIEnv *env, jobject obj); 728 | jint (JNICALL *MonitorExit) 729 | (JNIEnv *env, jobject obj); 730 | 731 | jint (JNICALL *GetJavaVM) 732 | (JNIEnv *env, JavaVM **vm); 733 | 734 | void (JNICALL *GetStringRegion) 735 | (JNIEnv *env, jstring str, jsize start, jsize len, jchar *buf); 736 | void (JNICALL *GetStringUTFRegion) 737 | (JNIEnv *env, jstring str, jsize start, jsize len, char *buf); 738 | 739 | void * (JNICALL *GetPrimitiveArrayCritical) 740 | (JNIEnv *env, jarray array, jboolean *isCopy); 741 | void (JNICALL *ReleasePrimitiveArrayCritical) 742 | (JNIEnv *env, jarray array, void *carray, jint mode); 743 | 744 | const jchar * (JNICALL *GetStringCritical) 745 | (JNIEnv *env, jstring string, jboolean *isCopy); 746 | void (JNICALL *ReleaseStringCritical) 747 | (JNIEnv *env, jstring string, const jchar *cstring); 748 | 749 | jweak (JNICALL *NewWeakGlobalRef) 750 | (JNIEnv *env, jobject obj); 751 | void (JNICALL *DeleteWeakGlobalRef) 752 | (JNIEnv *env, jweak ref); 753 | 754 | jboolean (JNICALL *ExceptionCheck) 755 | (JNIEnv *env); 756 | 757 | jobject (JNICALL *NewDirectByteBuffer) 758 | (JNIEnv* env, void* address, jlong capacity); 759 | void* (JNICALL *GetDirectBufferAddress) 760 | (JNIEnv* env, jobject buf); 761 | jlong (JNICALL *GetDirectBufferCapacity) 762 | (JNIEnv* env, jobject buf); 763 | 764 | /* New JNI 1.6 Features */ 765 | 766 | jobjectRefType (JNICALL *GetObjectRefType) 767 | (JNIEnv* env, jobject obj); 768 | }; 769 | 770 | /* 771 | * We use inlined functions for C++ so that programmers can write: 772 | * 773 | * env->FindClass("java/lang/String") 774 | * 775 | * in C++ rather than: 776 | * 777 | * (*env)->FindClass(env, "java/lang/String") 778 | * 779 | * in C. 780 | */ 781 | 782 | struct JNIEnv_ { 783 | const struct JNINativeInterface_ *functions; 784 | #ifdef __cplusplus 785 | 786 | jint GetVersion() { 787 | return functions->GetVersion(this); 788 | } 789 | jclass DefineClass(const char *name, jobject loader, const jbyte *buf, 790 | jsize len) { 791 | return functions->DefineClass(this, name, loader, buf, len); 792 | } 793 | jclass FindClass(const char *name) { 794 | return functions->FindClass(this, name); 795 | } 796 | jmethodID FromReflectedMethod(jobject method) { 797 | return functions->FromReflectedMethod(this,method); 798 | } 799 | jfieldID FromReflectedField(jobject field) { 800 | return functions->FromReflectedField(this,field); 801 | } 802 | 803 | jobject ToReflectedMethod(jclass cls, jmethodID methodID, jboolean isStatic) { 804 | return functions->ToReflectedMethod(this, cls, methodID, isStatic); 805 | } 806 | 807 | jclass GetSuperclass(jclass sub) { 808 | return functions->GetSuperclass(this, sub); 809 | } 810 | jboolean IsAssignableFrom(jclass sub, jclass sup) { 811 | return functions->IsAssignableFrom(this, sub, sup); 812 | } 813 | 814 | jobject ToReflectedField(jclass cls, jfieldID fieldID, jboolean isStatic) { 815 | return functions->ToReflectedField(this,cls,fieldID,isStatic); 816 | } 817 | 818 | jint Throw(jthrowable obj) { 819 | return functions->Throw(this, obj); 820 | } 821 | jint ThrowNew(jclass clazz, const char *msg) { 822 | return functions->ThrowNew(this, clazz, msg); 823 | } 824 | jthrowable ExceptionOccurred() { 825 | return functions->ExceptionOccurred(this); 826 | } 827 | void ExceptionDescribe() { 828 | functions->ExceptionDescribe(this); 829 | } 830 | void ExceptionClear() { 831 | functions->ExceptionClear(this); 832 | } 833 | void FatalError(const char *msg) { 834 | functions->FatalError(this, msg); 835 | } 836 | 837 | jint PushLocalFrame(jint capacity) { 838 | return functions->PushLocalFrame(this,capacity); 839 | } 840 | jobject PopLocalFrame(jobject result) { 841 | return functions->PopLocalFrame(this,result); 842 | } 843 | 844 | jobject NewGlobalRef(jobject lobj) { 845 | return functions->NewGlobalRef(this,lobj); 846 | } 847 | void DeleteGlobalRef(jobject gref) { 848 | functions->DeleteGlobalRef(this,gref); 849 | } 850 | void DeleteLocalRef(jobject obj) { 851 | functions->DeleteLocalRef(this, obj); 852 | } 853 | 854 | jboolean IsSameObject(jobject obj1, jobject obj2) { 855 | return functions->IsSameObject(this,obj1,obj2); 856 | } 857 | 858 | jobject NewLocalRef(jobject ref) { 859 | return functions->NewLocalRef(this,ref); 860 | } 861 | jint EnsureLocalCapacity(jint capacity) { 862 | return functions->EnsureLocalCapacity(this,capacity); 863 | } 864 | 865 | jobject AllocObject(jclass clazz) { 866 | return functions->AllocObject(this,clazz); 867 | } 868 | jobject NewObject(jclass clazz, jmethodID methodID, ...) { 869 | va_list args; 870 | jobject result; 871 | va_start(args, methodID); 872 | result = functions->NewObjectV(this,clazz,methodID,args); 873 | va_end(args); 874 | return result; 875 | } 876 | jobject NewObjectV(jclass clazz, jmethodID methodID, 877 | va_list args) { 878 | return functions->NewObjectV(this,clazz,methodID,args); 879 | } 880 | jobject NewObjectA(jclass clazz, jmethodID methodID, 881 | const jvalue *args) { 882 | return functions->NewObjectA(this,clazz,methodID,args); 883 | } 884 | 885 | jclass GetObjectClass(jobject obj) { 886 | return functions->GetObjectClass(this,obj); 887 | } 888 | jboolean IsInstanceOf(jobject obj, jclass clazz) { 889 | return functions->IsInstanceOf(this,obj,clazz); 890 | } 891 | 892 | jmethodID GetMethodID(jclass clazz, const char *name, 893 | const char *sig) { 894 | return functions->GetMethodID(this,clazz,name,sig); 895 | } 896 | 897 | jobject CallObjectMethod(jobject obj, jmethodID methodID, ...) { 898 | va_list args; 899 | jobject result; 900 | va_start(args,methodID); 901 | result = functions->CallObjectMethodV(this,obj,methodID,args); 902 | va_end(args); 903 | return result; 904 | } 905 | jobject CallObjectMethodV(jobject obj, jmethodID methodID, 906 | va_list args) { 907 | return functions->CallObjectMethodV(this,obj,methodID,args); 908 | } 909 | jobject CallObjectMethodA(jobject obj, jmethodID methodID, 910 | const jvalue * args) { 911 | return functions->CallObjectMethodA(this,obj,methodID,args); 912 | } 913 | 914 | jboolean CallBooleanMethod(jobject obj, 915 | jmethodID methodID, ...) { 916 | va_list args; 917 | jboolean result; 918 | va_start(args,methodID); 919 | result = functions->CallBooleanMethodV(this,obj,methodID,args); 920 | va_end(args); 921 | return result; 922 | } 923 | jboolean CallBooleanMethodV(jobject obj, jmethodID methodID, 924 | va_list args) { 925 | return functions->CallBooleanMethodV(this,obj,methodID,args); 926 | } 927 | jboolean CallBooleanMethodA(jobject obj, jmethodID methodID, 928 | const jvalue * args) { 929 | return functions->CallBooleanMethodA(this,obj,methodID, args); 930 | } 931 | 932 | jbyte CallByteMethod(jobject obj, jmethodID methodID, ...) { 933 | va_list args; 934 | jbyte result; 935 | va_start(args,methodID); 936 | result = functions->CallByteMethodV(this,obj,methodID,args); 937 | va_end(args); 938 | return result; 939 | } 940 | jbyte CallByteMethodV(jobject obj, jmethodID methodID, 941 | va_list args) { 942 | return functions->CallByteMethodV(this,obj,methodID,args); 943 | } 944 | jbyte CallByteMethodA(jobject obj, jmethodID methodID, 945 | const jvalue * args) { 946 | return functions->CallByteMethodA(this,obj,methodID,args); 947 | } 948 | 949 | jchar CallCharMethod(jobject obj, jmethodID methodID, ...) { 950 | va_list args; 951 | jchar result; 952 | va_start(args,methodID); 953 | result = functions->CallCharMethodV(this,obj,methodID,args); 954 | va_end(args); 955 | return result; 956 | } 957 | jchar CallCharMethodV(jobject obj, jmethodID methodID, 958 | va_list args) { 959 | return functions->CallCharMethodV(this,obj,methodID,args); 960 | } 961 | jchar CallCharMethodA(jobject obj, jmethodID methodID, 962 | const jvalue * args) { 963 | return functions->CallCharMethodA(this,obj,methodID,args); 964 | } 965 | 966 | jshort CallShortMethod(jobject obj, jmethodID methodID, ...) { 967 | va_list args; 968 | jshort result; 969 | va_start(args,methodID); 970 | result = functions->CallShortMethodV(this,obj,methodID,args); 971 | va_end(args); 972 | return result; 973 | } 974 | jshort CallShortMethodV(jobject obj, jmethodID methodID, 975 | va_list args) { 976 | return functions->CallShortMethodV(this,obj,methodID,args); 977 | } 978 | jshort CallShortMethodA(jobject obj, jmethodID methodID, 979 | const jvalue * args) { 980 | return functions->CallShortMethodA(this,obj,methodID,args); 981 | } 982 | 983 | jint CallIntMethod(jobject obj, jmethodID methodID, ...) { 984 | va_list args; 985 | jint result; 986 | va_start(args,methodID); 987 | result = functions->CallIntMethodV(this,obj,methodID,args); 988 | va_end(args); 989 | return result; 990 | } 991 | jint CallIntMethodV(jobject obj, jmethodID methodID, 992 | va_list args) { 993 | return functions->CallIntMethodV(this,obj,methodID,args); 994 | } 995 | jint CallIntMethodA(jobject obj, jmethodID methodID, 996 | const jvalue * args) { 997 | return functions->CallIntMethodA(this,obj,methodID,args); 998 | } 999 | 1000 | jlong CallLongMethod(jobject obj, jmethodID methodID, ...) { 1001 | va_list args; 1002 | jlong result; 1003 | va_start(args,methodID); 1004 | result = functions->CallLongMethodV(this,obj,methodID,args); 1005 | va_end(args); 1006 | return result; 1007 | } 1008 | jlong CallLongMethodV(jobject obj, jmethodID methodID, 1009 | va_list args) { 1010 | return functions->CallLongMethodV(this,obj,methodID,args); 1011 | } 1012 | jlong CallLongMethodA(jobject obj, jmethodID methodID, 1013 | const jvalue * args) { 1014 | return functions->CallLongMethodA(this,obj,methodID,args); 1015 | } 1016 | 1017 | jfloat CallFloatMethod(jobject obj, jmethodID methodID, ...) { 1018 | va_list args; 1019 | jfloat result; 1020 | va_start(args,methodID); 1021 | result = functions->CallFloatMethodV(this,obj,methodID,args); 1022 | va_end(args); 1023 | return result; 1024 | } 1025 | jfloat CallFloatMethodV(jobject obj, jmethodID methodID, 1026 | va_list args) { 1027 | return functions->CallFloatMethodV(this,obj,methodID,args); 1028 | } 1029 | jfloat CallFloatMethodA(jobject obj, jmethodID methodID, 1030 | const jvalue * args) { 1031 | return functions->CallFloatMethodA(this,obj,methodID,args); 1032 | } 1033 | 1034 | jdouble CallDoubleMethod(jobject obj, jmethodID methodID, ...) { 1035 | va_list args; 1036 | jdouble result; 1037 | va_start(args,methodID); 1038 | result = functions->CallDoubleMethodV(this,obj,methodID,args); 1039 | va_end(args); 1040 | return result; 1041 | } 1042 | jdouble CallDoubleMethodV(jobject obj, jmethodID methodID, 1043 | va_list args) { 1044 | return functions->CallDoubleMethodV(this,obj,methodID,args); 1045 | } 1046 | jdouble CallDoubleMethodA(jobject obj, jmethodID methodID, 1047 | const jvalue * args) { 1048 | return functions->CallDoubleMethodA(this,obj,methodID,args); 1049 | } 1050 | 1051 | void CallVoidMethod(jobject obj, jmethodID methodID, ...) { 1052 | va_list args; 1053 | va_start(args,methodID); 1054 | functions->CallVoidMethodV(this,obj,methodID,args); 1055 | va_end(args); 1056 | } 1057 | void CallVoidMethodV(jobject obj, jmethodID methodID, 1058 | va_list args) { 1059 | functions->CallVoidMethodV(this,obj,methodID,args); 1060 | } 1061 | void CallVoidMethodA(jobject obj, jmethodID methodID, 1062 | const jvalue * args) { 1063 | functions->CallVoidMethodA(this,obj,methodID,args); 1064 | } 1065 | 1066 | jobject CallNonvirtualObjectMethod(jobject obj, jclass clazz, 1067 | jmethodID methodID, ...) { 1068 | va_list args; 1069 | jobject result; 1070 | va_start(args,methodID); 1071 | result = functions->CallNonvirtualObjectMethodV(this,obj,clazz, 1072 | methodID,args); 1073 | va_end(args); 1074 | return result; 1075 | } 1076 | jobject CallNonvirtualObjectMethodV(jobject obj, jclass clazz, 1077 | jmethodID methodID, va_list args) { 1078 | return functions->CallNonvirtualObjectMethodV(this,obj,clazz, 1079 | methodID,args); 1080 | } 1081 | jobject CallNonvirtualObjectMethodA(jobject obj, jclass clazz, 1082 | jmethodID methodID, const jvalue * args) { 1083 | return functions->CallNonvirtualObjectMethodA(this,obj,clazz, 1084 | methodID,args); 1085 | } 1086 | 1087 | jboolean CallNonvirtualBooleanMethod(jobject obj, jclass clazz, 1088 | jmethodID methodID, ...) { 1089 | va_list args; 1090 | jboolean result; 1091 | va_start(args,methodID); 1092 | result = functions->CallNonvirtualBooleanMethodV(this,obj,clazz, 1093 | methodID,args); 1094 | va_end(args); 1095 | return result; 1096 | } 1097 | jboolean CallNonvirtualBooleanMethodV(jobject obj, jclass clazz, 1098 | jmethodID methodID, va_list args) { 1099 | return functions->CallNonvirtualBooleanMethodV(this,obj,clazz, 1100 | methodID,args); 1101 | } 1102 | jboolean CallNonvirtualBooleanMethodA(jobject obj, jclass clazz, 1103 | jmethodID methodID, const jvalue * args) { 1104 | return functions->CallNonvirtualBooleanMethodA(this,obj,clazz, 1105 | methodID, args); 1106 | } 1107 | 1108 | jbyte CallNonvirtualByteMethod(jobject obj, jclass clazz, 1109 | jmethodID methodID, ...) { 1110 | va_list args; 1111 | jbyte result; 1112 | va_start(args,methodID); 1113 | result = functions->CallNonvirtualByteMethodV(this,obj,clazz, 1114 | methodID,args); 1115 | va_end(args); 1116 | return result; 1117 | } 1118 | jbyte CallNonvirtualByteMethodV(jobject obj, jclass clazz, 1119 | jmethodID methodID, va_list args) { 1120 | return functions->CallNonvirtualByteMethodV(this,obj,clazz, 1121 | methodID,args); 1122 | } 1123 | jbyte CallNonvirtualByteMethodA(jobject obj, jclass clazz, 1124 | jmethodID methodID, const jvalue * args) { 1125 | return functions->CallNonvirtualByteMethodA(this,obj,clazz, 1126 | methodID,args); 1127 | } 1128 | 1129 | jchar CallNonvirtualCharMethod(jobject obj, jclass clazz, 1130 | jmethodID methodID, ...) { 1131 | va_list args; 1132 | jchar result; 1133 | va_start(args,methodID); 1134 | result = functions->CallNonvirtualCharMethodV(this,obj,clazz, 1135 | methodID,args); 1136 | va_end(args); 1137 | return result; 1138 | } 1139 | jchar CallNonvirtualCharMethodV(jobject obj, jclass clazz, 1140 | jmethodID methodID, va_list args) { 1141 | return functions->CallNonvirtualCharMethodV(this,obj,clazz, 1142 | methodID,args); 1143 | } 1144 | jchar CallNonvirtualCharMethodA(jobject obj, jclass clazz, 1145 | jmethodID methodID, const jvalue * args) { 1146 | return functions->CallNonvirtualCharMethodA(this,obj,clazz, 1147 | methodID,args); 1148 | } 1149 | 1150 | jshort CallNonvirtualShortMethod(jobject obj, jclass clazz, 1151 | jmethodID methodID, ...) { 1152 | va_list args; 1153 | jshort result; 1154 | va_start(args,methodID); 1155 | result = functions->CallNonvirtualShortMethodV(this,obj,clazz, 1156 | methodID,args); 1157 | va_end(args); 1158 | return result; 1159 | } 1160 | jshort CallNonvirtualShortMethodV(jobject obj, jclass clazz, 1161 | jmethodID methodID, va_list args) { 1162 | return functions->CallNonvirtualShortMethodV(this,obj,clazz, 1163 | methodID,args); 1164 | } 1165 | jshort CallNonvirtualShortMethodA(jobject obj, jclass clazz, 1166 | jmethodID methodID, const jvalue * args) { 1167 | return functions->CallNonvirtualShortMethodA(this,obj,clazz, 1168 | methodID,args); 1169 | } 1170 | 1171 | jint CallNonvirtualIntMethod(jobject obj, jclass clazz, 1172 | jmethodID methodID, ...) { 1173 | va_list args; 1174 | jint result; 1175 | va_start(args,methodID); 1176 | result = functions->CallNonvirtualIntMethodV(this,obj,clazz, 1177 | methodID,args); 1178 | va_end(args); 1179 | return result; 1180 | } 1181 | jint CallNonvirtualIntMethodV(jobject obj, jclass clazz, 1182 | jmethodID methodID, va_list args) { 1183 | return functions->CallNonvirtualIntMethodV(this,obj,clazz, 1184 | methodID,args); 1185 | } 1186 | jint CallNonvirtualIntMethodA(jobject obj, jclass clazz, 1187 | jmethodID methodID, const jvalue * args) { 1188 | return functions->CallNonvirtualIntMethodA(this,obj,clazz, 1189 | methodID,args); 1190 | } 1191 | 1192 | jlong CallNonvirtualLongMethod(jobject obj, jclass clazz, 1193 | jmethodID methodID, ...) { 1194 | va_list args; 1195 | jlong result; 1196 | va_start(args,methodID); 1197 | result = functions->CallNonvirtualLongMethodV(this,obj,clazz, 1198 | methodID,args); 1199 | va_end(args); 1200 | return result; 1201 | } 1202 | jlong CallNonvirtualLongMethodV(jobject obj, jclass clazz, 1203 | jmethodID methodID, va_list args) { 1204 | return functions->CallNonvirtualLongMethodV(this,obj,clazz, 1205 | methodID,args); 1206 | } 1207 | jlong CallNonvirtualLongMethodA(jobject obj, jclass clazz, 1208 | jmethodID methodID, const jvalue * args) { 1209 | return functions->CallNonvirtualLongMethodA(this,obj,clazz, 1210 | methodID,args); 1211 | } 1212 | 1213 | jfloat CallNonvirtualFloatMethod(jobject obj, jclass clazz, 1214 | jmethodID methodID, ...) { 1215 | va_list args; 1216 | jfloat result; 1217 | va_start(args,methodID); 1218 | result = functions->CallNonvirtualFloatMethodV(this,obj,clazz, 1219 | methodID,args); 1220 | va_end(args); 1221 | return result; 1222 | } 1223 | jfloat CallNonvirtualFloatMethodV(jobject obj, jclass clazz, 1224 | jmethodID methodID, 1225 | va_list args) { 1226 | return functions->CallNonvirtualFloatMethodV(this,obj,clazz, 1227 | methodID,args); 1228 | } 1229 | jfloat CallNonvirtualFloatMethodA(jobject obj, jclass clazz, 1230 | jmethodID methodID, 1231 | const jvalue * args) { 1232 | return functions->CallNonvirtualFloatMethodA(this,obj,clazz, 1233 | methodID,args); 1234 | } 1235 | 1236 | jdouble CallNonvirtualDoubleMethod(jobject obj, jclass clazz, 1237 | jmethodID methodID, ...) { 1238 | va_list args; 1239 | jdouble result; 1240 | va_start(args,methodID); 1241 | result = functions->CallNonvirtualDoubleMethodV(this,obj,clazz, 1242 | methodID,args); 1243 | va_end(args); 1244 | return result; 1245 | } 1246 | jdouble CallNonvirtualDoubleMethodV(jobject obj, jclass clazz, 1247 | jmethodID methodID, 1248 | va_list args) { 1249 | return functions->CallNonvirtualDoubleMethodV(this,obj,clazz, 1250 | methodID,args); 1251 | } 1252 | jdouble CallNonvirtualDoubleMethodA(jobject obj, jclass clazz, 1253 | jmethodID methodID, 1254 | const jvalue * args) { 1255 | return functions->CallNonvirtualDoubleMethodA(this,obj,clazz, 1256 | methodID,args); 1257 | } 1258 | 1259 | void CallNonvirtualVoidMethod(jobject obj, jclass clazz, 1260 | jmethodID methodID, ...) { 1261 | va_list args; 1262 | va_start(args,methodID); 1263 | functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); 1264 | va_end(args); 1265 | } 1266 | void CallNonvirtualVoidMethodV(jobject obj, jclass clazz, 1267 | jmethodID methodID, 1268 | va_list args) { 1269 | functions->CallNonvirtualVoidMethodV(this,obj,clazz,methodID,args); 1270 | } 1271 | void CallNonvirtualVoidMethodA(jobject obj, jclass clazz, 1272 | jmethodID methodID, 1273 | const jvalue * args) { 1274 | functions->CallNonvirtualVoidMethodA(this,obj,clazz,methodID,args); 1275 | } 1276 | 1277 | jfieldID GetFieldID(jclass clazz, const char *name, 1278 | const char *sig) { 1279 | return functions->GetFieldID(this,clazz,name,sig); 1280 | } 1281 | 1282 | jobject GetObjectField(jobject obj, jfieldID fieldID) { 1283 | return functions->GetObjectField(this,obj,fieldID); 1284 | } 1285 | jboolean GetBooleanField(jobject obj, jfieldID fieldID) { 1286 | return functions->GetBooleanField(this,obj,fieldID); 1287 | } 1288 | jbyte GetByteField(jobject obj, jfieldID fieldID) { 1289 | return functions->GetByteField(this,obj,fieldID); 1290 | } 1291 | jchar GetCharField(jobject obj, jfieldID fieldID) { 1292 | return functions->GetCharField(this,obj,fieldID); 1293 | } 1294 | jshort GetShortField(jobject obj, jfieldID fieldID) { 1295 | return functions->GetShortField(this,obj,fieldID); 1296 | } 1297 | jint GetIntField(jobject obj, jfieldID fieldID) { 1298 | return functions->GetIntField(this,obj,fieldID); 1299 | } 1300 | jlong GetLongField(jobject obj, jfieldID fieldID) { 1301 | return functions->GetLongField(this,obj,fieldID); 1302 | } 1303 | jfloat GetFloatField(jobject obj, jfieldID fieldID) { 1304 | return functions->GetFloatField(this,obj,fieldID); 1305 | } 1306 | jdouble GetDoubleField(jobject obj, jfieldID fieldID) { 1307 | return functions->GetDoubleField(this,obj,fieldID); 1308 | } 1309 | 1310 | void SetObjectField(jobject obj, jfieldID fieldID, jobject val) { 1311 | functions->SetObjectField(this,obj,fieldID,val); 1312 | } 1313 | void SetBooleanField(jobject obj, jfieldID fieldID, 1314 | jboolean val) { 1315 | functions->SetBooleanField(this,obj,fieldID,val); 1316 | } 1317 | void SetByteField(jobject obj, jfieldID fieldID, 1318 | jbyte val) { 1319 | functions->SetByteField(this,obj,fieldID,val); 1320 | } 1321 | void SetCharField(jobject obj, jfieldID fieldID, 1322 | jchar val) { 1323 | functions->SetCharField(this,obj,fieldID,val); 1324 | } 1325 | void SetShortField(jobject obj, jfieldID fieldID, 1326 | jshort val) { 1327 | functions->SetShortField(this,obj,fieldID,val); 1328 | } 1329 | void SetIntField(jobject obj, jfieldID fieldID, 1330 | jint val) { 1331 | functions->SetIntField(this,obj,fieldID,val); 1332 | } 1333 | void SetLongField(jobject obj, jfieldID fieldID, 1334 | jlong val) { 1335 | functions->SetLongField(this,obj,fieldID,val); 1336 | } 1337 | void SetFloatField(jobject obj, jfieldID fieldID, 1338 | jfloat val) { 1339 | functions->SetFloatField(this,obj,fieldID,val); 1340 | } 1341 | void SetDoubleField(jobject obj, jfieldID fieldID, 1342 | jdouble val) { 1343 | functions->SetDoubleField(this,obj,fieldID,val); 1344 | } 1345 | 1346 | jmethodID GetStaticMethodID(jclass clazz, const char *name, 1347 | const char *sig) { 1348 | return functions->GetStaticMethodID(this,clazz,name,sig); 1349 | } 1350 | 1351 | jobject CallStaticObjectMethod(jclass clazz, jmethodID methodID, 1352 | ...) { 1353 | va_list args; 1354 | jobject result; 1355 | va_start(args,methodID); 1356 | result = functions->CallStaticObjectMethodV(this,clazz,methodID,args); 1357 | va_end(args); 1358 | return result; 1359 | } 1360 | jobject CallStaticObjectMethodV(jclass clazz, jmethodID methodID, 1361 | va_list args) { 1362 | return functions->CallStaticObjectMethodV(this,clazz,methodID,args); 1363 | } 1364 | jobject CallStaticObjectMethodA(jclass clazz, jmethodID methodID, 1365 | const jvalue *args) { 1366 | return functions->CallStaticObjectMethodA(this,clazz,methodID,args); 1367 | } 1368 | 1369 | jboolean CallStaticBooleanMethod(jclass clazz, 1370 | jmethodID methodID, ...) { 1371 | va_list args; 1372 | jboolean result; 1373 | va_start(args,methodID); 1374 | result = functions->CallStaticBooleanMethodV(this,clazz,methodID,args); 1375 | va_end(args); 1376 | return result; 1377 | } 1378 | jboolean CallStaticBooleanMethodV(jclass clazz, 1379 | jmethodID methodID, va_list args) { 1380 | return functions->CallStaticBooleanMethodV(this,clazz,methodID,args); 1381 | } 1382 | jboolean CallStaticBooleanMethodA(jclass clazz, 1383 | jmethodID methodID, const jvalue *args) { 1384 | return functions->CallStaticBooleanMethodA(this,clazz,methodID,args); 1385 | } 1386 | 1387 | jbyte CallStaticByteMethod(jclass clazz, 1388 | jmethodID methodID, ...) { 1389 | va_list args; 1390 | jbyte result; 1391 | va_start(args,methodID); 1392 | result = functions->CallStaticByteMethodV(this,clazz,methodID,args); 1393 | va_end(args); 1394 | return result; 1395 | } 1396 | jbyte CallStaticByteMethodV(jclass clazz, 1397 | jmethodID methodID, va_list args) { 1398 | return functions->CallStaticByteMethodV(this,clazz,methodID,args); 1399 | } 1400 | jbyte CallStaticByteMethodA(jclass clazz, 1401 | jmethodID methodID, const jvalue *args) { 1402 | return functions->CallStaticByteMethodA(this,clazz,methodID,args); 1403 | } 1404 | 1405 | jchar CallStaticCharMethod(jclass clazz, 1406 | jmethodID methodID, ...) { 1407 | va_list args; 1408 | jchar result; 1409 | va_start(args,methodID); 1410 | result = functions->CallStaticCharMethodV(this,clazz,methodID,args); 1411 | va_end(args); 1412 | return result; 1413 | } 1414 | jchar CallStaticCharMethodV(jclass clazz, 1415 | jmethodID methodID, va_list args) { 1416 | return functions->CallStaticCharMethodV(this,clazz,methodID,args); 1417 | } 1418 | jchar CallStaticCharMethodA(jclass clazz, 1419 | jmethodID methodID, const jvalue *args) { 1420 | return functions->CallStaticCharMethodA(this,clazz,methodID,args); 1421 | } 1422 | 1423 | jshort CallStaticShortMethod(jclass clazz, 1424 | jmethodID methodID, ...) { 1425 | va_list args; 1426 | jshort result; 1427 | va_start(args,methodID); 1428 | result = functions->CallStaticShortMethodV(this,clazz,methodID,args); 1429 | va_end(args); 1430 | return result; 1431 | } 1432 | jshort CallStaticShortMethodV(jclass clazz, 1433 | jmethodID methodID, va_list args) { 1434 | return functions->CallStaticShortMethodV(this,clazz,methodID,args); 1435 | } 1436 | jshort CallStaticShortMethodA(jclass clazz, 1437 | jmethodID methodID, const jvalue *args) { 1438 | return functions->CallStaticShortMethodA(this,clazz,methodID,args); 1439 | } 1440 | 1441 | jint CallStaticIntMethod(jclass clazz, 1442 | jmethodID methodID, ...) { 1443 | va_list args; 1444 | jint result; 1445 | va_start(args,methodID); 1446 | result = functions->CallStaticIntMethodV(this,clazz,methodID,args); 1447 | va_end(args); 1448 | return result; 1449 | } 1450 | jint CallStaticIntMethodV(jclass clazz, 1451 | jmethodID methodID, va_list args) { 1452 | return functions->CallStaticIntMethodV(this,clazz,methodID,args); 1453 | } 1454 | jint CallStaticIntMethodA(jclass clazz, 1455 | jmethodID methodID, const jvalue *args) { 1456 | return functions->CallStaticIntMethodA(this,clazz,methodID,args); 1457 | } 1458 | 1459 | jlong CallStaticLongMethod(jclass clazz, 1460 | jmethodID methodID, ...) { 1461 | va_list args; 1462 | jlong result; 1463 | va_start(args,methodID); 1464 | result = functions->CallStaticLongMethodV(this,clazz,methodID,args); 1465 | va_end(args); 1466 | return result; 1467 | } 1468 | jlong CallStaticLongMethodV(jclass clazz, 1469 | jmethodID methodID, va_list args) { 1470 | return functions->CallStaticLongMethodV(this,clazz,methodID,args); 1471 | } 1472 | jlong CallStaticLongMethodA(jclass clazz, 1473 | jmethodID methodID, const jvalue *args) { 1474 | return functions->CallStaticLongMethodA(this,clazz,methodID,args); 1475 | } 1476 | 1477 | jfloat CallStaticFloatMethod(jclass clazz, 1478 | jmethodID methodID, ...) { 1479 | va_list args; 1480 | jfloat result; 1481 | va_start(args,methodID); 1482 | result = functions->CallStaticFloatMethodV(this,clazz,methodID,args); 1483 | va_end(args); 1484 | return result; 1485 | } 1486 | jfloat CallStaticFloatMethodV(jclass clazz, 1487 | jmethodID methodID, va_list args) { 1488 | return functions->CallStaticFloatMethodV(this,clazz,methodID,args); 1489 | } 1490 | jfloat CallStaticFloatMethodA(jclass clazz, 1491 | jmethodID methodID, const jvalue *args) { 1492 | return functions->CallStaticFloatMethodA(this,clazz,methodID,args); 1493 | } 1494 | 1495 | jdouble CallStaticDoubleMethod(jclass clazz, 1496 | jmethodID methodID, ...) { 1497 | va_list args; 1498 | jdouble result; 1499 | va_start(args,methodID); 1500 | result = functions->CallStaticDoubleMethodV(this,clazz,methodID,args); 1501 | va_end(args); 1502 | return result; 1503 | } 1504 | jdouble CallStaticDoubleMethodV(jclass clazz, 1505 | jmethodID methodID, va_list args) { 1506 | return functions->CallStaticDoubleMethodV(this,clazz,methodID,args); 1507 | } 1508 | jdouble CallStaticDoubleMethodA(jclass clazz, 1509 | jmethodID methodID, const jvalue *args) { 1510 | return functions->CallStaticDoubleMethodA(this,clazz,methodID,args); 1511 | } 1512 | 1513 | void CallStaticVoidMethod(jclass cls, jmethodID methodID, ...) { 1514 | va_list args; 1515 | va_start(args,methodID); 1516 | functions->CallStaticVoidMethodV(this,cls,methodID,args); 1517 | va_end(args); 1518 | } 1519 | void CallStaticVoidMethodV(jclass cls, jmethodID methodID, 1520 | va_list args) { 1521 | functions->CallStaticVoidMethodV(this,cls,methodID,args); 1522 | } 1523 | void CallStaticVoidMethodA(jclass cls, jmethodID methodID, 1524 | const jvalue * args) { 1525 | functions->CallStaticVoidMethodA(this,cls,methodID,args); 1526 | } 1527 | 1528 | jfieldID GetStaticFieldID(jclass clazz, const char *name, 1529 | const char *sig) { 1530 | return functions->GetStaticFieldID(this,clazz,name,sig); 1531 | } 1532 | jobject GetStaticObjectField(jclass clazz, jfieldID fieldID) { 1533 | return functions->GetStaticObjectField(this,clazz,fieldID); 1534 | } 1535 | jboolean GetStaticBooleanField(jclass clazz, jfieldID fieldID) { 1536 | return functions->GetStaticBooleanField(this,clazz,fieldID); 1537 | } 1538 | jbyte GetStaticByteField(jclass clazz, jfieldID fieldID) { 1539 | return functions->GetStaticByteField(this,clazz,fieldID); 1540 | } 1541 | jchar GetStaticCharField(jclass clazz, jfieldID fieldID) { 1542 | return functions->GetStaticCharField(this,clazz,fieldID); 1543 | } 1544 | jshort GetStaticShortField(jclass clazz, jfieldID fieldID) { 1545 | return functions->GetStaticShortField(this,clazz,fieldID); 1546 | } 1547 | jint GetStaticIntField(jclass clazz, jfieldID fieldID) { 1548 | return functions->GetStaticIntField(this,clazz,fieldID); 1549 | } 1550 | jlong GetStaticLongField(jclass clazz, jfieldID fieldID) { 1551 | return functions->GetStaticLongField(this,clazz,fieldID); 1552 | } 1553 | jfloat GetStaticFloatField(jclass clazz, jfieldID fieldID) { 1554 | return functions->GetStaticFloatField(this,clazz,fieldID); 1555 | } 1556 | jdouble GetStaticDoubleField(jclass clazz, jfieldID fieldID) { 1557 | return functions->GetStaticDoubleField(this,clazz,fieldID); 1558 | } 1559 | 1560 | void SetStaticObjectField(jclass clazz, jfieldID fieldID, 1561 | jobject value) { 1562 | functions->SetStaticObjectField(this,clazz,fieldID,value); 1563 | } 1564 | void SetStaticBooleanField(jclass clazz, jfieldID fieldID, 1565 | jboolean value) { 1566 | functions->SetStaticBooleanField(this,clazz,fieldID,value); 1567 | } 1568 | void SetStaticByteField(jclass clazz, jfieldID fieldID, 1569 | jbyte value) { 1570 | functions->SetStaticByteField(this,clazz,fieldID,value); 1571 | } 1572 | void SetStaticCharField(jclass clazz, jfieldID fieldID, 1573 | jchar value) { 1574 | functions->SetStaticCharField(this,clazz,fieldID,value); 1575 | } 1576 | void SetStaticShortField(jclass clazz, jfieldID fieldID, 1577 | jshort value) { 1578 | functions->SetStaticShortField(this,clazz,fieldID,value); 1579 | } 1580 | void SetStaticIntField(jclass clazz, jfieldID fieldID, 1581 | jint value) { 1582 | functions->SetStaticIntField(this,clazz,fieldID,value); 1583 | } 1584 | void SetStaticLongField(jclass clazz, jfieldID fieldID, 1585 | jlong value) { 1586 | functions->SetStaticLongField(this,clazz,fieldID,value); 1587 | } 1588 | void SetStaticFloatField(jclass clazz, jfieldID fieldID, 1589 | jfloat value) { 1590 | functions->SetStaticFloatField(this,clazz,fieldID,value); 1591 | } 1592 | void SetStaticDoubleField(jclass clazz, jfieldID fieldID, 1593 | jdouble value) { 1594 | functions->SetStaticDoubleField(this,clazz,fieldID,value); 1595 | } 1596 | 1597 | jstring NewString(const jchar *unicode, jsize len) { 1598 | return functions->NewString(this,unicode,len); 1599 | } 1600 | jsize GetStringLength(jstring str) { 1601 | return functions->GetStringLength(this,str); 1602 | } 1603 | const jchar *GetStringChars(jstring str, jboolean *isCopy) { 1604 | return functions->GetStringChars(this,str,isCopy); 1605 | } 1606 | void ReleaseStringChars(jstring str, const jchar *chars) { 1607 | functions->ReleaseStringChars(this,str,chars); 1608 | } 1609 | 1610 | jstring NewStringUTF(const char *utf) { 1611 | return functions->NewStringUTF(this,utf); 1612 | } 1613 | jsize GetStringUTFLength(jstring str) { 1614 | return functions->GetStringUTFLength(this,str); 1615 | } 1616 | const char* GetStringUTFChars(jstring str, jboolean *isCopy) { 1617 | return functions->GetStringUTFChars(this,str,isCopy); 1618 | } 1619 | void ReleaseStringUTFChars(jstring str, const char* chars) { 1620 | functions->ReleaseStringUTFChars(this,str,chars); 1621 | } 1622 | 1623 | jsize GetArrayLength(jarray array) { 1624 | return functions->GetArrayLength(this,array); 1625 | } 1626 | 1627 | jobjectArray NewObjectArray(jsize len, jclass clazz, 1628 | jobject init) { 1629 | return functions->NewObjectArray(this,len,clazz,init); 1630 | } 1631 | jobject GetObjectArrayElement(jobjectArray array, jsize index) { 1632 | return functions->GetObjectArrayElement(this,array,index); 1633 | } 1634 | void SetObjectArrayElement(jobjectArray array, jsize index, 1635 | jobject val) { 1636 | functions->SetObjectArrayElement(this,array,index,val); 1637 | } 1638 | 1639 | jbooleanArray NewBooleanArray(jsize len) { 1640 | return functions->NewBooleanArray(this,len); 1641 | } 1642 | jbyteArray NewByteArray(jsize len) { 1643 | return functions->NewByteArray(this,len); 1644 | } 1645 | jcharArray NewCharArray(jsize len) { 1646 | return functions->NewCharArray(this,len); 1647 | } 1648 | jshortArray NewShortArray(jsize len) { 1649 | return functions->NewShortArray(this,len); 1650 | } 1651 | jintArray NewIntArray(jsize len) { 1652 | return functions->NewIntArray(this,len); 1653 | } 1654 | jlongArray NewLongArray(jsize len) { 1655 | return functions->NewLongArray(this,len); 1656 | } 1657 | jfloatArray NewFloatArray(jsize len) { 1658 | return functions->NewFloatArray(this,len); 1659 | } 1660 | jdoubleArray NewDoubleArray(jsize len) { 1661 | return functions->NewDoubleArray(this,len); 1662 | } 1663 | 1664 | jboolean * GetBooleanArrayElements(jbooleanArray array, jboolean *isCopy) { 1665 | return functions->GetBooleanArrayElements(this,array,isCopy); 1666 | } 1667 | jbyte * GetByteArrayElements(jbyteArray array, jboolean *isCopy) { 1668 | return functions->GetByteArrayElements(this,array,isCopy); 1669 | } 1670 | jchar * GetCharArrayElements(jcharArray array, jboolean *isCopy) { 1671 | return functions->GetCharArrayElements(this,array,isCopy); 1672 | } 1673 | jshort * GetShortArrayElements(jshortArray array, jboolean *isCopy) { 1674 | return functions->GetShortArrayElements(this,array,isCopy); 1675 | } 1676 | jint * GetIntArrayElements(jintArray array, jboolean *isCopy) { 1677 | return functions->GetIntArrayElements(this,array,isCopy); 1678 | } 1679 | jlong * GetLongArrayElements(jlongArray array, jboolean *isCopy) { 1680 | return functions->GetLongArrayElements(this,array,isCopy); 1681 | } 1682 | jfloat * GetFloatArrayElements(jfloatArray array, jboolean *isCopy) { 1683 | return functions->GetFloatArrayElements(this,array,isCopy); 1684 | } 1685 | jdouble * GetDoubleArrayElements(jdoubleArray array, jboolean *isCopy) { 1686 | return functions->GetDoubleArrayElements(this,array,isCopy); 1687 | } 1688 | 1689 | void ReleaseBooleanArrayElements(jbooleanArray array, 1690 | jboolean *elems, 1691 | jint mode) { 1692 | functions->ReleaseBooleanArrayElements(this,array,elems,mode); 1693 | } 1694 | void ReleaseByteArrayElements(jbyteArray array, 1695 | jbyte *elems, 1696 | jint mode) { 1697 | functions->ReleaseByteArrayElements(this,array,elems,mode); 1698 | } 1699 | void ReleaseCharArrayElements(jcharArray array, 1700 | jchar *elems, 1701 | jint mode) { 1702 | functions->ReleaseCharArrayElements(this,array,elems,mode); 1703 | } 1704 | void ReleaseShortArrayElements(jshortArray array, 1705 | jshort *elems, 1706 | jint mode) { 1707 | functions->ReleaseShortArrayElements(this,array,elems,mode); 1708 | } 1709 | void ReleaseIntArrayElements(jintArray array, 1710 | jint *elems, 1711 | jint mode) { 1712 | functions->ReleaseIntArrayElements(this,array,elems,mode); 1713 | } 1714 | void ReleaseLongArrayElements(jlongArray array, 1715 | jlong *elems, 1716 | jint mode) { 1717 | functions->ReleaseLongArrayElements(this,array,elems,mode); 1718 | } 1719 | void ReleaseFloatArrayElements(jfloatArray array, 1720 | jfloat *elems, 1721 | jint mode) { 1722 | functions->ReleaseFloatArrayElements(this,array,elems,mode); 1723 | } 1724 | void ReleaseDoubleArrayElements(jdoubleArray array, 1725 | jdouble *elems, 1726 | jint mode) { 1727 | functions->ReleaseDoubleArrayElements(this,array,elems,mode); 1728 | } 1729 | 1730 | void GetBooleanArrayRegion(jbooleanArray array, 1731 | jsize start, jsize len, jboolean *buf) { 1732 | functions->GetBooleanArrayRegion(this,array,start,len,buf); 1733 | } 1734 | void GetByteArrayRegion(jbyteArray array, 1735 | jsize start, jsize len, jbyte *buf) { 1736 | functions->GetByteArrayRegion(this,array,start,len,buf); 1737 | } 1738 | void GetCharArrayRegion(jcharArray array, 1739 | jsize start, jsize len, jchar *buf) { 1740 | functions->GetCharArrayRegion(this,array,start,len,buf); 1741 | } 1742 | void GetShortArrayRegion(jshortArray array, 1743 | jsize start, jsize len, jshort *buf) { 1744 | functions->GetShortArrayRegion(this,array,start,len,buf); 1745 | } 1746 | void GetIntArrayRegion(jintArray array, 1747 | jsize start, jsize len, jint *buf) { 1748 | functions->GetIntArrayRegion(this,array,start,len,buf); 1749 | } 1750 | void GetLongArrayRegion(jlongArray array, 1751 | jsize start, jsize len, jlong *buf) { 1752 | functions->GetLongArrayRegion(this,array,start,len,buf); 1753 | } 1754 | void GetFloatArrayRegion(jfloatArray array, 1755 | jsize start, jsize len, jfloat *buf) { 1756 | functions->GetFloatArrayRegion(this,array,start,len,buf); 1757 | } 1758 | void GetDoubleArrayRegion(jdoubleArray array, 1759 | jsize start, jsize len, jdouble *buf) { 1760 | functions->GetDoubleArrayRegion(this,array,start,len,buf); 1761 | } 1762 | 1763 | void SetBooleanArrayRegion(jbooleanArray array, jsize start, jsize len, 1764 | const jboolean *buf) { 1765 | functions->SetBooleanArrayRegion(this,array,start,len,buf); 1766 | } 1767 | void SetByteArrayRegion(jbyteArray array, jsize start, jsize len, 1768 | const jbyte *buf) { 1769 | functions->SetByteArrayRegion(this,array,start,len,buf); 1770 | } 1771 | void SetCharArrayRegion(jcharArray array, jsize start, jsize len, 1772 | const jchar *buf) { 1773 | functions->SetCharArrayRegion(this,array,start,len,buf); 1774 | } 1775 | void SetShortArrayRegion(jshortArray array, jsize start, jsize len, 1776 | const jshort *buf) { 1777 | functions->SetShortArrayRegion(this,array,start,len,buf); 1778 | } 1779 | void SetIntArrayRegion(jintArray array, jsize start, jsize len, 1780 | const jint *buf) { 1781 | functions->SetIntArrayRegion(this,array,start,len,buf); 1782 | } 1783 | void SetLongArrayRegion(jlongArray array, jsize start, jsize len, 1784 | const jlong *buf) { 1785 | functions->SetLongArrayRegion(this,array,start,len,buf); 1786 | } 1787 | void SetFloatArrayRegion(jfloatArray array, jsize start, jsize len, 1788 | const jfloat *buf) { 1789 | functions->SetFloatArrayRegion(this,array,start,len,buf); 1790 | } 1791 | void SetDoubleArrayRegion(jdoubleArray array, jsize start, jsize len, 1792 | const jdouble *buf) { 1793 | functions->SetDoubleArrayRegion(this,array,start,len,buf); 1794 | } 1795 | 1796 | jint RegisterNatives(jclass clazz, const JNINativeMethod *methods, 1797 | jint nMethods) { 1798 | return functions->RegisterNatives(this,clazz,methods,nMethods); 1799 | } 1800 | jint UnregisterNatives(jclass clazz) { 1801 | return functions->UnregisterNatives(this,clazz); 1802 | } 1803 | 1804 | jint MonitorEnter(jobject obj) { 1805 | return functions->MonitorEnter(this,obj); 1806 | } 1807 | jint MonitorExit(jobject obj) { 1808 | return functions->MonitorExit(this,obj); 1809 | } 1810 | 1811 | jint GetJavaVM(JavaVM **vm) { 1812 | return functions->GetJavaVM(this,vm); 1813 | } 1814 | 1815 | void GetStringRegion(jstring str, jsize start, jsize len, jchar *buf) { 1816 | functions->GetStringRegion(this,str,start,len,buf); 1817 | } 1818 | void GetStringUTFRegion(jstring str, jsize start, jsize len, char *buf) { 1819 | functions->GetStringUTFRegion(this,str,start,len,buf); 1820 | } 1821 | 1822 | void * GetPrimitiveArrayCritical(jarray array, jboolean *isCopy) { 1823 | return functions->GetPrimitiveArrayCritical(this,array,isCopy); 1824 | } 1825 | void ReleasePrimitiveArrayCritical(jarray array, void *carray, jint mode) { 1826 | functions->ReleasePrimitiveArrayCritical(this,array,carray,mode); 1827 | } 1828 | 1829 | const jchar * GetStringCritical(jstring string, jboolean *isCopy) { 1830 | return functions->GetStringCritical(this,string,isCopy); 1831 | } 1832 | void ReleaseStringCritical(jstring string, const jchar *cstring) { 1833 | functions->ReleaseStringCritical(this,string,cstring); 1834 | } 1835 | 1836 | jweak NewWeakGlobalRef(jobject obj) { 1837 | return functions->NewWeakGlobalRef(this,obj); 1838 | } 1839 | void DeleteWeakGlobalRef(jweak ref) { 1840 | functions->DeleteWeakGlobalRef(this,ref); 1841 | } 1842 | 1843 | jboolean ExceptionCheck() { 1844 | return functions->ExceptionCheck(this); 1845 | } 1846 | 1847 | jobject NewDirectByteBuffer(void* address, jlong capacity) { 1848 | return functions->NewDirectByteBuffer(this, address, capacity); 1849 | } 1850 | void* GetDirectBufferAddress(jobject buf) { 1851 | return functions->GetDirectBufferAddress(this, buf); 1852 | } 1853 | jlong GetDirectBufferCapacity(jobject buf) { 1854 | return functions->GetDirectBufferCapacity(this, buf); 1855 | } 1856 | jobjectRefType GetObjectRefType(jobject obj) { 1857 | return functions->GetObjectRefType(this, obj); 1858 | } 1859 | 1860 | #endif /* __cplusplus */ 1861 | }; 1862 | 1863 | typedef struct JavaVMOption { 1864 | char *optionString; 1865 | void *extraInfo; 1866 | } JavaVMOption; 1867 | 1868 | typedef struct JavaVMInitArgs { 1869 | jint version; 1870 | 1871 | jint nOptions; 1872 | JavaVMOption *options; 1873 | jboolean ignoreUnrecognized; 1874 | } JavaVMInitArgs; 1875 | 1876 | typedef struct JavaVMAttachArgs { 1877 | jint version; 1878 | 1879 | char *name; 1880 | jobject group; 1881 | } JavaVMAttachArgs; 1882 | 1883 | /* These will be VM-specific. */ 1884 | 1885 | #define JDK1_2 1886 | #define JDK1_4 1887 | 1888 | /* End VM-specific. */ 1889 | 1890 | struct JNIInvokeInterface_ { 1891 | void *reserved0; 1892 | void *reserved1; 1893 | void *reserved2; 1894 | 1895 | jint (JNICALL *DestroyJavaVM)(JavaVM *vm); 1896 | 1897 | jint (JNICALL *AttachCurrentThread)(JavaVM *vm, void **penv, void *args); 1898 | 1899 | jint (JNICALL *DetachCurrentThread)(JavaVM *vm); 1900 | 1901 | jint (JNICALL *GetEnv)(JavaVM *vm, void **penv, jint version); 1902 | 1903 | jint (JNICALL *AttachCurrentThreadAsDaemon)(JavaVM *vm, void **penv, void *args); 1904 | }; 1905 | 1906 | struct JavaVM_ { 1907 | const struct JNIInvokeInterface_ *functions; 1908 | #ifdef __cplusplus 1909 | 1910 | jint DestroyJavaVM() { 1911 | return functions->DestroyJavaVM(this); 1912 | } 1913 | jint AttachCurrentThread(void **penv, void *args) { 1914 | return functions->AttachCurrentThread(this, penv, args); 1915 | } 1916 | jint DetachCurrentThread() { 1917 | return functions->DetachCurrentThread(this); 1918 | } 1919 | 1920 | jint GetEnv(void **penv, jint version) { 1921 | return functions->GetEnv(this, penv, version); 1922 | } 1923 | jint AttachCurrentThreadAsDaemon(void **penv, void *args) { 1924 | return functions->AttachCurrentThreadAsDaemon(this, penv, args); 1925 | } 1926 | #endif 1927 | }; 1928 | 1929 | #ifdef _JNI_IMPLEMENTATION_ 1930 | #define _JNI_IMPORT_OR_EXPORT_ JNIEXPORT 1931 | #else 1932 | #define _JNI_IMPORT_OR_EXPORT_ JNIIMPORT 1933 | #endif 1934 | _JNI_IMPORT_OR_EXPORT_ jint JNICALL 1935 | JNI_GetDefaultJavaVMInitArgs(void *args); 1936 | 1937 | _JNI_IMPORT_OR_EXPORT_ jint JNICALL 1938 | JNI_CreateJavaVM(JavaVM **pvm, void **penv, void *args); 1939 | 1940 | _JNI_IMPORT_OR_EXPORT_ jint JNICALL 1941 | JNI_GetCreatedJavaVMs(JavaVM **, jsize, jsize *); 1942 | 1943 | /* Defined by native libraries. */ 1944 | JNIEXPORT jint JNICALL 1945 | JNI_OnLoad(JavaVM *vm, void *reserved); 1946 | 1947 | JNIEXPORT void JNICALL 1948 | JNI_OnUnload(JavaVM *vm, void *reserved); 1949 | 1950 | #define JNI_VERSION_1_1 0x00010001 1951 | #define JNI_VERSION_1_2 0x00010002 1952 | #define JNI_VERSION_1_4 0x00010004 1953 | #define JNI_VERSION_1_6 0x00010006 1954 | 1955 | #ifdef __cplusplus 1956 | } /* extern "C" */ 1957 | #endif /* __cplusplus */ 1958 | 1959 | #endif /* !_JAVASOFT_JNI_H_ */ 1960 | -------------------------------------------------------------------------------- /include/jni_md.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1996, 2000, Oracle and/or its affiliates. All rights reserved. 3 | * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. 4 | * 5 | * 6 | * 7 | * 8 | * 9 | * 10 | * 11 | * 12 | * 13 | * 14 | * 15 | * 16 | * 17 | * 18 | * 19 | * 20 | * 21 | * 22 | * 23 | * 24 | */ 25 | 26 | #ifndef _JAVASOFT_JNI_MD_H_ 27 | #define _JAVASOFT_JNI_MD_H_ 28 | 29 | #define JNIEXPORT 30 | #define JNIIMPORT 31 | #define JNICALL 32 | 33 | typedef int jint; 34 | #ifdef _LP64 /* 64-bit Solaris */ 35 | typedef long jlong; 36 | #else 37 | typedef long long jlong; 38 | #endif 39 | 40 | typedef signed char jbyte; 41 | 42 | #endif /* !_JAVASOFT_JNI_MD_H_ */ 43 | -------------------------------------------------------------------------------- /project/Build.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | import sbt.Keys._ 3 | import xerial.sbt.Pack._ 4 | 5 | object Build extends sbt.Build { 6 | 7 | private def profile = System.getProperty("xerial.profile", "default") 8 | 9 | def releaseResolver(v: String): Option[Resolver] = { 10 | profile match { 11 | case "default" => { 12 | val nexus = "https://oss.sonatype.org/" 13 | if (v.trim.endsWith("SNAPSHOT")) 14 | Some("snapshots" at nexus + "content/repositories/snapshots") 15 | else 16 | Some("releases" at nexus + "service/local/staging/deploy/maven2") 17 | } 18 | case p => { 19 | scala.Console.err.println("unknown xerial.profile:%s".format(p)) 20 | None 21 | } 22 | } 23 | } 24 | 25 | val SCALA_VERSION = "2.9.2" 26 | 27 | lazy val defaultJavacOptions = Seq("-encoding", "UTF-8", "-source", "1.6") 28 | lazy val defaultScalacOptions = Seq("-encoding", "UTF-8", "-deprecation", "-unchecked", "-target:jvm-1.6") 29 | 30 | lazy val root = Project( 31 | id = "jnuma", 32 | base = file("."), 33 | settings = Defaults.defaultSettings ++ packSettings ++ 34 | Seq( 35 | organization := "org.xerial", 36 | organizationName := "Xerial Project", 37 | organizationHomepage := Some(new URL("http://xerial.org/")), 38 | description := "A library for creating numa-aware buffer in Java/Scala", 39 | scalaVersion := SCALA_VERSION, 40 | publishMavenStyle := true, 41 | publishArtifact in Test := false, 42 | publishTo <<= version { (v) => releaseResolver(v) }, 43 | pomIncludeRepository := { _ => false }, 44 | // custom settings here 45 | crossPaths := false, 46 | libraryDependencies ++= Seq( 47 | // Add dependent jars here 48 | "org.xerial" % "xerial-core" % "3.0" % "test", 49 | "org.scalatest" %% "scalatest" % "1.8" % "test" 50 | ), 51 | javacOptions in Compile := defaultJavacOptions ++ Seq("-target", "1.6"), 52 | javacOptions in Compile in doc := defaultJavacOptions ++ Seq("-windowtitle", "xerial.jnuma API", "-linkoffline", "http://docs.oracle.com/javase/6/docs/api/", "http://docs.oracle.com/javase/6/docs/api/"), 53 | // scalacOptions in Compile := defaultScalacOptions, 54 | // scalacOptions in doc <++= (baseDirectory in LocalProject("jnuma"), version) map { (bd, v) => 55 | // val tree = if(v.endsWith("-SNAPSHOT")) "develop" else "master" 56 | // Seq( 57 | // "-sourcepath", bd.getAbsolutePath, 58 | // "-doctitle", "Xerial JNuma Version %s".format(v) 59 | // ) 60 | // }, 61 | pomExtra := { 62 | http://xerial.org/ 63 | 64 | 65 | Apache 2 66 | http://www.apache.org/licenses/LICENSE-2.0.txt 67 | 68 | 69 | 70 | scm:git:github.com/xerial/jnuma.git 71 | scm:git:git@github.com:xerial/jnuma.git 72 | github.com/xerial/jnuma.git 73 | 74 | 75 | 76 | {SCALA_VERSION} 77 | 78 | UTF-8 79 | 80 | 81 | 82 | leo 83 | Taro L. Saito 84 | http://xerial.org/leo 85 | 86 | 87 | } 88 | 89 | ) 90 | ) 91 | } 92 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("org.xerial.sbt" % "sbt-pack" % "0.1.1") 2 | 3 | addSbtPlugin("com.github.mpeltonen" % "sbt-idea" % "1.1.0") 4 | 5 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NoNuma.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma; 18 | 19 | import java.lang.reflect.Field; 20 | import java.nio.ByteBuffer; 21 | 22 | /** 23 | * A stub when accessing numa API is not supported in the system 24 | * @author leo 25 | */ 26 | public class NoNuma implements NumaInterface { 27 | 28 | private sun.misc.Unsafe unsafe; 29 | 30 | NoNuma() { 31 | try { 32 | Field f = sun.misc.Unsafe.class.getDeclaredField("theUnsafe"); 33 | f.setAccessible(true); 34 | unsafe = (sun.misc.Unsafe) f.get(null); 35 | } 36 | catch(Exception e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | 41 | 42 | public boolean isAvailable() { 43 | return false; 44 | } 45 | 46 | @Override 47 | public int maxNode() { 48 | return 1; 49 | } 50 | 51 | @Override 52 | public long nodeSize(int node) { 53 | return Runtime.getRuntime().maxMemory(); 54 | } 55 | 56 | @Override 57 | public long freeSize(int node) { 58 | return Runtime.getRuntime().freeMemory(); 59 | } 60 | 61 | @Override 62 | public int distance(int node1, int node2) { 63 | return 10; 64 | } 65 | 66 | @Override 67 | public void nodeToCpus(int node, long[] buffer) { 68 | } 69 | 70 | @Override 71 | public void getAffinity(int pid, long[] cpuBitMask, int numCPUs) { 72 | // do nothing 73 | } 74 | 75 | @Override 76 | public void setAffinity(int pid, long[] cpuBitMask, int numCPUs) { 77 | // do nothing 78 | } 79 | 80 | @Override 81 | public int preferredNode() { 82 | return 0; 83 | } 84 | 85 | @Override 86 | public void setLocalAlloc() { 87 | // do nothing 88 | } 89 | 90 | @Override 91 | public void setPreferred(int node) { 92 | // do nothing 93 | } 94 | 95 | @Override 96 | public void runOnNode(int node) { 97 | // do nothing 98 | } 99 | 100 | @Override 101 | public void toNodeMemory(Object array, int length, int node) { 102 | // do nothing 103 | } 104 | 105 | @Override 106 | public ByteBuffer alloc(int capacity) { 107 | return ByteBuffer.allocate(capacity); 108 | } 109 | 110 | 111 | public ByteBuffer allocLocal(int capacity) { 112 | return alloc(capacity); 113 | } 114 | 115 | public ByteBuffer allocOnNode(int capacity, int node) { 116 | return allocLocal(capacity); 117 | } 118 | 119 | @Override 120 | public ByteBuffer allocInterleaved(int capacity) { 121 | return allocLocal(capacity); 122 | } 123 | 124 | @Override 125 | public long allocMemory(long capacity) { 126 | return unsafe.allocateMemory(capacity); 127 | } 128 | 129 | @Override 130 | public void free(long address, long capacity) { 131 | unsafe.freeMemory(address); 132 | } 133 | 134 | @Override 135 | public void free(ByteBuffer buf) { 136 | // Simply clear the buffer and let the GC collect the freed memory 137 | buf.clear(); 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/Numa.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma; 18 | 19 | 20 | import java.io.*; 21 | import java.lang.reflect.Method; 22 | import java.nio.ByteBuffer; 23 | import java.security.ProtectionDomain; 24 | import java.util.Arrays; 25 | 26 | /** 27 | * Numa API. 28 | * 29 | * 30 | * When allocating new {@link java.nio.ByteBuffer}s using this API, 31 | * you must release these buffers by calling {@link Numa#free(java.nio.ByteBuffer)} because 32 | * the allocated buffers are out of control of the GC of the JVM. 33 | * 34 | * @author Taro L. Saito 35 | */ 36 | public class Numa { 37 | 38 | /** 39 | * This type must be Object rather than NumaInterface because some JVM implementation loads the the class 40 | * specified in the field before the completion of the injection of NumaInterface and NumaNative to the root class loader. 41 | */ 42 | private static Object impl = init(); 43 | 44 | private static ClassLoader rootClassLoader() { 45 | ClassLoader cl = Thread.currentThread().getContextClassLoader(); 46 | while(cl.getParent() != null) { 47 | cl = cl.getParent(); 48 | } 49 | return cl; 50 | } 51 | 52 | private static byte[] loadByteCode(String className) throws IOException { 53 | return loadResource(Numa.class.getResourceAsStream(String.format("/%s.class", className.replaceAll("\\.", "/")))); 54 | } 55 | 56 | private static byte[] loadResource(InputStream in) throws IOException { 57 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 58 | byte[] buf = new byte[8192]; 59 | for(int ret = 0; (ret = in.read(buf)) != -1;) { 60 | out.write(buf, 0, ret); 61 | } 62 | in.close(); 63 | out.close(); 64 | return out.toByteArray(); 65 | } 66 | 67 | 68 | private static void inject(String[] classNames, ClassLoader cl) throws Exception { 69 | 70 | Class clClass = Class.forName("java.lang.ClassLoader"); 71 | 72 | Method m = clClass.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class, ProtectionDomain.class }); 73 | boolean isAccessible = m.isAccessible(); 74 | try { 75 | if(!isAccessible) 76 | m.setAccessible(true); 77 | for(String c : classNames) { 78 | try { 79 | cl.loadClass(c); 80 | } 81 | catch(ClassNotFoundException e) { 82 | byte[] byteCode = loadByteCode(c); 83 | m.invoke(cl, c, byteCode, 0, byteCode.length, System.class.getProtectionDomain()); 84 | } 85 | } 86 | } 87 | finally { 88 | if(!isAccessible) 89 | m.setAccessible(false); 90 | } 91 | 92 | } 93 | 94 | 95 | private static Object init() { 96 | String osName = System.getProperty("os.name", ""); 97 | if(osName.contains("Windows") || osName.contains("Mac")) 98 | return new NoNuma(); 99 | else { 100 | // Extract the native lib to temp folder 101 | try { 102 | File libFile = new File(System.getProperty("java.io.tmpdir") + "/libjnuma.so"); 103 | byte[] newLib = loadResource(Numa.class.getResourceAsStream("/xerial/jnuma/native/libjnuma.so")); 104 | if(!libFile.exists() || (libFile.exists() && !Arrays.equals(loadResource(new FileInputStream(libFile)), newLib))) { 105 | FileOutputStream out = new FileOutputStream(libFile); 106 | out.write(newLib); 107 | out.close(); 108 | } 109 | 110 | String loader = "xerial.jnuma.NumaJNILoader"; 111 | String nativeAPI = "xerial.jnuma.NumaNative"; 112 | inject(new String[]{loader, "xerial.jnuma.NumaInterface", "xerial.jnuma.NumaNative"}, rootClassLoader()); 113 | Class loaderClass = rootClassLoader().loadClass(loader); 114 | Method loadMethod = loaderClass.getDeclaredMethod("load", new Class[] {String.class}); 115 | loadMethod.invoke(null, libFile.getAbsolutePath()); 116 | return rootClassLoader().loadClass(nativeAPI).newInstance(); 117 | } 118 | catch(Exception e) { 119 | e.printStackTrace(); 120 | return new NoNuma(); 121 | } 122 | } 123 | } 124 | 125 | /** 126 | * Returns true if the NUMA is available in this machine 127 | * @return 128 | */ 129 | public static boolean isAvailable() { 130 | return ((NumaInterface) impl).isAvailable(); 131 | } 132 | 133 | /** 134 | * Max number of numa nodes (local memories) 135 | * @return 136 | */ 137 | public static int numNodes() { 138 | return ((NumaInterface) impl).maxNode()+1; 139 | } 140 | 141 | /** 142 | * The memory size of the node 143 | * @param node node number 144 | * @return memory byte size 145 | */ 146 | public static long nodeSize(int node) { 147 | return ((NumaInterface) impl).nodeSize(node); 148 | } 149 | 150 | /** 151 | * The free memory size of the node 152 | * @param node node number 153 | * @return free memory byte size 154 | */ 155 | public static long freeSize(int node) { 156 | return ((NumaInterface) impl).freeSize(node); 157 | } 158 | 159 | /** 160 | * Distance between two NUMA nodes. The distance is a multiple of 10s 161 | * @param node1 162 | * @param node2 163 | * @return node distance 164 | */ 165 | public static int distance(int node1, int node2) { 166 | return ((NumaInterface) impl).distance(node1, node2); 167 | } 168 | 169 | /** 170 | * Get the number of CPUs available to this machine 171 | * @return 172 | */ 173 | public static int numCPUs() { 174 | return Runtime.getRuntime().availableProcessors(); 175 | } 176 | 177 | /** 178 | * Create a bit mask for specifying CPU sets. From the LSB, it corresponds CPU0, CPU1, ... 179 | * @return 180 | */ 181 | public static long[] newCPUBitMask() { 182 | int bufSize = (numCPUs() + 64 -1)/ 64; 183 | return new long[bufSize]; 184 | } 185 | 186 | /** 187 | * Create a bit mask setting a single CPU on 188 | * @param cpu 189 | * @return 190 | */ 191 | public static long[] newCPUBitMaskForOneCPU(int cpu) { 192 | long[] cpuMask = newCPUBitMask(); 193 | cpuMask[cpu / 64] |= 1L << (cpu % 64); 194 | return cpuMask; 195 | } 196 | 197 | /** 198 | * Create a bit mask setting all CPUs on 199 | * @return 200 | */ 201 | public static long[] newCPUBitMaskForAllCPUs() { 202 | long[] cpuMask = newCPUBitMask(); 203 | int M = numCPUs(); 204 | for(int i=0; i M) ? ~0L : ~(~0L << (M % 64)); 206 | return cpuMask; 207 | } 208 | 209 | /** 210 | * Return the bit vector showing the closest CPUs to the specified NUMA node 211 | * @param node numa node number 212 | * @return cpu bit vector 213 | */ 214 | public static long[] nodeToCpus(int node) { 215 | long[] bv = new long[512/8]; 216 | ((NumaInterface) impl).nodeToCpus(node, bv); 217 | return bv; 218 | } 219 | 220 | /** 221 | * Get the affinity bit vector of the current thread to the CPUs. In default, 222 | * all bits are set to 1. If you want to bind the current thread to a specific CPU, use {@link #setAffinity(int)}. 223 | * 224 | * Before terminating the thread, you should reset the affinity so that OS can assign (probably pooled) threads to arbitrary CPUs. 225 | * @return 226 | */ 227 | public static long[] getAffinity() { 228 | long[] cpuMask = newCPUBitMask(); 229 | ((NumaInterface) impl).getAffinity(0, cpuMask, numCPUs()); 230 | return cpuMask; 231 | } 232 | 233 | /** 234 | * Set the affinity of this thread to a single cpu 235 | * @param cpu cpu number 236 | */ 237 | public static void setAffinity(int cpu) { 238 | setAffinity(newCPUBitMaskForOneCPU(cpu)); 239 | } 240 | 241 | /** 242 | * Set the affinity of this thread to CPUs specified in the bit vector 243 | * @param cpuBitMask bit vector. CPU0 corresponds to the LSB. 244 | */ 245 | public static void setAffinity(long[] cpuBitMask) { 246 | ((NumaInterface) impl).setAffinity(0, cpuBitMask, numCPUs()); 247 | } 248 | 249 | /** 250 | * Reset the affinity of the current thread to CPUs. 251 | */ 252 | public static void resetAffinity() { 253 | ((NumaInterface) impl).setAffinity(0, newCPUBitMaskForAllCPUs(), numCPUs()); 254 | } 255 | 256 | /** 257 | * Returns the preferred node of the current thread. 258 | * @return preferred numa node 259 | */ 260 | public static int getPreferredNode() { 261 | return ((NumaInterface) impl).preferredNode(); 262 | } 263 | 264 | /** 265 | * Set the memory allocation policy for the calling thread to local allocation. 266 | */ 267 | public static void setLocalAlloc() { 268 | ((NumaInterface) impl).setLocalAlloc(); 269 | } 270 | 271 | /** 272 | * Sets the preferred node for the current thread. The system will attempt to allocate memory from the preferred node, but will fall back to other 273 | * nodes if no memory is available on the preferred node. To reset the node preference, pass a node of -1 argument or call {@link #setLocalAlloc()} . 274 | * @param node 275 | */ 276 | public static void setPreferred(int node) { 277 | ((NumaInterface) impl).setPreferred(node); 278 | } 279 | 280 | /** 281 | * Run the current thread and its children on a specified node. To reset the binding call {@link #runOnAllNodes()} 282 | * @param node 283 | */ 284 | public static void runOnNode(int node) { 285 | ((NumaInterface) impl).runOnNode(node); 286 | } 287 | 288 | public static void runOnAllNodes() { 289 | runOnNode(-1); 290 | } 291 | 292 | 293 | /** 294 | * Allocate a new NUMA buffer using the current policy. You must release the acquired buffer by {@link #free(java.nio.ByteBuffer)} because 295 | * it is out of the control of GC. 296 | * @param capacity byte size of the buffer 297 | * @return new ByteBuffer 298 | */ 299 | public static ByteBuffer alloc(int capacity) { 300 | return ((NumaInterface) impl).alloc(capacity); 301 | } 302 | 303 | /** 304 | * Allocate a new local NUMA buffer. You must release the acquired buffer by {@link #free(java.nio.ByteBuffer)} because 305 | * it is out of the control of GC. 306 | * @param capacity byte size of the buffer 307 | * @return new ByteBuffer 308 | */ 309 | public static ByteBuffer allocLocal(int capacity) { 310 | return ((NumaInterface) impl).allocLocal(capacity); 311 | } 312 | 313 | /** 314 | * Allocate a new NUMA buffer on a specific node. You must release the acquired buffer by {@link #free(java.nio.ByteBuffer)} because 315 | * it is out of the control of GC. 316 | * @param capacity byte size of the buffer 317 | * @param node node number 318 | * @return new ByteBuffer 319 | */ 320 | public static ByteBuffer allocOnNode(int capacity, int node) { 321 | return ((NumaInterface) impl).allocOnNode(capacity, node); 322 | } 323 | 324 | /** 325 | * Allocate a new NUMA buffer interleaved on multiple NUMA nodes. You must release the acquired buffer by {@link #free(java.nio.ByteBuffer)} because 326 | * it is out of the control of GC. 327 | * @param capacity byte size of the buffer 328 | * @return new ByteBuffer 329 | */ 330 | public static ByteBuffer allocInterleaved(int capacity) { 331 | return ((NumaInterface) impl).allocInterleaved(capacity); 332 | } 333 | 334 | /** 335 | * Allocate a new NUMA buffer of the specified capacity 336 | * @param capacity 337 | * @return the raw memory address 338 | */ 339 | public static long allocMemory(long capacity) { 340 | return ((NumaInterface) impl).allocMemory(capacity); 341 | } 342 | 343 | /** 344 | * Release the memory resource allocated at the specified address and capacity. 345 | * @param address 346 | * @param capacity 347 | */ 348 | public static void free(long address, long capacity) { 349 | ((NumaInterface) impl).free(address, capacity); 350 | } 351 | 352 | /** 353 | * Release the memory resources of the numa ByteBuffer. 354 | * @param buf the buffer to release 355 | */ 356 | public static void free(ByteBuffer buf) { 357 | ((NumaInterface) impl).free(buf); 358 | } 359 | 360 | 361 | /** 362 | * Send the array to a node. The array should be primitive type array. To send the array to a node correctly, 363 | * the array should not be touched before calling this method. 364 | * @param array 365 | * @param byteLength 366 | * @param node 367 | */ 368 | public static void toNodeMemory(Object array, int byteLength, int node) { 369 | ((NumaInterface) impl).toNodeMemory(array, byteLength, node); 370 | } 371 | 372 | 373 | 374 | } 375 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NumaInterface.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma; 18 | 19 | import java.nio.ByteBuffer; 20 | 21 | /** 22 | * NUMA API Interface. This interface is used when loading native class in the root class loader, so you are not allowed to use 23 | * this class. If you describe this class in an import statement or source codes, loading the native class ({@link xerial.jnuma.Numa}) will fail. 24 | * @author leo 25 | */ 26 | public interface NumaInterface { 27 | 28 | public boolean isAvailable(); 29 | 30 | public int maxNode(); 31 | 32 | public long nodeSize(int node); 33 | 34 | public long freeSize(int node); 35 | 36 | public int distance(int node1, int node2); 37 | public void nodeToCpus(int node, long[] buffer); 38 | public void getAffinity(int pid, long[] cpuBitMask, int numCPUs); 39 | public void setAffinity(int pid, long[] cpuBitMask, int numCPUs); 40 | 41 | public int preferredNode(); 42 | public void setLocalAlloc(); 43 | 44 | public void setPreferred(int node); 45 | public void runOnNode(int node); 46 | 47 | public void toNodeMemory(Object array, int length, int node); 48 | 49 | //public void bind(long[] nodeMask); 50 | 51 | public ByteBuffer alloc(int capacity); 52 | /** 53 | * Allocate a new ByteBuffer on local NUMA node 54 | * @param capacity 55 | * @return 56 | */ 57 | public ByteBuffer allocLocal(int capacity); 58 | 59 | /** 60 | * Allocate a new ByteBuffer on the specified NUMA node 61 | * @param capacity 62 | * @param node 63 | * @return 64 | */ 65 | public ByteBuffer allocOnNode(int capacity, int node); 66 | public ByteBuffer allocInterleaved(int capacity); 67 | 68 | 69 | /** 70 | * Allocate a new memory of the size of the given capacity. 71 | * @param capacity 72 | * @return the allocated memory address 73 | */ 74 | public long allocMemory(long capacity); 75 | 76 | /** 77 | * Free the allocated memory 78 | * @param address 79 | */ 80 | public void free(long address, long capacity); 81 | 82 | /** 83 | * Release the numa buffer 84 | * @param buf 85 | */ 86 | public void free(ByteBuffer buf); 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NumaJNILoader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma; 18 | 19 | import java.util.HashSet; 20 | 21 | /** 22 | * This class will be used only when loading NUMA native library. Do not reference this class in an import statement or source codes. 23 | * 24 | * @author Taro L. Saito 25 | */ 26 | public class NumaJNILoader { 27 | private static HashSet loadedLib = new HashSet(); 28 | 29 | public static synchronized void load(String libPath) { 30 | if(loadedLib.contains(libPath)) 31 | return; 32 | 33 | try { 34 | System.load(libPath); 35 | loadedLib.add(libPath); 36 | } 37 | catch(Exception e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NumaNative.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | #define _GNU_SOURCE 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include "NumaNative.h" 23 | 24 | 25 | void throwException(JNIEnv *env, jobject self, int errorCode) { 26 | jclass c = (*env)->FindClass(env, "xerial/jnuma/NumaNative"); 27 | if(c == 0) 28 | return; 29 | 30 | jmethodID m = (*env)->GetMethodID(env, c, "throwError", "(I)V"); 31 | if(m == 0) 32 | return; 33 | 34 | (*env)->CallVoidMethod(env, self, m, (jint) errorCode); 35 | } 36 | 37 | 38 | /* 39 | * Class: xerial_jnuma_NumaNative 40 | * Method: numaAvailable 41 | * Signature: ()Z 42 | */ 43 | JNIEXPORT jboolean JNICALL Java_xerial_jnuma_NumaNative_isAvailable 44 | (JNIEnv *env, jobject obj) { 45 | return numa_available() != -1; 46 | } 47 | 48 | /* 49 | * Class: xerial_jnuma_NumaNative 50 | * Method: maxNode 51 | * Signature: ()I 52 | */ 53 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_maxNode 54 | (JNIEnv *env, jobject obj) { 55 | return numa_max_node(); 56 | } 57 | 58 | /* 59 | * Class: xerial_jnuma_NumaNative 60 | * Method: nodeSize 61 | * Signature: (I)J 62 | */ 63 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_nodeSize 64 | (JNIEnv *env, jobject obj, jint node) { 65 | return (jlong) numa_node_size((int) node, NULL); 66 | } 67 | 68 | /* 69 | * Class: xerial_jnuma_NumaNative 70 | * Method: freeSize 71 | * Signature: (I)J 72 | */ 73 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_freeSize 74 | (JNIEnv *env, jobject obj, jint node) { 75 | long free = 0; 76 | numa_node_size((int) node, &free); 77 | return free; 78 | } 79 | 80 | 81 | /* 82 | * Class: xerial_jnuma_NumaNative 83 | * Method: distance 84 | * Signature: (II)I 85 | */ 86 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_distance 87 | (JNIEnv *env, jobject obj, jint node1, jint node2) { 88 | return numa_distance(node1, node2); 89 | } 90 | 91 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_nodeToCpus 92 | (JNIEnv *env, jobject obj, jint node, jlongArray array) { 93 | 94 | unsigned long* buf = (unsigned long*) (*env)->GetPrimitiveArrayCritical(env, (jarray) array, 0); 95 | int len = (int) (*env)->GetArrayLength(env, array); 96 | int ret = numa_node_to_cpus((int) node, buf, len * 8); 97 | (*env)->ReleasePrimitiveArrayCritical(env, (jarray) array, buf, 0); 98 | if(ret != 0) 99 | throwException(env, obj, errno); 100 | } 101 | 102 | 103 | /* 104 | * Class: xerial_jnuma_NumaNative 105 | * Method: alloc 106 | * Signature: (I)Ljava/nio/ByteBuffer; 107 | */ 108 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_alloc 109 | (JNIEnv *env, jobject obj, jint capacity) { 110 | void* mem = numa_alloc((size_t) capacity); 111 | //printf("allocate local memory\n"); 112 | if(mem == NULL) 113 | printf("failed to allocate local memory\n"); 114 | return (*env)->NewDirectByteBuffer(env, mem, (jlong) capacity); 115 | } 116 | 117 | 118 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocLocal 119 | (JNIEnv *env, jobject jobj, jint capacity) 120 | { 121 | void* mem = numa_alloc_local((size_t) capacity); 122 | //printf("allocate local memory\n"); 123 | if(mem == NULL) 124 | printf("failed to allocate local memory\n"); 125 | return (*env)->NewDirectByteBuffer(env, mem, (jlong) capacity); 126 | } 127 | 128 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocOnNode 129 | (JNIEnv *env, jobject jobj, jint capacity, jint node) 130 | { 131 | jobject b; 132 | void* mem = numa_alloc_onnode((size_t) capacity, (int) node); 133 | if(mem == NULL) 134 | printf("failed to allocate memory on node %d\n", (int) node); 135 | b = (*env)->NewDirectByteBuffer(env, mem, (jlong) capacity); 136 | return b; 137 | } 138 | 139 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocInterleaved 140 | (JNIEnv *env, jobject obj, jint capacity) { 141 | jobject b; 142 | void* mem = numa_alloc_interleaved((size_t) capacity); 143 | if(mem == NULL) { 144 | // failed to allocate interleaved memory 145 | throwException(env, obj, 11); 146 | } 147 | else { 148 | b = (*env)->NewDirectByteBuffer(env, mem, (jlong) capacity); 149 | return b; 150 | } 151 | } 152 | 153 | 154 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_free__Ljava_nio_ByteBuffer_2 155 | (JNIEnv *env, jobject jobj, jobject buf) { 156 | //printf("free is called\n"); 157 | void* mem = (*env)->GetDirectBufferAddress(env, buf); 158 | jlong capacity = (*env)->GetDirectBufferCapacity(env, buf); 159 | if(mem != 0) { 160 | //printf("free capacity:%d\n", capacity); 161 | numa_free(mem, (size_t) capacity); 162 | } 163 | } 164 | 165 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_allocMemory 166 | (JNIEnv *env, jobject obj, jlong capacity) { 167 | void* mem = numa_alloc((size_t) capacity); 168 | if(mem == NULL) 169 | printf("failed to allocate local memory\n"); 170 | return (jlong) mem; 171 | } 172 | 173 | 174 | 175 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_free__JJ 176 | (JNIEnv *env, jobject jobj, jlong address, jlong capacity) { 177 | if(address != 0) { 178 | numa_free((void *) address, (size_t) capacity); 179 | } 180 | } 181 | 182 | 183 | 184 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_getAffinity 185 | (JNIEnv *env, jobject obj, jint pid, jlongArray maskBuf, jint numCPUs) { 186 | 187 | uint64_t* in = (uint64_t*) (*env)->GetPrimitiveArrayCritical(env, (jarray) maskBuf, 0); 188 | cpu_set_t mask; 189 | int i; 190 | if(in == 0) 191 | throwException(env, obj, 10); 192 | 193 | CPU_ZERO(&mask); 194 | int ret = sched_getaffinity(0, sizeof(mask), &mask); 195 | if(ret < 0) 196 | throwException(env, obj, ret); 197 | 198 | for(i=0; iReleasePrimitiveArrayCritical(env, (jarray) maskBuf, (void*) in, (jint) 0); 203 | } 204 | 205 | 206 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setAffinity 207 | (JNIEnv *env, jobject obj, jint pid, jlongArray maskBuf, jint numCPUs) { 208 | 209 | uint64_t* in = (uint64_t*) (*env)->GetPrimitiveArrayCritical(env, (jarray) maskBuf, 0); 210 | cpu_set_t mask; 211 | int i; 212 | 213 | CPU_ZERO(&mask); 214 | for(i=0; iReleasePrimitiveArrayCritical(env, (jarray) maskBuf, (void*) in, (jint) 0); 219 | 220 | int ret = sched_setaffinity(0, sizeof(cpu_set_t), &mask); 221 | if(ret < 0) 222 | throwException(env, obj, errno); 223 | } 224 | 225 | 226 | /* 227 | * Class: xerial_jnuma_NumaNative 228 | * Method: preferredNode 229 | * Signature: ()I 230 | */ 231 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_preferredNode 232 | (JNIEnv *env, jobject obj) { 233 | return (jint) numa_preferred(); 234 | } 235 | 236 | /* 237 | * Class: xerial_jnuma_NumaNative 238 | * Method: setLocalAlloc 239 | * Signature: ()V 240 | */ 241 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setLocalAlloc 242 | (JNIEnv *env, jobject obj) { 243 | numa_set_localalloc(); 244 | } 245 | 246 | /* 247 | * Class: xerial_jnuma_NumaNative 248 | * Method: setPreferred 249 | * Signature: (I)V 250 | */ 251 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setPreferred 252 | (JNIEnv *env, jobject obj, jint node) { 253 | numa_set_preferred((int) node); 254 | } 255 | 256 | /* 257 | * Class: xerial_jnuma_NumaNative 258 | * Method: runOnNode 259 | * Signature: (I)V 260 | */ 261 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_runOnNode 262 | (JNIEnv *env, jobject obj, jint node) { 263 | int ret = numa_run_on_node((int) node); 264 | if(ret != 0) 265 | throwException(env, obj, errno); 266 | } 267 | 268 | /* 269 | * Class: xerial_jnuma_NumaNative 270 | * Method: toNodeMemory 271 | * Signature: (Ljava/lang/Object;II)V 272 | */ 273 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_toNodeMemory 274 | (JNIEnv *env, jobject obj, jobject array, jint length, jint node) { 275 | 276 | void* buf = (void*) (*env)->GetPrimitiveArrayCritical(env, (jarray) array, 0); 277 | 278 | numa_tonode_memory(buf, (size_t) length, (int) node); 279 | 280 | (*env)->ReleasePrimitiveArrayCritical(env, (jarray) array, buf, (jint) 0); 281 | } 282 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NumaNative.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class xerial_jnuma_NumaNative */ 4 | 5 | #ifndef _Included_xerial_jnuma_NumaNative 6 | #define _Included_xerial_jnuma_NumaNative 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: xerial_jnuma_NumaNative 12 | * Method: isAvailable 13 | * Signature: ()Z 14 | */ 15 | JNIEXPORT jboolean JNICALL Java_xerial_jnuma_NumaNative_isAvailable 16 | (JNIEnv *, jobject); 17 | 18 | /* 19 | * Class: xerial_jnuma_NumaNative 20 | * Method: maxNode 21 | * Signature: ()I 22 | */ 23 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_maxNode 24 | (JNIEnv *, jobject); 25 | 26 | /* 27 | * Class: xerial_jnuma_NumaNative 28 | * Method: nodeSize 29 | * Signature: (I)J 30 | */ 31 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_nodeSize 32 | (JNIEnv *, jobject, jint); 33 | 34 | /* 35 | * Class: xerial_jnuma_NumaNative 36 | * Method: freeSize 37 | * Signature: (I)J 38 | */ 39 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_freeSize 40 | (JNIEnv *, jobject, jint); 41 | 42 | /* 43 | * Class: xerial_jnuma_NumaNative 44 | * Method: distance 45 | * Signature: (II)I 46 | */ 47 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_distance 48 | (JNIEnv *, jobject, jint, jint); 49 | 50 | /* 51 | * Class: xerial_jnuma_NumaNative 52 | * Method: nodeToCpus 53 | * Signature: (I[J)V 54 | */ 55 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_nodeToCpus 56 | (JNIEnv *, jobject, jint, jlongArray); 57 | 58 | /* 59 | * Class: xerial_jnuma_NumaNative 60 | * Method: getAffinity 61 | * Signature: (I[JI)V 62 | */ 63 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_getAffinity 64 | (JNIEnv *, jobject, jint, jlongArray, jint); 65 | 66 | /* 67 | * Class: xerial_jnuma_NumaNative 68 | * Method: setAffinity 69 | * Signature: (I[JI)V 70 | */ 71 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setAffinity 72 | (JNIEnv *, jobject, jint, jlongArray, jint); 73 | 74 | /* 75 | * Class: xerial_jnuma_NumaNative 76 | * Method: preferredNode 77 | * Signature: ()I 78 | */ 79 | JNIEXPORT jint JNICALL Java_xerial_jnuma_NumaNative_preferredNode 80 | (JNIEnv *, jobject); 81 | 82 | /* 83 | * Class: xerial_jnuma_NumaNative 84 | * Method: setLocalAlloc 85 | * Signature: ()V 86 | */ 87 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setLocalAlloc 88 | (JNIEnv *, jobject); 89 | 90 | /* 91 | * Class: xerial_jnuma_NumaNative 92 | * Method: setPreferred 93 | * Signature: (I)V 94 | */ 95 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_setPreferred 96 | (JNIEnv *, jobject, jint); 97 | 98 | /* 99 | * Class: xerial_jnuma_NumaNative 100 | * Method: runOnNode 101 | * Signature: (I)V 102 | */ 103 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_runOnNode 104 | (JNIEnv *, jobject, jint); 105 | 106 | /* 107 | * Class: xerial_jnuma_NumaNative 108 | * Method: toNodeMemory 109 | * Signature: (Ljava/lang/Object;II)V 110 | */ 111 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_toNodeMemory 112 | (JNIEnv *, jobject, jobject, jint, jint); 113 | 114 | /* 115 | * Class: xerial_jnuma_NumaNative 116 | * Method: alloc 117 | * Signature: (I)Ljava/nio/ByteBuffer; 118 | */ 119 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_alloc 120 | (JNIEnv *, jobject, jint); 121 | 122 | /* 123 | * Class: xerial_jnuma_NumaNative 124 | * Method: allocLocal 125 | * Signature: (I)Ljava/nio/ByteBuffer; 126 | */ 127 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocLocal 128 | (JNIEnv *, jobject, jint); 129 | 130 | /* 131 | * Class: xerial_jnuma_NumaNative 132 | * Method: allocOnNode 133 | * Signature: (II)Ljava/nio/ByteBuffer; 134 | */ 135 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocOnNode 136 | (JNIEnv *, jobject, jint, jint); 137 | 138 | /* 139 | * Class: xerial_jnuma_NumaNative 140 | * Method: allocInterleaved 141 | * Signature: (I)Ljava/nio/ByteBuffer; 142 | */ 143 | JNIEXPORT jobject JNICALL Java_xerial_jnuma_NumaNative_allocInterleaved 144 | (JNIEnv *, jobject, jint); 145 | 146 | /* 147 | * Class: xerial_jnuma_NumaNative 148 | * Method: free 149 | * Signature: (Ljava/nio/ByteBuffer;)V 150 | */ 151 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_free__Ljava_nio_ByteBuffer_2 152 | (JNIEnv *, jobject, jobject); 153 | 154 | /* 155 | * Class: xerial_jnuma_NumaNative 156 | * Method: allocMemory 157 | * Signature: (J)J 158 | */ 159 | JNIEXPORT jlong JNICALL Java_xerial_jnuma_NumaNative_allocMemory 160 | (JNIEnv *, jobject, jlong); 161 | 162 | /* 163 | * Class: xerial_jnuma_NumaNative 164 | * Method: free 165 | * Signature: (JJ)V 166 | */ 167 | JNIEXPORT void JNICALL Java_xerial_jnuma_NumaNative_free__JJ 168 | (JNIEnv *, jobject, jlong, jlong); 169 | 170 | #ifdef __cplusplus 171 | } 172 | #endif 173 | #endif 174 | -------------------------------------------------------------------------------- /src/main/java/xerial/jnuma/NumaNative.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma; 18 | 19 | import java.nio.ByteBuffer; 20 | 21 | /** 22 | * Native code interface. Do not describe this class name in an import statement or source codes, because it will break 23 | * the native code loading mechanism. Use static methods in {@link xerial.jnuma.Numa} to access NUMA. 24 | * 25 | * @author Taro L. Saito 26 | */ 27 | public class NumaNative implements NumaInterface { 28 | 29 | public native boolean isAvailable(); 30 | public native int maxNode(); 31 | public native long nodeSize(int node); 32 | public native long freeSize(int node); 33 | public native int distance(int node1, int node2); 34 | public native void nodeToCpus(int node, long[] buffer); 35 | public native void getAffinity(int pid, long[] cpuBitMask, int numCPUs); 36 | public native void setAffinity(int pid, long[] cpuBitMask, int numCPUs); 37 | 38 | public native int preferredNode(); 39 | public native void setLocalAlloc(); 40 | 41 | public native void setPreferred(int node); 42 | public native void runOnNode(int node); 43 | 44 | public native void toNodeMemory(Object array, int length, int node); 45 | 46 | public native ByteBuffer alloc(int capacity); 47 | public native ByteBuffer allocLocal(int capacity); 48 | public native ByteBuffer allocOnNode(int capacity, int node); 49 | public native ByteBuffer allocInterleaved(int capacity); 50 | 51 | public native void free(ByteBuffer buf); 52 | 53 | public native long allocMemory(long capacity); 54 | public native void free(long address, long capacity); 55 | 56 | 57 | private void throwError(int errorCode) throws Exception { 58 | throw new Exception(String.format("NUMA error occurred %d", errorCode)); 59 | } 60 | 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/main/resources/xerial/jnuma/native/libjnuma.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xerial/jnuma/fe2b9b34fc758d95bc35f77f8d79fce56152389e/src/main/resources/xerial/jnuma/native/libjnuma.so -------------------------------------------------------------------------------- /src/test/scala/xerial/jnuma/MySpec.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package xerial.jnuma 18 | 19 | import org.scalatest.matchers.{ShouldMatchers, MustMatchers} 20 | import org.scalatest.{Tag, OptionValues, GivenWhenThen, WordSpec} 21 | import xerial.core.io.Resource 22 | import xerial.core.log.Logger 23 | import xerial.core.util.Timer 24 | 25 | //-------------------------------------- 26 | // 27 | // MySpec.scala 28 | // Since: 2012/11/20 12:57 PM 29 | // 30 | //-------------------------------------- 31 | 32 | /** 33 | * Helper trait for writing test codes. Extend this trait in your test classes 34 | */ 35 | trait MySpec extends WordSpec with ShouldMatchers with MustMatchers with GivenWhenThen with OptionValues with Resource with Timer with Logger { 36 | 37 | implicit def toTag(s:String) = Tag(s) 38 | 39 | } -------------------------------------------------------------------------------- /src/test/scala/xerial/jnuma/NumaTest.scala: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2012 Taro L. Saito 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | //-------------------------------------- 18 | // 19 | // NumaTest.scala 20 | // Since: 2012/11/22 2:24 PM 21 | // 22 | //-------------------------------------- 23 | 24 | package xerial.jnuma 25 | 26 | import util.Random 27 | import java.nio.{ByteOrder, ByteBuffer} 28 | import java.util 29 | import java.io.{OutputStream, FileOutputStream} 30 | 31 | 32 | /** 33 | * @author leo 34 | */ 35 | class NumaTest extends MySpec { 36 | 37 | "Numa" should { 38 | "report NUMA info" taggedAs ("report") in { 39 | val available = Numa.isAvailable 40 | val numNodes = Numa.numNodes() 41 | debug("numa is available: " + available) 42 | debug("num nodes: " + numNodes) 43 | for (i <- 0 until numNodes) { 44 | val n = Numa.nodeSize(i) 45 | val f = Numa.freeSize(i) 46 | debug("node %d - size:%,d free:%,d", i, n, f) 47 | } 48 | 49 | 50 | val nodes = (0 until numNodes) 51 | 52 | for (n1 <- nodes; n2 <- n1 until numNodes) { 53 | val d = Numa.distance(n1, n2) 54 | debug("distance %s - %s: %d", n1, n2, d) 55 | } 56 | 57 | def toBitString(b: Array[Long]) = { 58 | val s = for (i <- 0 until Numa.numCPUs()) yield { 59 | if ((b(i / 64) & (1L << (i % 64))) == 0) "0" else "1" 60 | } 61 | s.mkString 62 | } 63 | 64 | for (node <- nodes) { 65 | val cpuVector = Numa.nodeToCpus(node) 66 | debug("node %d -> cpus %s", node, toBitString(cpuVector)) 67 | } 68 | 69 | 70 | val numCPUs = Runtime.getRuntime.availableProcessors(); 71 | val affinity = (0 until numCPUs).par.map { 72 | cpu => 73 | Numa.getAffinity() 74 | } 75 | debug("affinity: %s", affinity.map(toBitString(_)).mkString(", ")) 76 | 77 | val preferred = (0 until numCPUs).par.map { 78 | cpu => 79 | Numa.runOnNode(cpu % numNodes) 80 | Numa.setPreferred(cpu % numNodes) 81 | val n = Numa.getPreferredNode 82 | Numa.runOnAllNodes() 83 | n 84 | } 85 | debug("setting prefererd NUMA nodes: %s", preferred.mkString(", ")) 86 | 87 | 88 | val s = (0 until numCPUs).par.map { 89 | cpu => 90 | Numa.setAffinity((cpu + 1) % numCPUs) 91 | if (cpu % 2 == 0) 92 | (0 until Int.MaxValue / 10).foreach { 93 | i => 94 | } 95 | Numa.getAffinity() 96 | } 97 | debug("affinity after setting: %s", s.map(toBitString(_)).mkString(", ")) 98 | 99 | val r = (0 until numCPUs).par.map { 100 | cpu => 101 | Numa.resetAffinity() 102 | Numa.getAffinity() 103 | } 104 | debug("affinity after resetting: %s", r.map(toBitString(_)).mkString(", ")) 105 | 106 | } 107 | 108 | "allocate local buffer" in { 109 | for (i <- 0 until 3) { 110 | val local = Numa.allocLocal(1024) 111 | Numa.free(local) 112 | } 113 | } 114 | 115 | 116 | "allocate buffer on nodes" in { 117 | 118 | val N = 100000 119 | 120 | def access(b: ByteBuffer) { 121 | val r = new Random(0) 122 | var i = 0 123 | val p = 1024 124 | val buf = new Array[Byte](p) 125 | while (i < N) { 126 | b.position(r.nextInt(b.capacity() / p) * p) 127 | b.get(buf) 128 | i += 1 129 | } 130 | } 131 | val bl = ByteBuffer.allocateDirect(8 * 1024 * 1024) 132 | val bj = ByteBuffer.allocate(8 * 1024 * 1024) 133 | val b0 = Numa.allocOnNode(8 * 1024 * 1024, 0) 134 | val b1 = Numa.allocOnNode(8 * 1024 * 1024, 1) 135 | val bi = Numa.allocInterleaved(8 * 1024 * 1024) 136 | 137 | 138 | time("numa random access", repeat = 10) { 139 | 140 | block("direct") { 141 | access(bl) 142 | } 143 | 144 | block("heap") { 145 | access(bj) 146 | } 147 | 148 | block("numa0") { 149 | access(b0) 150 | } 151 | 152 | block("numa1") { 153 | access(b1) 154 | } 155 | block("interleaved") { 156 | access(bi) 157 | } 158 | } 159 | 160 | 161 | 162 | Numa.free(b0) 163 | Numa.free(b1) 164 | Numa.free(bi) 165 | } 166 | 167 | def radixSort8(buf: ByteBuffer) = { 168 | val K = 256 169 | val N = buf.capacity() 170 | 171 | val pile = Array.ofDim[Int](K) 172 | // count frequencies 173 | buf.position(0) 174 | for (i <- 0 until N) 175 | pile(buf.get(i) + 128) += 1 176 | 177 | // count cumulates 178 | for (i <- 1 until K) { 179 | pile(i) += pile(i - 1) 180 | } 181 | 182 | def split { 183 | for (i <- 0 until N) { 184 | var e = buf.get(i) 185 | var toContinue = true 186 | while (toContinue) { 187 | val p = e + 128 188 | val pileIndex = pile(p) - 1 189 | pile(p) -= 1 190 | if (pileIndex < i) 191 | toContinue = false 192 | else { 193 | val tmp = buf.get(pileIndex) 194 | buf.put(pileIndex, e) 195 | e = tmp 196 | } 197 | } 198 | buf.put(i, e) 199 | } 200 | } 201 | split 202 | } 203 | 204 | 205 | def radixSort8_local(buf: ByteBuffer) = { 206 | val K = 256 207 | val N = buf.capacity() - (2 * 4 * K) 208 | 209 | val countOffset = buf.capacity() / 4 210 | val pileOffset = countOffset + K 211 | 212 | // count frequencies 213 | buf.position(0) 214 | for (i <- 0 until K) { 215 | buf.putInt(countOffset + i * 4, 0) 216 | } 217 | for (i <- 0 until buf.capacity()) { 218 | val ch = buf.get(i) + 128 219 | val prevCount = buf.getInt(countOffset + ch * 4) 220 | buf.putInt(countOffset + ch * 4, prevCount + 1) 221 | } 222 | // count cumulates 223 | for (i <- 0 until K) { 224 | val prev = if (i == 0) 0 else buf.getInt(countOffset + (i - 1) * 4) 225 | val current = buf.getInt(countOffset + i * 4) 226 | buf.putInt(pileOffset + i * 4, prev + current) 227 | } 228 | 229 | def split { 230 | for (i <- 0 until N) { 231 | var e = buf.get(i) 232 | var toContinue = true 233 | while (toContinue) { 234 | val p = e + 128 235 | val pileIndex = buf.getInt(pileOffset + p * 4) - 1 236 | buf.putInt(pileOffset + p * 4, pileIndex) 237 | if (pileIndex < i) 238 | toContinue = false 239 | else { 240 | val tmp = buf.get(pileIndex) 241 | buf.put(pileIndex, e) 242 | e = tmp 243 | } 244 | } 245 | buf.put(i, e) 246 | } 247 | } 248 | split 249 | } 250 | 251 | 252 | 253 | def radixSort8_array(b: Array[Byte]) = { 254 | val K = 256 255 | val N = b.length 256 | val count = new Array[Int](K + 1) 257 | 258 | // count frequencies 259 | for (i <- 0 until N) { 260 | count(b(i) + 128) += 1 261 | } 262 | // count cumulates 263 | for (i <- 1 to K) 264 | count(i) += count(i - 1) 265 | 266 | def split { 267 | val pile = new Array[Int](K + 1) 268 | Array.copy(count, 1, pile, 0, K) 269 | for (i <- 0 until N) { 270 | var e = b(i) 271 | var toContinue = true 272 | while (toContinue) { 273 | val p = e + 128 274 | val pileIndex = pile(p) - 1 275 | pile(p) -= 1 276 | if (pileIndex < i) 277 | toContinue = false 278 | else { 279 | val tmp = b(pileIndex) 280 | b(pileIndex) = e 281 | e = tmp 282 | } 283 | } 284 | b(i) = e 285 | } 286 | } 287 | split 288 | } 289 | 290 | 291 | "perform microbenchmark" taggedAs ("bench") in { 292 | 293 | val bufferSize = 4 * 1024 * 1024 294 | when("buffer size is %,d".format(bufferSize)) 295 | 296 | val numaBufs = (for (i <- 0 until Numa.numNodes()) yield "numa%d".format(i) -> Numa.allocOnNode(bufferSize, i)) :+ 297 | "numa-i" -> Numa.allocInterleaved(bufferSize) 298 | 299 | 300 | //val bdirect = ByteBuffer.allocateDirect(bufferSize) 301 | val bheap = ByteBuffer.allocate(bufferSize).order(ByteOrder.nativeOrder()); 302 | 303 | val bufs = numaBufs ++ Map("heap" -> bheap) 304 | 305 | // fill bytes 306 | def fillBytes(b: ByteBuffer) = { 307 | var i = 0 308 | b.clear() 309 | while (b.remaining() > 0) { 310 | b.put(i.toByte) 311 | i += 1 312 | } 313 | } 314 | 315 | def fillInt(b: ByteBuffer) = { 316 | val r = new Random(0) 317 | b.clear() 318 | var i = 0 319 | while (b.remaining() >= 4) { 320 | b.putInt(r.nextInt()) 321 | i += 1 322 | } 323 | } 324 | 325 | val devNull = new FileOutputStream("/dev/null") 326 | def dump(b: ByteBuffer) = { 327 | b.position(0) 328 | b.limit(b.capacity()) 329 | devNull.getChannel().write(b) 330 | } 331 | 332 | def randomAccess(b: ByteBuffer) = { 333 | val r = new Random(0) 334 | val pageSize = 128 335 | val maxPage = b.capacity() / pageSize 336 | var i = 0 337 | val buf = new Array[Byte](pageSize) 338 | while (i < 100000) { 339 | b.position(r.nextInt(maxPage) * pageSize) 340 | b.get(buf) 341 | i += 1 342 | } 343 | } 344 | 345 | 346 | 347 | def bench[U](name: String, f: ByteBuffer => U, rep: Int = 3) { 348 | time(name, repeat = rep) { 349 | for ((name, b) <- bufs) 350 | block(name) { 351 | f(b) 352 | } 353 | } 354 | } 355 | 356 | bench("fill byte", fillBytes) 357 | bench("fill int", fillInt) 358 | bench("dump to /dev/null", dump) 359 | bench("random page read", randomAccess) 360 | 361 | val R = 1 362 | bench("radix sort", radixSort8, rep = R) 363 | val ba = Array.ofDim[Byte](bufferSize) 364 | val r = new Random(0) 365 | for (i <- 0 until bufferSize / 4) { 366 | val v = r.nextInt 367 | ba(i) = ((v >> 24) & 0xFF).toByte 368 | ba(i + 1) = ((v >> 16) & 0xFF).toByte 369 | ba(i + 2) = ((v >> 8) & 0xFF).toByte 370 | ba(i + 3) = (v & 0xFF).toByte 371 | } 372 | 373 | time("radix sort on java array", repeat = R) { 374 | radixSort8_array(ba) 375 | } 376 | 377 | 378 | for ((name, b) <- numaBufs) 379 | Numa.free(b) 380 | } 381 | 382 | def boundTo[U](cpu: Int)(f: => U): U = { 383 | try { 384 | Numa.setAffinity(cpu) 385 | f 386 | } 387 | finally 388 | Numa.resetAffinity 389 | } 390 | 391 | "sort in parallel" taggedAs ("psort") in { 392 | 393 | val bufferSize = 1024 * 1024 394 | 395 | def init(b: ByteBuffer) { 396 | val r = new Random(0) 397 | for (i <- 0 until bufferSize) { 398 | b.put(i, r.nextInt.toByte) 399 | } 400 | } 401 | val N = 1 402 | 403 | 404 | val holder = Seq.newBuilder[ByteBuffer] 405 | val C = Numa.numCPUs 406 | debug("start parallel sorting using %d CPUs", C) 407 | time("sorting", repeat = 3) { 408 | block("numa-aware", repeat = N) { 409 | val M = Numa.numNodes 410 | (0 until C).par.foreach { 411 | cpu => 412 | boundTo(cpu) { 413 | val node = cpu % M; 414 | Numa.runOnNode(node) 415 | Numa.setPreferred(node) 416 | val buf = Numa.allocOnNode(bufferSize, node) 417 | holder += buf 418 | init(buf) 419 | radixSort8(buf) 420 | Numa.runOnAllNodes(); 421 | Numa.setLocalAlloc(); 422 | } 423 | } 424 | } 425 | 426 | // block("numa-aware-local", repeat=N) { 427 | // val M = Numa.numNodes 428 | // (0 until C).par.foreach { cpu => 429 | // boundTo(cpu) { 430 | // val buf = Numa.allocOnNode(bufferSize, cpu % M) 431 | // holder += buf 432 | // init(buf) 433 | // radixSort8_local(buf) 434 | // } 435 | // } 436 | // } 437 | 438 | block("heap", repeat = N) { 439 | (0 until C).par.foreach { 440 | cpu => 441 | boundTo(cpu) { 442 | val buf = ByteBuffer.allocate(bufferSize) 443 | init(buf) 444 | radixSort8(buf) 445 | } 446 | } 447 | } 448 | 449 | block("wrapped", repeat = N) { 450 | (0 until C).par.foreach { 451 | cpu => 452 | boundTo(cpu) { 453 | val arr = new Array[Byte](bufferSize) 454 | val buf = ByteBuffer.wrap(arr) 455 | init(buf) 456 | radixSort8(buf) 457 | } 458 | } 459 | } 460 | 461 | 462 | } 463 | 464 | holder.result.foreach(b => Numa.free(b)) 465 | } 466 | 467 | "allocate more than 2GB array" taggedAs("long") in { 468 | val N = 4L * 1024L * 1024L * 1024L 469 | for(i <- 0 until 10) { 470 | debug("alloc") 471 | val addr = Numa.allocMemory(N) 472 | debug("free") 473 | Numa.free(addr, N) 474 | } 475 | } 476 | 477 | 478 | "allocate memory and a CPU to a specific node" taggedAs ("pref") in { 479 | 480 | val numCPU = Numa.numCPUs 481 | val bufferSize = 1024 * 1024 482 | def newArray = { 483 | val a = Array.ofDim[Int](bufferSize) 484 | val r = new Random(0) 485 | for (i <- 0 until bufferSize) 486 | a(i) = r.nextInt 487 | a 488 | } 489 | 490 | debug("start Array sorting") 491 | val R = 2 492 | val RR = 10 493 | time("alloc", repeat = R) { 494 | 495 | block("numa-aware", repeat=RR) { 496 | val M = Numa.numNodes 497 | (0 until numCPU).par.foreach { 498 | cpu => 499 | boundTo(cpu) { 500 | val node = cpu % M 501 | Numa.runOnNode(node) 502 | Numa.setPreferred(node) 503 | val a = newArray 504 | util.Arrays.sort(a) 505 | Numa.runOnAllNodes() 506 | Numa.setLocalAlloc() 507 | } 508 | } 509 | } 510 | 511 | block("numa-anti", repeat=RR) { 512 | val M = Numa.numNodes 513 | (0 until numCPU).par.foreach { 514 | cpu => 515 | boundTo(cpu) { 516 | val node = (cpu + 1) % M 517 | Numa.setPreferred(node) 518 | val a = newArray 519 | util.Arrays.sort(a) 520 | Numa.setLocalAlloc() 521 | } 522 | } 523 | } 524 | 525 | block("default", repeat=RR) { 526 | (0 until numCPU).par.foreach { 527 | cpu => 528 | boundTo(cpu) { 529 | val a = newArray 530 | util.Arrays.sort(a) 531 | Numa.runOnAllNodes() 532 | Numa.setLocalAlloc() 533 | } 534 | } 535 | } 536 | 537 | 538 | } 539 | } 540 | 541 | "retrieve memory from another nodes" taggedAs("remote") in { 542 | 543 | val prop = System.getProperty("jnuma.test.bf", "8192") 544 | debug("buffer size: %s", prop) 545 | val B = prop.toInt 546 | def access(b:ByteBuffer) { 547 | b.position(0) 548 | for(i <- 0 until B) { 549 | b.get 550 | } 551 | } 552 | 553 | def alloc(f: => ByteBuffer) { 554 | val r = new Random(13) 555 | val b = f 556 | b.position(0) 557 | for(i <- 0 until B / 4) 558 | b.putInt(r.nextInt()) 559 | // b.position(0) 560 | // for(i <- 0 until B / 4) 561 | // b.getInt 562 | radixSort8(b) 563 | Numa.free(b) 564 | } 565 | 566 | Numa.runOnNode(0) 567 | debug("using a cpu on node %d", 0) 568 | time("numa") { 569 | block("node0") { 570 | alloc(Numa.allocOnNode(B, 0)) 571 | } 572 | 573 | block("node1") { 574 | alloc(Numa.allocOnNode(B, 1)) 575 | } 576 | 577 | block("iv") { 578 | alloc(Numa.allocInterleaved(B)) 579 | } 580 | } 581 | 582 | Numa.runOnAllNodes() 583 | } 584 | 585 | "retrieve array from another node" taggedAs("jarray") in { 586 | 587 | val B = 1024 * 1024 588 | 589 | def alloc(f: => Array[Int]) { 590 | val r = new Random(13) 591 | for(i <- 0 until 1000) { 592 | val arr = f 593 | for(index <- 0 until B / 4) 594 | arr(index) = r.nextInt() 595 | } 596 | } 597 | 598 | Numa.runOnNode(0) 599 | debug("using a cpu on node %d", 0) 600 | time("numa", repeat=2) { 601 | block("node0") { 602 | debug("allocate array on node 0") 603 | Numa.setPreferred(0) 604 | alloc{ 605 | val a = new Array[Int](B) 606 | Numa.toNodeMemory(a, B * 4, 0) 607 | a 608 | } 609 | Numa.setLocalAlloc 610 | } 611 | 612 | block("node1") { 613 | debug("allocate array on node 1") 614 | Numa.setPreferred(1) 615 | alloc{ 616 | val a = new Array[Int](B) 617 | Numa.toNodeMemory(a, B * 4, 1) 618 | a 619 | } 620 | Numa.setLocalAlloc 621 | } 622 | } 623 | 624 | Numa.runOnAllNodes() 625 | } 626 | 627 | "bulk parallel write" taggedAs("pwrite") in { 628 | pending 629 | val C = Numa.numCPUs 630 | 631 | val bufferSize = 1024 * 1024 * 1024 632 | val WR = 1 633 | 634 | def writeBench(cpu:Int, b:ByteBuffer) { 635 | (0 until WR).foreach { r => 636 | for(i <- 0 until bufferSize / 256) { 637 | b.put(i, Random.nextInt(256).toByte) 638 | if(cpu == 0 && i > 0 && (i % (1024 * 1024)) == 0) { 639 | debug("wrote at %,d bytes", i) 640 | } 641 | } 642 | } 643 | } 644 | 645 | time("pwrite", repeat=2) { 646 | block("heap") { 647 | debug("heap write") 648 | (0 until C).par.foreach { cpu => 649 | boundTo(cpu) { 650 | val b = ByteBuffer.allocate(bufferSize) 651 | writeBench(cpu, b) 652 | } 653 | } 654 | } 655 | 656 | block("numa") { 657 | debug("numa local write") 658 | (0 until C).par.foreach { cpu => 659 | boundTo(cpu) { 660 | val b = Numa.allocLocal(bufferSize) 661 | writeBench(cpu, b) 662 | Numa.free(b) 663 | } 664 | } 665 | } 666 | } 667 | } 668 | 669 | "allocate memory" in { 670 | val size = 1L * 1024 * 1024 671 | var addr : Long = 0L 672 | try { 673 | addr = Numa.allocMemory(size) 674 | } 675 | finally { 676 | if(addr != 0L) 677 | Numa.free(addr, size) 678 | } 679 | 680 | } 681 | 682 | } 683 | } 684 | -------------------------------------------------------------------------------- /version.sbt: -------------------------------------------------------------------------------- 1 | version in ThisBuild := "0.1.3" 2 | --------------------------------------------------------------------------------