Re: Create binary from GCJ generated assembly

isuru herath <[email protected]>
Newsgroups gmane.comp.gcc.java.devel
Message-ID <[email protected]>
Hi Andrew,

Thanks for the reply. My code is attached.

My intention of using this xchg instruction is that the simulator[Simics] I am using recognizes them as an special event and I can start counting the memory reference from that point onwards. I am trying this on Java is because we are going to use benchmark programs written Java. Thats why I am trying to use CNI to insert assembly to the binary.

I dont understand what you mean by "intrinsic counter". I would greatly appreciate if you could explain it bit more if you have time.

Aslo I didn get clearly what you mean by
 
Personally speaking, I'd just write the routines that need to access the counter in C++.

I am trying to find a way to insert these two assembly instructions to the binary created by gcj so that it will give the same number of memory references as C programs does.

thanks a lot for your help. further help is greatly appreciated.

regards,
isuru

--- On Wed, 10/28/09, Andrew Haley <[email protected]> wrote:

> From: Andrew Haley <[email protected]>
> Subject: Re: Create binary from GCJ generated assembly
> To: "isuru herath" <[email protected]>
> Cc: [email protected]
> Date: Wednesday, October 28, 2009, 8:56 AM
> isuru herath wrote:
> 
> > Thanks a lot for the quick reply. I did accordingly.
> But results were not the same. My program is a multi
> threaded shared counter.
> > so in my Java code I have 
> > counter++
> > 
> > I need to surround this with two xchg instructions.
> like
> > 
> > xchg
> > counter++
> > xchg
> > 
> > so that I can count number of read and write
> operations between two xchg instructions.
> 
> OK.
> 
> > with gcc I got both as 1 which is correct.
> > with gcj and JNI I got 47 read operations and 29 write
> operations
> > with gcj and CNI I got 6 read operations and 6 write
> operations
> > 
> > the way I am doing with CNI is follows.
> > 1. a java class with native method.(custom.java)
> > 2. c++ implementation of it to insert
> assembly.(custom.cc)
> > 3. compile custom.java (gcj -C custom.java)
> > 4. create the header file (gcjh custom -o custom.h)
> > 5. write multi threaded shared counter program. it has
> calls to native method to insert
> assembly(shared_counter.java)
> > 6. compile all java classes (gcj -C *.java)
> > 7. compile the custom.cc (g++ -c custom.cc -o
> custom.o)
> > 8. create the executable. (gcj do_options.class
> custom.class shared_counter.class custom.o -lstdc++
> --main=shared_counter -o shared_conter)
> > 
> > do_options is an interface with final variables. is
> there something that is wrong. or should I need do some
> additional thing. any help/ advice is greatly appreciated.
> 
> I'd rather see your code than guess what you did.
> 
> But yes, you're right.  You'd be calling code to
> invoke the inline asm,
> rather than executing it directly.  If you can't
> tolerate that, your
> only recourse is to add an intrinsic counter
> increment.  gcj already has
> intrinsics for things like
> sun.misc.Unsafe.compareAndSwapInt(), so this one
> should be easy enough.  Personally speaking, I'd just
> write the routines
> that need to access the counter in C++.
> 
> Andrew.
> 
>
custom.cc (text/x-c++src, 670 B)
#define _GNU_SOURCE
#include <gcj/cni.h>
#include <pthread.h>
#include <iostream>
#include "custom.h"
#include "java_magic_c.h"


using namespace std;
using namespace java::lang;

void
custom::do_this(jint option)
{
	MAGIC(option);
}

jint
custom::bind_this_thread(jlong thread_id)
{
// 	Mask for achieve the hard coded processor affinity
	cpu_set_t mask;
// 	Initializes all the bits in the mask to zero
	CPU_ZERO(&mask);
// 	Sets only the bits corresponding to the cpu
	CPU_SET(thread_id, &mask);

	if(sched_setaffinity(0, sizeof(mask), &mask) == -1 )
	{
		cout << "Thread"<< (int)thread_id << ": WARNING: Could not set CPU Affinity, continuing...\n";
	}
	return 0;
}
custom.h (text/x-chdr, 434 B)
// DO NOT EDIT THIS FILE - it is machine generated -*- c++ -*-

#ifndef __custom__
#define __custom__

#pragma interface

#include <java/lang/Object.h>

extern "Java"
{
  class custom;
}

class custom : public ::java::lang::Object
{
public:
  static void do_this (jint);
  static jint bind_this_thread (jlong);
public: // actually package-private
  custom ();
public:

  static ::java::lang::Class class$;
};

#endif /* __custom__ */
custom.java (text/x-java, 124 B)
class custom
{
	public static native void do_this(int option);
	public static native int bind_this_thread(long thread_id);
}
do_options.java (text/x-java, 313 B)
interface do_options
{
	int TX_ABORT		= 0xA;
	int TX_BEGIN		= 0xB;
	int TX_COMMIT		= 0xC;
	int TX_PRINT		= 0xD;

	int RW_PRIVATE		= 0x1;
	int RO_SHARED		= 0x2;
	int R_SHARED_W_PRIVATE	= 0x3;
	int RW_SHARED		= 0x4;

	int HEAP		= 0x5;

	int THREAD		= 0x6;

	int START_SIMULATION	= 0x8;
	int STOP_SIMULATION	= 0x9;
}
shared_counter.java (text/x-java, 802 B)
class shared_counter implements Runnable, do_options
{
	static int counter = 0;
	long thread_id;
	
	shared_counter(long thread_id)
	{
		this.thread_id = thread_id;
	}

	long get_thread_id()
	{
		return thread_id;
	}

	public void run()
	{
		custom.bind_this_thread(get_thread_id());
		custom.do_this(do_options.TX_BEGIN);
		counter++;
		custom.do_this(do_options.TX_COMMIT);
	}

	public static void main(String[]args)
	{
		Thread sc[] = new Thread[Integer.parseInt(args[0])];
		for(int i = 0;i<sc.length;i++)
		{
			sc[i] = new Thread(new shared_counter(i));
			sc[i].start();
		}

		for(int i = 0;i<sc.length;i++)
		{
			try
			{
				sc[i].join();
			}
			catch(Exception e)
			{
				System.out.println("Got the error "+e);
			}
			
		}
		System.out.println("shared counter value is "+counter);
	}
	
}
java_magic_c.h (text/x-chdr, 495 B)
#ifndef JAVA_MAGIC_C_H_
#define JAVA_MAGIC_C_H_
/* use to allow c++ files to import it */
#ifdef __cplusplus
extern "C" {
#endif

#define	ABORT_TX		0xA
#define	BEGIN_TX		0xB
#define	COMMIT_TX		0xC
#define	PRINT_TX		0xD


#define MAGIC(n) do {                                \
  asm volatile ("movl %0, %%eax" : : "g" (n) : "eax");  \
  asm volatile ("xchg %bx,%bx");                        \
} while (0)

#define MAGIC_BREAKPOINT MAGIC(0)

#ifdef __cplusplus
}
#endif

#endif /*JAVA_MAGIC_C_*/
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.