This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
#include <jni.h>
|
|
|
|
|
#include <assert.h>
|
2015-12-17 16:19:44 -08:00
|
|
|
#include <atomic>
|
|
|
|
|
#include <condition_variable>
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
#include <functional>
|
2015-12-17 16:19:44 -08:00
|
|
|
#include <mutex>
|
|
|
|
|
#include <thread>
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
#include <stdio.h>
|
|
|
|
|
#include "Log.hpp"
|
|
|
|
|
#include "edu_wpi_first_wpilibj_hal_NotifierJNI.h"
|
|
|
|
|
#include "HAL/Notifier.hpp"
|
2015-11-01 09:11:52 -08:00
|
|
|
#include "HALUtil.h"
|
2015-12-17 16:19:44 -08:00
|
|
|
#include "SafeThread.h"
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
|
|
|
|
// set the logging level
|
|
|
|
|
TLogLevel notifierJNILogLevel = logWARNING;
|
|
|
|
|
|
|
|
|
|
#define NOTIFIERJNI_LOG(level) \
|
|
|
|
|
if (level > notifierJNILogLevel) ; \
|
|
|
|
|
else Log().Get(level)
|
|
|
|
|
|
2015-12-17 16:19:44 -08:00
|
|
|
// Thread where callbacks are actually performed.
|
|
|
|
|
//
|
|
|
|
|
// JNI's AttachCurrentThread() creates a Java Thread object on every
|
|
|
|
|
// invocation, which is both time inefficient and causes issues with Eclipse
|
|
|
|
|
// (which tries to keep a thread list up-to-date and thus gets swamped).
|
|
|
|
|
//
|
|
|
|
|
// Instead, this class attaches just once. When a hardware notification
|
|
|
|
|
// occurs, a condition variable wakes up this thread and this thread actually
|
|
|
|
|
// makes the call into Java.
|
|
|
|
|
//
|
|
|
|
|
// We don't want to use a FIFO here. If the user code takes too long to
|
|
|
|
|
// process, we will just ignore the redundant wakeup.
|
|
|
|
|
class NotifierThreadJNI : public SafeThread {
|
|
|
|
|
public:
|
|
|
|
|
void Main();
|
|
|
|
|
|
|
|
|
|
bool m_notify = false;
|
|
|
|
|
jobject m_func = nullptr;
|
|
|
|
|
jmethodID m_mid;
|
2015-12-30 19:06:47 -08:00
|
|
|
uint64_t m_currentTime;
|
2015-12-17 16:19:44 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class NotifierJNI : public SafeThreadOwner<NotifierThreadJNI> {
|
|
|
|
|
public:
|
|
|
|
|
void SetFunc(JNIEnv* env, jobject func, jmethodID mid);
|
|
|
|
|
|
2015-12-30 19:06:47 -08:00
|
|
|
void Notify(uint64_t currentTime) {
|
2015-12-17 16:19:44 -08:00
|
|
|
auto thr = GetThread();
|
|
|
|
|
if (!thr) return;
|
|
|
|
|
thr->m_currentTime = currentTime;
|
|
|
|
|
thr->m_notify = true;
|
|
|
|
|
thr->m_cond.notify_one();
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
2015-12-17 16:19:44 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
void NotifierJNI::SetFunc(JNIEnv* env, jobject func, jmethodID mid) {
|
|
|
|
|
auto thr = GetThread();
|
|
|
|
|
if (!thr) return;
|
|
|
|
|
// free global reference
|
|
|
|
|
if (thr->m_func) env->DeleteGlobalRef(thr->m_func);
|
|
|
|
|
// create global reference
|
|
|
|
|
thr->m_func = env->NewGlobalRef(func);
|
|
|
|
|
thr->m_mid = mid;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void NotifierThreadJNI::Main() {
|
|
|
|
|
JNIEnv *env;
|
|
|
|
|
JavaVMAttachArgs args;
|
|
|
|
|
args.version = JNI_VERSION_1_2;
|
|
|
|
|
args.name = const_cast<char*>("Notifier");
|
|
|
|
|
args.group = nullptr;
|
|
|
|
|
jint rs = jvm->AttachCurrentThreadAsDaemon((void**)&env, &args);
|
|
|
|
|
if (rs != JNI_OK) return;
|
|
|
|
|
|
|
|
|
|
std::unique_lock<std::mutex> lock(m_mutex);
|
|
|
|
|
while (m_active) {
|
|
|
|
|
m_cond.wait(lock, [&] { return !m_active || m_notify; });
|
|
|
|
|
if (!m_active) break;
|
|
|
|
|
m_notify = false;
|
|
|
|
|
if (!m_func) continue;
|
|
|
|
|
jobject func = m_func;
|
|
|
|
|
jmethodID mid = m_mid;
|
2015-12-30 19:06:47 -08:00
|
|
|
uint64_t currentTime = m_currentTime;
|
2015-12-17 16:19:44 -08:00
|
|
|
lock.unlock(); // don't hold mutex during callback execution
|
2015-12-30 19:06:47 -08:00
|
|
|
env->CallVoidMethod(func, mid, (jlong)currentTime);
|
2015-12-17 16:19:44 -08:00
|
|
|
if (env->ExceptionCheck()) {
|
|
|
|
|
env->ExceptionDescribe();
|
|
|
|
|
env->ExceptionClear();
|
|
|
|
|
}
|
|
|
|
|
lock.lock();
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
2015-12-17 16:19:44 -08:00
|
|
|
|
|
|
|
|
// free global reference
|
|
|
|
|
if (m_func) env->DeleteGlobalRef(m_func);
|
|
|
|
|
|
|
|
|
|
jvm->DetachCurrentThread();
|
|
|
|
|
}
|
|
|
|
|
|
2015-12-30 19:06:47 -08:00
|
|
|
void notifierHandler(uint64_t currentTimeInt, void* param) {
|
2015-12-17 16:19:44 -08:00
|
|
|
((NotifierJNI*)param)->Notify(currentTimeInt);
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
|
|
|
|
|
2015-11-01 09:11:52 -08:00
|
|
|
extern "C" {
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: edu_wpi_first_wpilibj_hal_NotifierJNI
|
|
|
|
|
* Method: initializeNotifier
|
2015-11-01 09:11:52 -08:00
|
|
|
* Signature: (Ljava/lang/Runnable;)J
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
*/
|
2015-11-01 09:11:52 -08:00
|
|
|
JNIEXPORT jlong JNICALL Java_edu_wpi_first_wpilibj_hal_NotifierJNI_initializeNotifier
|
|
|
|
|
(JNIEnv *env, jclass, jobject func)
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
{
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI initializeNotifier";
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
|
|
|
|
jclass cls = env->GetObjectClass(func);
|
2015-12-17 16:19:44 -08:00
|
|
|
if (cls == 0) {
|
|
|
|
|
NOTIFIERJNI_LOG(logERROR) << "Error getting java class";
|
|
|
|
|
assert(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2015-12-30 19:06:47 -08:00
|
|
|
jmethodID mid = env->GetMethodID(cls, "apply", "(J)V");
|
2015-12-17 16:19:44 -08:00
|
|
|
if (mid == 0) {
|
|
|
|
|
NOTIFIERJNI_LOG(logERROR) << "Error getting java method ID";
|
|
|
|
|
assert(false);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// each notifier runs in its own thread; this is so if one takes too long
|
|
|
|
|
// to execute, it doesn't keep the others from running
|
|
|
|
|
NotifierJNI* notify = new NotifierJNI;
|
|
|
|
|
notify->Start();
|
|
|
|
|
notify->SetFunc(env, func, mid);
|
|
|
|
|
int32_t status = 0;
|
|
|
|
|
void *notifierPtr = initializeNotifier(notifierHandler, notify, &status);
|
|
|
|
|
|
|
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Notifier Ptr = " << notifierPtr;
|
|
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
|
|
|
|
|
|
|
|
|
|
if (!notifierPtr || !CheckStatus(env, status)) {
|
|
|
|
|
// something went wrong in HAL, clean up
|
|
|
|
|
delete notify;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (jlong)notifierPtr;
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: edu_wpi_first_wpilibj_hal_NotifierJNI
|
|
|
|
|
* Method: cleanNotifier
|
2015-11-01 09:11:52 -08:00
|
|
|
* Signature: (J)V
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
*/
|
2015-11-01 09:11:52 -08:00
|
|
|
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_NotifierJNI_cleanNotifier
|
|
|
|
|
(JNIEnv *env, jclass, jlong notifierPtr)
|
|
|
|
|
{
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI cleanNotifier";
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Notifier Ptr = " << (void *)notifierPtr;
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
2015-11-01 09:11:52 -08:00
|
|
|
int32_t status = 0;
|
2015-12-17 16:19:44 -08:00
|
|
|
NotifierJNI* notify =
|
|
|
|
|
(NotifierJNI*)getNotifierParam((void*)notifierPtr, &status);
|
2015-11-01 09:11:52 -08:00
|
|
|
cleanNotifier((void*)notifierPtr, &status);
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
|
|
|
|
|
CheckStatus(env, status);
|
|
|
|
|
delete notify;
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: edu_wpi_first_wpilibj_hal_NotifierJNI
|
|
|
|
|
* Method: updateNotifierAlarm
|
2015-12-30 19:06:47 -08:00
|
|
|
* Signature: (JJ)V
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
*/
|
2015-11-01 09:11:52 -08:00
|
|
|
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_NotifierJNI_updateNotifierAlarm
|
2015-12-30 19:06:47 -08:00
|
|
|
(JNIEnv *env, jclass cls, jlong notifierPtr, jlong triggerTime)
|
2015-11-01 09:11:52 -08:00
|
|
|
{
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI updateNotifierAlarm";
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Notifier Ptr = " << (void *)notifierPtr;
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "triggerTime = " << triggerTime;
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
|
2015-11-01 09:11:52 -08:00
|
|
|
int32_t status = 0;
|
2015-12-30 19:06:47 -08:00
|
|
|
updateNotifierAlarm((void*)notifierPtr, (uint64_t)triggerTime, &status);
|
2015-12-17 16:19:44 -08:00
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
|
|
|
|
|
CheckStatus(env, status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Class: edu_wpi_first_wpilibj_hal_NotifierJNI
|
|
|
|
|
* Method: stopNotifierAlarm
|
|
|
|
|
* Signature: (J)V
|
|
|
|
|
*/
|
|
|
|
|
JNIEXPORT void JNICALL Java_edu_wpi_first_wpilibj_hal_NotifierJNI_stopNotifierAlarm
|
|
|
|
|
(JNIEnv *env, jclass cls, jlong notifierPtr)
|
|
|
|
|
{
|
|
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Calling NOTIFIERJNI stopNotifierAlarm";
|
|
|
|
|
|
|
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Notifier Ptr = " << (void *)notifierPtr;
|
|
|
|
|
|
|
|
|
|
int32_t status = 0;
|
|
|
|
|
stopNotifierAlarm((void*)notifierPtr, &status);
|
|
|
|
|
NOTIFIERJNI_LOG(logDEBUG) << "Status = " << status;
|
|
|
|
|
CheckStatus(env, status);
|
This commit adds JNI bindings for the C++ Notifier.
The bindings only wrap the HAL interface, rather than the entire C++ Notifier,
as I ran into issues trying to wrap the whole Notifier (all the existing
bindings only wrap HAL components, so wrapping stuff in :wpilibc is
unexplored). As such, the new edu.wpi.first.wpilibj.Notifier is just a
re-implementation of the wpilibc/.../Notifier.cpp.
The purpose of doing this bindings is to allow Java users a better option
for running tasks which require good timing (such as control loops). The
previous method used java.util.Timer to schedule a task, causing various
issues. Although this update does improve things, Java loop timing is still
substantially worse than that of C++, and, even worse, if Java decides to call
the garbage collector at the wrong time then the loop can be delayed by
multiple milliseconds and the next iteration will be shorter to account for it
(although this particular behavior could be updated).
A few notes on individual components:
-the HAL Task.hpp and Task.cpp were modified due to compilation/linkage
issues with the JNI bindings. Nothing substantive changed.
-NotifierJNI was added to the build files for gradle.
-HALUtil was modified to include a function for getting the length of a C
pointer, rather than relying on it being 32-bit.
Change-Id: I966512d8a82c2a438ed8c8bbcc6cdc6ed186d0f2
2015-06-02 14:00:47 -04:00
|
|
|
}
|
2015-11-01 09:11:52 -08:00
|
|
|
|
|
|
|
|
} // extern "C"
|