Wikipedia Affiliate Button

Stanislav Vitvitskiy's blog

середа, 21 жовтня 2009 р.

SSE vector operations in GCC

Thanks to GCC vector types one can do SSE vector operations without having to write any assembly. The below code snippet:
#include <stdio.h>

typedef int v4si __attribute__ ((mode(V4SI)));

int main(int argc, char** argv) {


     v4si a[10], b[10], c[10];

        for(int i = 0; i < 10; i++) {
     c[i] = a[i] + b[i];
}

}

translates into the following assembly:
 movdqa  (%eax), %xmm1
 ...   
 movdqa  (%eax), %xmm0
 paddd   %xmm1, %xmm0

Linux profiling experience

After rambling around for a while I finally settled on Valgrind with kcachegdind GUI for profiling my C/C++ code under Linux. On my Ubuntu box:
sudo apt-get install valgrind
sudo apt-get install kcachegrind
valgrind --tool=callgrind 
kcachegrind
That's it!

пʼятниця, 8 травня 2009 р.

Some XULRunner traps on Mac OS X

Recently I've been fighting for quite a while with my XUL (Gecko runtime aka GRE) application on Mac OS X trying to make is 'speak' to java via LiveConnect. I had couple of problems which other people might also run into:
  • I accidentally downloaded a PowerPC version of XULRunner to my Intel Mac. While it runs perfectly well (thanks to Rosetta) it implies that java is also a PowerPC version. To check which platform your xulrunner supports simply type:
    file /Library/Frameworks/XUL.framework/Versions/Current/xulrunner-bin
    
    The output should contain something except PowerPC ('ppc').
  • You may still experience problems connecting to java due to outdated java plugin. In this case you may wish to download Java Embedding Plugin which utilizes Apple's Safari plugin to do the job.
  • Because XULRunner is distributed as x86 32 bit binary you'll have to use an appropriate java compiled for x86 32 bit. This is either default Leopard Sun JDK 1.5.x or Soylatte ( an independent OpenJDK port for OS X).

четвер, 30 квітня 2009 р.

Calling java from XUL applications

XULRunner is a technology from Mozilla that allows to create cross-platform GUI applications just as easy as a websites. Today I was trying to use my java libraries inside of a XUL application. This is basically to be able to load a jar file and call java functions with my javascript code. It turns out that the only ( and the best ) way to accomplish this is by using LiveConnect, a feature of java plugin that allows to 'talk' to java. LiveConnect among other things is responsible for communication with java applets. With LiveConnect one can instanciate arbitrary java class and use it in javascript. Any java objects returned from method calls will be accessible in javascript as well as any javascript objects passed to java methods will be accessible in java. To achieve this effect LiveConnect does two-way wrapping of objects, i.e. it wraps java object with javascript and the other way around. More precisely, to instanciate a JVM object simply do this:
var javaObject = new java.lang.String('Hello');
So to load classes from a library simply instanciate a classloader and then use it to instanciate the classes. Something like this:
  function getAppPath(appName) {
    var chromeRegistry = Components
      .classes["@mozilla.org/chrome/chrome-registry;1"]
      .getService(Components.interfaces.nsIChromeRegistry);
            
    var uri =
      Components.classes["@mozilla.org/network/standard-url;1"]
        .createInstance(Components.interfaces.nsIURI);
    
    uri.spec = "chrome://" + appName + "/content/";
    
    var path = chromeRegistry.convertChromeURL(uri);
    if (typeof(path) == "object") {
        path = path.spec;
    }
    
    path = path.substring(0, path.indexOf("/chrome/") + 1);
    
    return path;
  };

  var basePath = getAppPath('myapp');
  var url = new java.net.URL(basePath + 'java/my.jar');
  var cl = new java.net.URLClassLoader( [ url ] );
  
  var aClass = java.lang.Class.forName("com.stan.XULDemo", true, cl);

  var inst = aClass.newInstance();

  // Calling 'sum' function from java
  var a = inst.sum(2, 3); 
  alert(a);  // Will alert '5'

  // A function which we'll pass to java
  // and have java call it later with a parameter
  var callback = function(str) {
    alert(str);
  };

  inst.callMeLater(callback, 'test');
