2

I'm trying to implement a java wrapper for RCSwitch in a Raspberry Pi. It works fine until the grabbing method reaches the 80th iteration. Then it slows down and I can't figure out why. It needs more than 5 minutes to return with a value. I tried to figure out the problem, but I'm not out of memory, the raspberry still has more then 300mega. In spite ot this, I tried to run the JVM with the following parameter:-Xms5m -Xmx5m but the program still slowed down at the 80th iteration so I think its not a memory problem. My sender still sends the value, because if I restart the program it's working again until the 80th iteration, so it's not the lack of input data.

Here is the java part of the code:

public class RCSwitchWrapper {
    public native int recievedValue(int PIN);
    static{System.loadLibrary("RCSwitchWrapper");}

    public static void main(String[] args){
        RCSwitchWrapper wrapper = new RCSwitchWrapper();
        int counter=0;
        while(true){
            counter++;
            int grabbedData = wrapper.recievedValue(2);
            System.out.println(counter+" grabbed data: "+grabbedData);
        }
    }
}

The C++ part of the code:

#include "RCSwitch.h"
#include "RCSwitchWrapper.h"
#include <stdlib.h>
#include <stdio.h>
#include <iostream>

RCSwitch mySwitch;
JNIEXPORT jint JNICALL Java_RCSwitchWrapper_recieveValue(JNIEnv *env, jobject obj,jint PIN){
    if(wiringPiSetup()==-1){
        printf("wiringpi error \n");
        return 0;
    }
    mySwitch = RCSwitch();
    mySwitch.enableReceive(PIN);
    while(1){
        if(mySwitch.available()){
            int value = mySwitch.getReceivedValue();
            return value;
        }
        mySwitch.resetAvailable();
        return(-1);        
    }
} 

Now I'm confused and can't think a solution.

Thanks in advance.

Michael
  • 57,169
  • 9
  • 80
  • 125
blase
  • 67
  • 1
  • 8
  • Can you disable or otherwise control execution of garbage collection to remove that as a variable? – technomage May 21 '15 at 14:42
  • No, I can't. But I thought earlyer that, maybe there is an invoking GCthread what is blockink my main thread, so i used jstat and that said my GC is not ran for a single milisecond. So i don't think the GC is my problem. – blase May 21 '15 at 18:36
  • You might also try a `Thread.yield/sleep()` in your loop to give some other parts of the system more of a chance to run. – technomage May 21 '15 at 19:48
  • I just tried `Thread.sleep(4000);` and it still become slow at 80. – blase May 21 '15 at 20:23
  • Can you enable any sort of call/call graph profiling to determine what is consuming time when the slowdown happen? Maybe pause the system and attach a debugger to examine threads, or periodically dump stack? Is it the call _into_ the native code itself, or some _part_ of the native code (i.e. `mySwitch.getReceivedValue()`). Is it possible that your hardware (or whatever is behind `mySwitch`) is blocking? – technomage May 22 '15 at 12:11
  • I don't really know how to do that. I have only CLI. I tried to run just the native code without the java part, and it worked perfectly. – blase May 22 '15 at 18:03
  • Is there some trigger present in your native test that is absent the Java test? What does the native `RCSwitch::getReceivedValue()` do? Learn how to do the things I suggested, they will serve will in other situations (ask a new question if necessary). Figure out where in the code you're executing when you hit the "slow at 80" behavior. – technomage May 25 '15 at 12:51
  • Why do you create a new `RCSwitch()` every time this method is called? Why the `while (1)` loop when it only iterates once? Do you really need to call `enableReceive()` every time this method is called? Does it really need to return -1 when no data is available: couldn't it block instead? – user207421 May 26 '15 at 01:29
  • EJP: You are right, there are unnecessary steps in my code, and I stripped down a lot of things. That construction is while(1) was wrong, at the first time I didn't recognized that, because the java code is constantly called that method, so it worked. The point of that step is, I have to call .available() until I get the data. The enable is necessary since sometimes, I want to change the value of the transmitter pin. My code looks like this right now: http://pastebin.com/pcM051Kf But it does the same thing. – blase May 26 '15 at 01:51
  • technomage: There aren't any triggers and through console outs, I found out my code "stops" at .available(). This is the code behind .available(): `bool RCSwitch::available() { return RCSwitch::nReceivedValue != NULL; }` As i saw in the original source code, it's some kind of interrupt handling, but I don't really understand what happens in the background. – blase May 26 '15 at 02:02
  • Your code does not 'stop' at that line. It might *spin* at that line, if the code is different from what you've posted here. – user207421 May 26 '15 at 18:38

0 Answers0