Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Move some functions from MsgNative to Task, to make one less call
[simgrid.git] / src / jmsg_task.c
1 /* Functions related to the java task instances.                            */
2
3 /* Copyright (c) 2007, 2009, 2010. The SimGrid Team.
4  * All rights reserved.                                                     */
5
6 /* This program is free software; you can redistribute it and/or modify it
7   * under the terms of the license (GNU LGPL) which comes with this package. */
8
9 #include "jmsg.h"
10 #include "jmsg_task.h"
11 #include "jxbt_utilities.h"
12 #include "jmsg_host.h"
13
14 #include <msg/msg.h>
15 XBT_LOG_EXTERNAL_DEFAULT_CATEGORY(jmsg);
16
17 static jmethodID jtask_field_Comm_constructor;
18
19 static jfieldID jtask_field_Task_bind;
20 static jfieldID jtask_field_Comm_bind;
21 static jfieldID jtask_field_Comm_taskBind;
22 static jfieldID jtask_field_Comm_receiving;
23
24 void jtask_bind(jobject jtask, m_task_t task, JNIEnv * env)
25 {
26   (*env)->SetLongField(env, jtask, jtask_field_Task_bind, (jlong) (long) (task));
27 }
28
29 m_task_t jtask_to_native_task(jobject jtask, JNIEnv * env)
30 {
31   return (m_task_t) (long) (*env)->GetLongField(env, jtask, jtask_field_Task_bind);
32 }
33
34 jboolean jtask_is_valid(jobject jtask, JNIEnv * env)
35 {
36   return (*env)->GetLongField(env, jtask, jtask_field_Task_bind) ? JNI_TRUE : JNI_FALSE;
37 }
38
39 JNIEXPORT void JNICALL
40 Java_org_simgrid_msg_Task_nativeInit(JNIEnv *env, jclass cls) {
41         jclass jtask_class_Comm = (*env)->FindClass(env, "org/simgrid/msg/Comm");
42
43         jtask_field_Comm_constructor = (*env)->GetMethodID(env, jtask_class_Comm, "<init>", "()V");
44         //FIXME: Don't use jxbt_get_sfield directly.
45         jtask_field_Task_bind = jxbt_get_sfield(env, "org/simgrid/msg/Task", "bind", "J");
46         jtask_field_Comm_bind = jxbt_get_sfield(env, "org/simgrid/msg/Comm", "bind", "J");
47         jtask_field_Comm_taskBind = jxbt_get_sfield(env, "org/simgrid/msg/Comm", "taskBind", "J");
48         jtask_field_Comm_receiving = jxbt_get_sfield(env, "org/simgrid/msg/Comm", "receiving", "Z");
49 }
50
51 JNIEXPORT void JNICALL
52 Java_org_simgrid_msg_Task_create(JNIEnv * env,
53                                       jobject jtask, jstring jname,
54                                       jdouble jcomputeDuration,
55                                       jdouble jmessageSize)
56 {
57   m_task_t task;                /* the native task to create                            */
58   const char *name = NULL;      /* the name of the task                                 */
59
60   if (jcomputeDuration < 0) {
61     jxbt_throw_illegal(env,
62                        bprintf
63                        ("Task ComputeDuration (%f) cannot be negative",
64                         (double) jcomputeDuration));
65     return;
66   }
67
68   if (jmessageSize < 0) {
69     jxbt_throw_illegal(env,
70                        bprintf("Task MessageSize (%f) cannot be negative",
71                                (double) jmessageSize));
72     return;
73   }
74
75   if (jname) {
76     /* get the C string from the java string */
77     name = (*env)->GetStringUTFChars(env, jname, 0);
78   }
79
80
81   /* create the task */
82   task =
83       MSG_task_create(name, (double) jcomputeDuration,
84                       (double) jmessageSize, NULL);
85   if (jname)
86     (*env)->ReleaseStringUTFChars(env, jname, name);
87
88   /* bind & store the task */
89   jtask_bind(jtask, task, env);
90   MSG_task_set_data(task, jtask);
91 }
92
93 JNIEXPORT void JNICALL
94 Java_org_simgrid_msg_Task_parallelCreate(JNIEnv * env,
95                                                jobject jtask,
96                                                jstring jname,
97                                                jobjectArray jhosts,
98                                                jdoubleArray
99                                                jcomputeDurations_arg,
100                                                jdoubleArray
101                                                jmessageSizes_arg) {
102
103   m_task_t task;                /* the native parallel task to create           */
104   const char *name;             /* the name of the task                         */
105   int host_count;
106   m_host_t *hosts;
107   double *computeDurations;
108   double *messageSizes;
109   jdouble *jcomputeDurations;
110   jdouble *jmessageSizes;
111
112   jobject jhost;
113   int index;
114
115
116   if (!jcomputeDurations_arg) {
117     jxbt_throw_null(env,
118                     xbt_strdup
119                     ("Parallel task compute durations cannot be null"));
120     return;
121   }
122
123   if (!jmessageSizes_arg) {
124     jxbt_throw_null(env,
125                     xbt_strdup
126                     ("Parallel task message sizes cannot be null"));
127     return;
128   }
129
130   if (!jname) {
131     jxbt_throw_null(env, xbt_strdup("Parallel task name cannot be null"));
132     return;
133   }
134
135   host_count = (int) (*env)->GetArrayLength(env, jhosts);
136
137
138   hosts = xbt_new0(m_host_t, host_count);
139   computeDurations = xbt_new0(double, host_count);
140   messageSizes = xbt_new0(double, host_count * host_count);
141
142   jcomputeDurations =
143       (*env)->GetDoubleArrayElements(env, jcomputeDurations_arg, 0);
144   jmessageSizes =
145       (*env)->GetDoubleArrayElements(env, jmessageSizes_arg, 0);
146
147   for (index = 0; index < host_count; index++) {
148     jhost = (*env)->GetObjectArrayElement(env, jhosts, index);
149     hosts[index] = jhost_get_native(env, jhost);
150     computeDurations[index] = jcomputeDurations[index];
151   }
152   for (index = 0; index < host_count * host_count; index++) {
153     messageSizes[index] = jmessageSizes[index];
154   }
155
156   (*env)->ReleaseDoubleArrayElements(env, jcomputeDurations_arg,
157                                      jcomputeDurations, 0);
158   (*env)->ReleaseDoubleArrayElements(env, jmessageSizes_arg, jmessageSizes,
159                                      0);
160
161
162   /* get the C string from the java string */
163   name = (*env)->GetStringUTFChars(env, jname, 0);
164
165   task =
166       MSG_parallel_task_create(name, host_count, hosts, computeDurations,
167                                messageSizes, NULL);
168
169   (*env)->ReleaseStringUTFChars(env, jname, name);
170
171   /* associate the java task object and the native task */
172   jtask_bind(jtask, task, env);
173
174   MSG_task_set_data(task, (void *) jtask);
175
176   if (!MSG_task_get_data(task))
177     jxbt_throw_jni(env, "global ref allocation failed");
178 }
179
180 JNIEXPORT jstring JNICALL
181 Java_org_simgrid_msg_Task_getName(JNIEnv * env,
182                                        jobject jtask) {
183   m_task_t task = jtask_to_native_task(jtask, env);
184
185   if (!task) {
186     jxbt_throw_notbound(env, "task", jtask);
187     return NULL;
188   }
189
190   return (*env)->NewStringUTF(env, MSG_task_get_name(task));
191 }
192
193 JNIEXPORT jobject JNICALL
194 Java_org_simgrid_msg_Task_irecv(JNIEnv * env, jclass cls, jstring jmailbox) {
195         msg_comm_t comm;
196         const char *mailbox;
197         jclass comm_class;
198         //pointer to store the task object pointer.
199         m_task_t *task = xbt_new(m_task_t,1);
200         *task = NULL;
201         /* There should be a cache here */
202         comm_class = (*env)->FindClass(env, "org/simgrid/msg/Comm");
203
204         if (!comm_class) {
205                 jxbt_throw_native(env,bprintf("fieldID or methodID or class not found."));
206                 return NULL;
207         }
208
209         jobject jcomm = (*env)->NewObject(env, comm_class, jtask_field_Comm_constructor);
210         if (!jcomm) {
211                 jxbt_throw_native(env,bprintf("Can't create a Comm object."));
212                 return NULL;
213         }
214
215         mailbox = (*env)->GetStringUTFChars(env, jmailbox, 0);
216
217         comm = MSG_task_irecv(task,mailbox);
218
219         (*env)->SetLongField(env, jcomm, jtask_field_Comm_bind, (jlong) (long)(comm));
220         (*env)->SetLongField(env, jcomm, jtask_field_Comm_taskBind, (jlong) (long)(task));
221         (*env)->SetBooleanField(env, jcomm, jtask_field_Comm_receiving, JNI_TRUE);
222
223         (*env)->ReleaseStringUTFChars(env, jmailbox, mailbox);
224
225         return jcomm;
226 }
227
228 JNIEXPORT jobject JNICALL
229 Java_org_simgrid_msg_Task_isend(JNIEnv *env, jobject jtask, jstring jmailbox) {
230         jclass comm_class;
231
232         const char *mailbox;
233
234         m_task_t task;
235
236         jobject jcomm;
237         msg_comm_t comm;
238
239         comm_class = (*env)->FindClass(env, "org/simgrid/msg/Comm");
240
241         if (!comm_class) return NULL;
242
243         jcomm = (*env)->NewObject(env, comm_class, jtask_field_Comm_constructor);
244         mailbox = (*env)->GetStringUTFChars(env, jmailbox, 0);
245
246         task = jtask_to_native_task(jtask, env);
247
248         if (!task) {
249     (*env)->ReleaseStringUTFChars(env, jmailbox, mailbox);
250     (*env)->DeleteLocalRef(env, jcomm);
251     jxbt_throw_notbound(env, "task", jtask);
252                 return NULL;
253         }
254
255   MSG_task_set_data(task, (void *) (*env)->NewGlobalRef(env, jtask));
256         comm = MSG_task_isend(task,mailbox);
257
258         (*env)->SetLongField(env, jcomm, jtask_field_Comm_bind, (jlong) (long)(comm));
259         (*env)->SetLongField(env, jcomm, jtask_field_Comm_taskBind, (jlong) (long)(NULL));
260         (*env)->SetBooleanField(env, jcomm, jtask_field_Comm_receiving, JNI_FALSE);
261
262         (*env)->ReleaseStringUTFChars(env, jmailbox, mailbox);
263
264         return jcomm;
265 }