The code of com.stan.XULDemo.java will be the following:
package com.stan;

public calss XULDemo {
  public int sum(int a, int b) {
    return a + b;
  }
  
  public void callMeLater(final JSObject func, final String text) {
    new Thread() {
      public void run() {
        try {
          Thread.sleep(5000);  // Sleep 5 seconds
        } catch(Exception e) { }
        
        // We are passed a javascript Function Object 
        // which has method 'call' used to actually call the
        // function. The first parameter is 'this',
        // followed by a set
        // of actual function parameters
        func.call("call", new Object[] { null, text });
      }
    }.start();
  }
}
This works out of the box with XULRunner. Note. Currently there are troubles with LiveConnect 1.9 on Mac (jdk 1.6 u3) which I am looking at right now.

четвер, 25 грудня 2008 р.

Multipart post in Ruby

Uploading a file to a server is a common task in web-development practice. It requires you to create a special HTML form with enctype set to 'multipart/form-data' and include an input of type 'file' into it.
However sometime you want to upload a file to some third-party service from your Ruby script on background. For this you'll need to properly construct the multipart POST request and send it out via Ruby net/http library.
After playing a bit I came up with the following class. A very strong advantage of it is that it works well with big files ( such as videos ).
class Multipart
 
  def initialize( file_names )
    @file_names = file_names
  end
 
  def post( to_url )
    boundary = '----RubyMultipartClient' + rand(1000000).to_s + 'ZZZZZ'
   
    parts = []
    streams = []
    @file_names.each do |param_name, filepath|
      pos = filepath.rindex('/')
      filename = filepath[pos + 1, filepath.length - pos]
      parts << StringPart.new ( "--" + boundary + "\r\n" +
      "Content-Disposition: form-data; name=\"" + param_name.to_s + "\"; filename=\"" + filename + "\"\r\n" +
      "Content-Type: video/x-msvideo\r\n\r\n")
      stream = File.open(filepath, "rb")
      streams << stream
      parts << StreamPart.new (stream, File.size(filepath))
    end
    parts << StringPart.new ( "\r\n--" + boundary + "--\r\n" )
   
    post_stream = MultipartStream.new( parts )
   
    url = URI.parse( to_url )
    req = Net::HTTP::Post.new(url.path)
    req.content_length = post_stream.size
    req.content_type = 'multipart/form-data; boundary=' + boundary
    req.body_stream = post_stream
    res = Net::HTTP.new(url.host, url.port).start {|http| http.request(req) }

    streams.each do |stream|
      stream.close();
    end
   
    res
  end
 
end

class StreamPart
  def initialize( stream, size )
    @stream, @size = stream, size
  end
 
  def size
    @size
  end
 
  def read ( offset, how_much )
    @stream.read ( how_much )
  end
end

class StringPart
  def initialize ( str )
    @str = str
  end
 
  def size
    @str.length
  end
 
  def read ( offset, how_much )
    @str[offset, how_much]
  end
end

class MultipartStream
  def initialize( parts )
    @parts = parts
    @part_no = 0;
    @part_offset = 0;
  end
 
  def size
    total = 0
    @parts.each do |part|
      total += part.size
    end
    total
  end
 
  def read ( how_much )
   
    if @part_no >= @parts.size
      return nil;
    end
   
    how_much_current_part = @parts[@part_no].size - @part_offset
   
    how_much_current_part = if how_much_current_part > how_much
      how_much
    else
      how_much_current_part
    end
   
    how_much_next_part = how_much - how_much_current_part
   
    current_part = @parts[@part_no].read(@part_offset, how_much_current_part )

    if how_much_next_part > 0
      @part_no += 1
      @part_offset = 0
      next_part = read ( how_much_next_part  )
      current_part + if next_part
        next_part
      else
        ''
      end
    else
      @part_offset += how_much_current_part
      current_part
    end
  end
end