Disclaimer: this is an automatic aggregator which pulls feeds and comments from many blogs of contributors that have contributed to the Mono project. The contents of these blog entries do not necessarily reflect Novell's position.

February 08

Banshee + GNOME 3.0

The GNOME logo I spent a little time this weekend doing one of the things I've wanted to do for years - eradicate one of the oldest files in Banshee: banshee-dialogs.glade.

The vast majority of Banshee's UI is custom widgetry that is laid out dynamically at runtime. The main window and the preferences dialog hasn't been restricted by Glade for a couple of years, but all the other dialogs were defined in part in Glade:

  • Open Location
  • Seek To
  • Import Media
  • Smart Playlist Editor
  • Error list dialog (very unlikely anyone has ever seen this)
  • Last.FM Station Editor

These were all fairly simple dialogs in Glade -- mostly consisting of a table, some static labels, and placeholders to pack in custom widgets at runtime (e.g. the import source combo box in the Import Media dialog, or the actual query builder UI packed in the Smart Playlist Editor dialog).

Old Banshee Glade Dialogs
Old Banshee Glade Dialogs

These are now fully defined in code, allowing the dialogs to derive directly from BansheeDialog, which provides extra common functionality for dialogs on top of Gtk.Dialog.

The big take-away here is no longer depending on the deprecated libglade/glade-sharp libraries (well, almost -- later this week Gabriel will port Muinshee -- an alternative Banshee client in the image of Muine, but not a core component). Additionally, I removed our dependency on libgnome/gnome-sharp, which is also deprecated.

This means that Banshee 1.5.4 will be GNOME 3.0 ready. The last thing to do is implement a udev hardware backend. We already have partial DeviceKit support, and GIO support. However, we don't take a hard dependency on HAL. The removal of the last Glade file represents the eradication of any hard obsolete GNOME 2.0 dependencies. Exciting!

As a quick aside: what was really nice about the porting from Glade to C# was the use of C# 3.0 features - specifically type inference and object initializers. This permits interface construction using a more terse syntax than available in C# 2.0, yielding improved readability and organization. For instance:

    var table = new Table (2, 2, false) {
        RowSpacing = 12,
        ColumnSpacing = 6
    };

    table.Attach (new Label () {
            Text = Catalog.GetString ("Station _Type:"),
            UseUnderline = true,
            Xalign = 0.0f
        }, 0, 1, 0, 1, AttachOptions.Fill, AttachOptions.Shrink, 0, 0);

Bring it on, GNOME 3.0. We are ready!

Unity Tech signs a three-year deal with LEGO!

As y’all know the user base for Unity is exploding and that growth includes developers across the spectrum, from games to non-games, from small development shops to large studios, from social media outlets to major media providers. Today we have news about not just a major media provider but a major toy manufacturer as well, [...]

February 07

Introducing Pinta

Over the holiday break, I stumbled upon this article from OSNews stating that there was a need for something like Paint.NET for Gtk. Having some experience with porting Paint.NET to Mono Winforms before, I knew that that was a massive task. But it still got me curious about Cairo and creating a layered canvas, since I had never played with Cairo or Gtk.

After playing around for a few hours, I actually had a working paintbrush and canvas. Intrigued by my success, I played around with it for a few more days. By the end of the week I had a nifty little paint program with a few features. Now, a month later, it's time to open my little project up to the world: Pinta.


Pinta is a clone of Paint.NET. It already has a small, but hopefully useful, set of features like multiple layers and infinite levels of Undo/Redo.


I hope to implement the same feature set as Paint.NET. Currently there are several tools missing, as well as adjustments like brightness/contrast and levels and Paint.NET's effects.


Being written in Mono/Gtk, Pinta is naturally cross-platform.


To download Pinta or the source code, check out the website!

Note: I didn't misspell "Hello" in my screenshot, my dog's name is Helo. ;)

Why does Safari/Flash always crash?

On a personal note, I have started a new job at Kontera, involving much more web-related development than I have ever done. I will continue posting experiences from this job I find interesting and worthy of sharing.

Safari users may have noticed often crashes when visiting sites that contain Flash. I certainly have. This is not related to a specific OS - it happens both on Windows and on Mac (I personally use a Mac). I noticed this when developing a web component that includes also some Flash, and easily reproduced quite frequent crashes on Safari 4.0.4 and Flash 2010.

Interestingly enough, Chrome which is based on the same engine does not have these crashes.

From examining the stack of Safari (and also knowing the behavior of my flash app ;-), I think that the crash happens when Safari is trying to do something while Flash is calling JavaScript code via ExternalInterface.call(). Reducing the number of calls from Flash to JavaScript and reducing the time spent in the JavaScript calls causes the probability of a crash to be reduced dramatically. The simplest technique is to modify the JavaScript callback to wrap it in a setTimeout(...) as such:

function foo(param1, param2) { .....}

should be replaced with:

function foo(param1, param2, afterTimeout) {
if (!afterTimeout) {
setTimeout(function() { foo(param1, param2, true) }, 20);
}
.... // the original code
}

The flash code does not need to be modified at all.

Happy hacking,

Noam

February 06

Form Wizard Pro 0.0.1.5 Released

I'm happy to announce the first major upgrade for my Form Wizard Pro product

New Features:

  • Support for multi page forms aka surveys
  • You can import and export complete form definitions
  • You can import and export individual questions, so if you make a state list dropdown you don't have to type it again, just export it and then you can import it in a different form to re-use it.
  • Support for additional instruction blocks arranged by drag and drop among the questions
  • Support for regular expression validation
  • and more

This release is a free upgrade for existing customers who bought Form Wizard Pro previously and starts at $99 for new customers. 

Note: This new release requires mojoPortal 2.3.3.6 which was just released a few days ago.

See how easy it is to create custom forms and surveys using mojoPortal and Form Wizard Pro

 

Follow us on twitter or become a fan on Facebook

follow us on twitter become a fan on facebook


Joe Audette  ...

PPA installation on karmic

I don’t know how long add-apt-repository has been around, but I’ve found it very useful for installing some of the bleeding edge stuff I want to test:

$ for ppa in do-core team-xbmc nvidia-vdpau chromium-daily directhex/monoxide
do
  sudo add-apt-repository ppa:$ppa
done
$ apt-get update
$ apt-get install chromium-browser nvidia-glx-195 gnome-do xbmc monodevelop

Is there anything like this for debian proper, I wonder?

February 04

A Mirage made of music

Mirage 0.6 is now available, bringing interesting new features and bug fixes.

Mirage is an extension for Banshee, the media player you all know and love. It analyzes all the songs in your music library and is then able to evaluate the similarity between any particular songs, just by looking at the acoustic signal.

Mirage was originally created by Dominik Schnitzer as a part of his master thesis (Mirage - High-Performance Music Similarity Computation and Automatic Playlist Generation, pdf). I won't even try to pretend that I understand half of what is going on during the acoustic analysis and the similarity calculations, but I can tell you that there are matrices and Fourier transforms, amongst others.

Analyzing a song shouldn't take more than a few seconds, but of course if you have a music library with several thousand tracks, those seconds can add up to become quite a while. The good thing is that you can stop the analysis at any time, restart later, and Mirage only analyzes tracks that were not already processed.

When the analysis is finished, you can then select one or several tracks, drag-n-drop them to the "Playlist Generator" source and Mirage will automatically create a playlist of similar songs. The playlist will be refreshed automatically and will adapt itself as you listen to the songs or skip them.

This release introduces a new and experimental "duplicate search" feature : go to "Tools > Mirage Playlist Generator" and select "Duplicate Search". Mirage will then go through your whole music library and if any two tracks are very similar to each other, they will be added to a "Mirage Duplicates" playlist.

So go ahead and try it !

February 03

Moonlight 3.0 Preview 1

We have just released our first preview of Moonlight 3.0.

This release contains many updates to our 3.0 support, mostly on the infrastructure level necessary to support the rest of the features.

In the release:

  • MP4 demuxer support. The demuxer is in place but there are no codecs for it yet (unless you build from source code and configure Moonlight to pick up the codecs from ffmpeg).
  • Initial work on UI Virtualization.
  • Platform Abstraction Layer: the Moonlight core is now separated from the windowing system engine. This should make it possible for developers to port Moonligh to other windowing/graphics systems that are not X11/Gtk+ centric.
  • The new 3.0 Binding/BindingExpression support is in.
  • Many updates to the 3.0 APIs

The above is in addition to some of the Silverlight 3.0 features that we shipped with Moonlight 2.0.

For the adventurous among you, our SVN version of Moonlight contains David Reveman's pixel shader support:

From Silverlight Parametric Pixel Shader.

mojoPortal 2.3.3.6 Released

I'm happy to announce the release of mojoPortal 2.3.3.6, available now on our download page.

This release fixes a few bugs reported in our forums since the last release, adds a few minor improvements to some features and lots of minor fit and finish improvements based on feedback from our community.

In the previous release I added a hideable toolbar for administration links in most of the included skins, this release I took a queue from Joe Davis and added icons to the toolbar. Also based on community feedback, I made it remember your preference for open/closed across pages. Previously if you closed it and went to a different page it would open again on the new page, now it remembers your preference.

toolbar with icons

 

Contact Form - added a setting for BCC email, added a setting in case you don't want to store messages in the database, added a setting allowing you to use the email address entered by the user as the from address in the form notification.

Shared Files - added a setting for the Default Sort, when shared files are returned as search results in the search page, the download link now opens a new window.

Upgrade to NeatUpload 1.3.21

Updated Translations

  • Italian - thanks Diego Mora
  • Greek - thanks Yioryos Moschovakis
  • Russian - thanks Alexander (aka SkySandy)
  • Turkish - thanks to Cenk Kumas
  • Swedish - thanks to Par Rohlin
  • Spanish - thanks to Matias Molleja

Your Opinion Requested

I am currently using CKeditor as my main editor and it is also now the default for new installations of mojoPortal. The only thing I like better about TinyMCE at the moment is the spell checker which works much nicer than the one in CKeditor or FCKeditor. Since CKeditor is the successor to FCKeditor and no new development is being done on FCKeditor, I'm considering not including FCKeditor in mojoPortal going forward to reduce our footprint on disk a little as each editor is a lot of javascript. We could reduce 3 or 4 MB of disk footprint leaving it out. I could still make it available as a separate download for anyone who wants to continue using it. So, if you have a strong opinion about whether we should or should not continue to package FCKeditor with mojoPortal, please post in the comments.

 

Follow us on twitter or become a fan on Facebook

follow us on twitter become a fan on facebook


Joe Audette  ...

Mono at FOSDEM

I will be arriving in Brussels on Saturday Morning for the FOSDEM conference. We have an activity-packed day on Sunday of all-things-mono.

This is the current schedule, pretty awesome!

Feedback requested: My plan is to do a state-of-the-union kind of presentation on Mono, but if you have a specific topic that you would like me to present on, please leave a comment, I will try to prepare for that.

See you in Brussels!

February 02

Solving the gcc 4.4 strict aliasing problems

A couple of days ago Jeff Stedfast ran into some problems with gcc 4.4, strict aliasing and optimizations. Being a geeky sort of person, I found the problem really interesting, not only because it shows just how hard it is to write a good, clear standard, even when you're dealing with highly technical (and supposedly unambiguous) language, but also because I never did "get" the aliasing rules, so it was a nice excuse to read up on the subject.

Basically, the standard says that you can't do this:

int a = 0x12345678;
short *b = (short *)&a;

I'm forcing a cast here, and since the types are not compatible, they can't be "alias" of each other, and therefore I'm breaking strict-aliasing rules. Note that if you compile this with -O2 -Wall, it will *not* warn you that you're breaking the rules, even though -O2 activates -fstrict-aliasing and -Wall is supposed to complain about everything (right??). Apparently, this is by design, though why would anyone not want warnings in -Wall for something that will obviously break code is beyond me. If you want to be told that you're not playing by the rules, make sure you build with -Wstrict-aliasing=2, which will say:

line 2 - warning: dereferencing type-punned pointer will break strict-aliasing rules

So now you know you're being naughty. Of course, if you did try to access the variable, even just with -Wall it will complain at you - this more complete snippet will give you several warnings with -Wall:

int a = 0x12345678;
short *b = (short *)&a;
b[1] = 0;
if (a == 0x12345678)
  printf ("error\n");
else
  printf ("good\n");

line 3 - warning: dereferencing pointer ‘({anonymous})’ does break strict-aliasing rules

The problem gets ugly when you're dealing with structs and pointers to them - then -Wall is completely silent about possible issues, and only -Wstrict-aliasing=2 will work, like in this little snippet:

typedef struct type {
  struct type *next;
  int val;
} Type;

...

Type *t1, *t2, *t3;
t1 = t2 = NULL;
t1 = (Type*) &t2;
int i;
for (i = 0; i < 2; i++) {
  t3 = malloc (sizeof (Type));
  t1->next = t3;
  t1 = t3;
}
if (!t2)
  printf ("error\n");
else
  printf ("good\n");

This doesn't emit any warnings on -Wall because the loop makes it slightly fuzzy for gcc to tell whether things are getting assigned or not. -O2 will optimize away the assignment to t1 on line 3, which will make things not work later on.

So how to fix this? The attribute may_alias allows a type to bypass the aliasing rules, just like character types do (character types are allowed to alias any other type, according to the c99 standard). Changing the definition of Type to the following will make the compiler happy:

typedef struct type {
  struct type *next;
  int val;
} __attribute__((__may_alias__)) Type;

One final note: if you mix up code with aliased types and non-aliased types, gcc will not enforce aliasing optimizations on your non-aliased-possibly-broken code... i.e., if you define this type two times, one with the attribute, one without, and then do the loop above with both types (separately mind you, with separate variables, the code just happens to be in the same method), the non-aliased type won't fail. Aren't optimizations fun?


Update: People have pointed out that the first statement short *b = (short *)&a; is totally legal and has nothing to do with aliasing.

Yes, that's true, I should have been more precise. The statement is perfectly legal. It's when you try to access the data via the pointer that was assigned on that line that breaks the standard. So when your code blows up, it blows up accessing the data, but that's not the cause, that's the consequence. The cause of said explosion is that optimizations + strict-aliasing look at that (totally legal) statement and say "oh, dude, come on, this is bogus" and throw it away while munching on scooby snacks. Well, not sure about that last part.

Anyways, where was I? Oh yes, so, two things: if you don't want to change your code, you can use may_alias , gcc will say "that's so awesome" and everyone will make merry. Or something. The second thing is, and let me add a little emphasis to this part, because I'm sometimes a bit too subtle, and apparently some things should be said *very clearly*: when a statement is perfectly legal, and yet it IS removed via a combination of default flags with NO warnings whatsoever, something is WRONG, and in my opinion, the problem here is lack of warnings.

And that, as someone said, is that. Or not, whatever tickles your fancy. Hmmmm, tickles...

February 01

Unity and Mobile pt. 2 : The iPad Cometh

Ok, so the iPad is now officially old news. Let me get something out of the way, first: yes, we will support it. Yes, we are aiming for 0-day support. If we get there or not basically depends whether on if Apple can get us early access to the device. With that out of the way, [...]

Juxtapositions

From time to time, reCAPTCHA will give users odd juxtapositions of words. I got quite a kick out of seeing this one:

I think this would make a great show!

Granny Theft Tofu

This past weekend was the Global Game Jam, where teams from all around the world worked tirelessly to create amazing games in a single weekend. Here in Copenhagen, the local branch of the Global Game Jam is the Nordic Game Jam that was held at the IT University of Copenhagen. The cool things about the [...]

Iterator-based Microthreading

Back in May, I was wrapping PhyreEngine and porting the samples to C#. To extend one of them and demonstrate some of the capabilities of C#, Miguel and I decided to use simple iterator-based microthreading, which simulates multithreading but with many microthreads within a single real thread. Unity does something like it in their game engine too. It enables you to use a very imperative style of coding, as if using a single dedicated thread for each, but without anywhere near the overhead of real threads.

Here's the usage example we came up initially with that drove my design of the microthread scheduler:

public class Enemy1
{
	public void Init (Scheduler scheduler)
	{
		scheduler.AddTask (Patrol ());
	}
 
	IEnumerable Patrol ()
	{
		while (alive){
			if (CanSeeTarget ()) {
				yield return Attack ();
			} else if (InReloadStation){
				Signal signal = AnimateReload ();
				yield return signal;
			} else {
				MoveTowardsNextWayPoint ();
				yield return TimeSpan.FromSeconds (1);
			};
		}
		yield break;
	}
 
	IEnumerable Attack ()
	{
		while (TargetAlive && CanSeeTarget ()){
			AimAtTarget ();
			Fire ();
			yield return TimeSpan.FromSeconds (2);
		}
	}
}

The concept is fairly simple. The C# compiler magically transforms this code into an IEnumerator state machine (returned by IEnumerable.GetEnumerator()). Each time IEnumerator.MoveNext() is called, your method "iterates": it runs to the next yield statement, sets the Current property to the value yielded, and keeps enough state that next time it iterates, it can effectively resume where it left off. We can yield nulls to give other microthreads a chance to run, or yield objects to tell the scheduler other things. For example, yielding a TimeSpan could cause the microthread to sleep for that long.

interface IEnumerator
{
	bool MoveNext ();
	object Current;
}

As you can see, although C# iterators are primarily intended for iterating through collections, the yield keyword can also become effectively something like a microthread cooperatively yielding. Your method runs until it yields, then it later resumes from this point, runs to the next yield, and so on.

The class that enumerates your iterator is the scheduler. Before we get to that, we'll cover the boring bits to set some groundwork. First, we need a class to encapsulate the task. This holds hold the IEnumerator and which Scheduler it belongs to, is a singly linked list node, and has a field for arbitrary data we'll use later.

//tasks may move between lists but they may only be in one list at a time
internal class TaskItem
{
	public readonly IEnumerator Task;
	public TaskItem Next;
	public Scheduler Scheduler;
	public long Data;
 
	public TaskItem (IEnumerator task, Scheduler scheduler)
	{
		this.Task = task;
		this.Scheduler = scheduler;
	}
}

Next we need a simple linked list for keeping lists of TaskItem. We're not using LinkedList<T>; this is much simpler, does only what we need, and makes it easy to move tasks between lists and remove them via the enumerator.

internal sealed class TaskList
{
	public readonly Scheduler Scheduler;
 
	public TaskItem First { get; private set; }
	public TaskItem Last { get; private set; }
 
	public TaskList (Scheduler scheduler)
	{
		this.Scheduler = scheduler;
	}
 
	public void Append (TaskItem task)
	{
		Debug.Assert (task.Next == null);
		if (First == null) {
			Debug.Assert (Last == null);
			First = Last = task;
		} else {
			Debug.Assert (Last.Next == null);
			Last.Next = task;
			Last = task;
		}
	}
 
	public void Remove (TaskItem task, TaskItem previous)
	{
		if (previous == null) {
			Debug.Assert (task == First);
			First = task.Next;
		} else {
			Debug.Assert (previous.Next == task);
			previous.Next = task.Next;
		}
 
		if (task.Next == null) {
			Debug.Assert (Last == task);
			Last = previous;
		}
		task.Next = null;
	}
 
	public TaskEnumerator GetEnumerator ()
	{
		return new TaskEnumerator (this);
	}
 
	public sealed class TaskEnumerator
	{
		TaskList list;
		TaskItem current, previous;
 
		public TaskEnumerator (TaskList list)
		{
			this.list = list;
			previous = current = null;
		}
 
		public TaskItem Current { get { return current; } }
 
		public bool MoveNext ()
		{
			TaskItem next;
			if (current == null) {
				if (previous == null)
					next = list.First;
				else
					next = previous.Next;
			} else {
				next = current.Next;
			}
 
			if (next != null) {
				if (current != null)
					previous = Current;
				current = next;
				return true;
			}
			return false;
		}
 
		public void MoveCurrentToList (TaskList otherList)
		{
			otherList.Append (RemoveCurrent ());
		}
 
		public TaskItem RemoveCurrent ()
		{
			Debug.Assert (current != null);
			TaskItem ret = current;
			list.Remove (current, previous);
			current = null;
			return ret;
		}
	}
}

Now we can implement the scheduler. Using the scheduler is very simple. You register tasks with RegisterTask(IEnumerable), then call Run() to run all the active tasks for one yield iteration each. It handles sleeping and waking up tasks and removing tasks once they're finished.

public sealed class Scheduler
{
	TaskList active, sleeping;
 
	public Scheduler ()
	{
		active = new TaskList (this);
		sleeping = new TaskList (this);
	}
 
	public void AddTask (IEnumerator task)
	{
		active.Append (new TaskItem (task, this));
	}
 
	public void Run ()
	{
		//cache this, it's expensive to access DateTime.Now
		long nowTicks = DateTime.Now.Ticks;
 
		//move woken tasks back into the active list
		var en =  sleeping.GetEnumerator ();
		while (en.MoveNext ())
			if (en.Current.Data < nowTicks)
				en.MoveCurrentToList (active);
 
		//run all the active tasks
		en = active.GetEnumerator ();
		while (en.MoveNext ()) {
			//run each task's enumerator for one yield iteration
			IEnumerator t = en.Current.Task;
			if (!t.MoveNext ()) {
				//it finished, so remove it
				en.RemoveCurrent ();
				continue;
			}
 
			//check the current state
			object state = t.Current;
			if (state == null) {
				//it's just cooperatively yielding, state unchanged 
				continue;
			} else if  (state is TimeSpan) {
				//it wants to sleep, move to the sleeping list. we use the Data property for the wakeup time 
				en.Current.Data = nowTicks + ((TimeSpan)state).Ticks;
				en.MoveCurrentToList (sleeping);
			} else if (state is IEnumerable) {
				throw new NotImplementedException ("Nested tasks are not supported yet");
			} else {
				throw new InvalidOperationException ("Unknown task state returned:" + state.GetType ().FullName);
			} 
		}
	}
 
	internal void AddToActive (TaskItem task)
	{
		active.Append (task);
	}
}

At this point, it looks fairly useful, but let's add a simple synchronization primitive too. Microthreads should never make long blocking calls because they can't be pre-empted. Instead, we're going to let the microthread obtain and yield a signal object, which means it will not be scheduled until the signal has been set. Instead of using blocking APIs, you can use async APIs, create a signal object, wait on that, and have the callback set the signal. Or, thinking back to the initial game example, some game object's controlling microthread might want to sleep until another game object reaches a certain state; the target object can keep a signal accessible via a property that microthreads can read and wait on.

A thread can wait for more that one signal, and more than one thread can wait for a signal. Essentially we're going to have an equivalent of .NET's AutoResetEvent and WaitHandle.WaitAll(WaiHandle[]).

The signal's job is to keep a list of all the tasks that are waiting for it. When tasks start waiting, they move out of the scheduler's lists and are tracked by all the signals instead. Each signal increments/decrements the task's Data property to keep track of how many signals the task is waiting for. When the count reaches zero, the task can be moved back to the scheduler.

public class Signal
{
	static int nextId = int.MinValue;
 
	int id = nextId++;
	List<TaskItem> tasks = new List<TaskItem> ();
	bool isSet = true;
 
	public void Set ()
	{
		if (isSet)
			return;
		isSet = true;
		//decrement the wait count of all tasks waiting for thsi signal
		foreach (TaskItem task in tasks)
			if (--task.Data == 0)
				//if the wait count is zero, the task isn't waiting for any more signals, so re-schedule it
				task.Scheduler.AddToActive (task);
		tasks.Clear ();
	}
 
	internal void Add (TaskItem task)
	{
		//signal only becomes unset when it has tasks
		if (isSet)
			isSet = false;
		//the signal keeps a list of tasks that are waiting for it
		tasks.Add (task);
		//use the task's data for tracking the number of signals it's still waiting for
		task.Data++;
	}
}

And we need to add a couple more checks to the Scheduler.Run() state handling, so that when the task returns a signal or collection/array of signals, it's moved from the scheduler's lists to the tasks' lists.

} else if (state is Signal) {
	TaskItem task = en.RemoveCurrent ();
	task.Data = 0;
	((Signal)state).Add (task);
} else if (state is ICollection<Signal>) {
	TaskItem task = en.RemoveCurrent ();
	task.Data = 0;
	foreach (Signal s in ((ICollection<Signal>)state))
		s.Add (task);
}

And, there it is.

I have a few more ideas to improve this and turn it into a real library:

  • Implement a Signal that's a ManualResetEvent analogue
  • Use a IEnumerable<ThreadState> instead of plain IEnumerable, where ThreadState is a union struct with an enum specifying its type. This could be used to avoid the boxing of TimeSpan and the type checks and casts in the scheduler — just switch on the enum value. It would also prevent consumers returning a zero TimeSpan instead of null.
  • Dispose any disposable task IEnumerators
  • Implement task priorities, probably using different lists
  • Tidy up the accessibility and API a bit
  • Add a Scheduler.Run overload that only runs some number of iterations, not the whole list.

Some people may wonder why I haven't mentioned interactions with real threads. If the scheduler were thread-aware, then you could have multiple real threads on different cores consuming the microthread queue, and it would be faster with multiple cores and avoid blocking on slow tasks. The problem is not just that this increases the complexity, but that the microthreads all would have to be aware of threading too, and would need to lock all the objects they touched, and so on. This scheduler is meant to run in the equivalent of the GUI thread, purely to enable driving high-level game logic (and similar things) with an intuitive thread-like imperative programming model, and minimal overhead. If it doesn't fit easily on one core you're probably using it for the wrong thing. There might be cases where it's useful to create multiple Schedulers, and run them in different thread, but be careful about what the microthreads touch.

This is part of the Catchup 2010 series of posts.

January 30

Weird bugs due to gcc 4.4 and strict aliasing

I was just running the unit tests for GMime and I got a couple of failures on my openSUSE 11.2 machine that I have never gotten before. I started debugging and I noticed something very odd. One of my functions that returned a linked-list of 'word' tokens was returning NULL for something that it should not be returning NULL from, especially since I had just stepped through that method and seen with my own eyes that it was creating and appending nodes to my linked list as it should!

At this point I split out a tiny test case:

#include <stdio.h>
#include <stdlib.h>

typedef struct _node {
    struct _node *next;
    int value;
} Node;

int main (int argc, char **argv)
{
    Node *list, *node, *tail;
    int i;
    
    list = NULL;
    tail = (Node *) &list;
    
    for (i = 0; i < 10; i++) {
        node = malloc (sizeof (Node));
        node->next = NULL;
        node->value = i;
        
        tail->next = node;
        tail = node;
    }
    
    if (list == NULL)
        printf ("oops, list is null???\n");
    
    return 0;
}

I then built this test program using gcc -Wall -g -o list-test list-test.c. When I ran the program, no error.

Huh.

Luckily I thought to rebuild with -O2. This time when I ran my test program, it printed out the error I expected. The list was NULL.

Doing a bit of research suggests that gcc 4.4 has decided to enforce strict aliasing for -O2 and higher, which explains why it works without -O2.

Oddly enough, I get no strict aliasing warnings from gcc even when I use -Wall -O2.

So be warned... gcc 4.4 may break your perfectly valid code in mysterious ways.

Update: Looks like MySQL had similar problems and according to this article, it is suggested that the gcc developers have interpreted the c99 specification far too strictly.

Update 2: Josh's comment had an excellent explanation of the problem this code hits, so I thought I'd add it to my blog post for anyone who may otherwise miss his comment:

I imagine that gcc's aliasing thinks that dereferencing a Node* can only write to Node objects, so it won't have any effect on Node*s like list. Thus it thinks that list is never modified in that function, and it propagates the NULL constant throughout.

I also liked Josh's explanation of why the above code works (since a number of people have been confused by it already, I'll post that too):

The only reason it "works" in the -O0 case is because the next field happens to be the first field, as Fabian pointed out. The first time you write to tail->next, you're writing to &list with no offset, so list happens to get the value of node. When next does have an offset, then the value of list is not changed, but something else on the stack after it will be clobbered.

January 29

Banshee 1.5.3 and the return of OS X support

The Banshee logo

The Banshee community is proud to announce the availability of Banshee 1.5.3! With a slew of new features and bug fixes, and a fully refreshed Mac OS X build, this is another solid release on the road to 1.6 (due out on March 31st).

Get It!

Gabriel highlights a number of new features and improvements on his release announcement blog:

  • A new sync device from playlist option
  • Audiobooks library extension
  • Library-folder watcher extension
  • eMusic importer/downloader extension
  • GIO file backend supporting non-local files

Additionally, 75 bugs were fixed since the last release. Read the 1.5.3 release notes to learn about additional new features and improvements.

Mac OS X Release

What's particularly exciting to me is the return of the OS X releases. I have completely overhauled our OS X build, and we no longer take a framework dependency on Mono or GTK - these dependencies are bundled as part of the binary distribution of Banshee on OS X.

If you have OS X 10.5 or newer (Intel only), you can simply download and run Banshee - nothing else needs to be installed.

Banshee 1.5.3 on Mac OS X 10.6

This gives us greater flexibility to refine and polish Banshee for OS X. For instance, I started working on a new GTK theme that uses the flexible Murrine engine. Currently the Mono framework installation uses Clearlooks.

There's still a lot to do on the OS X build, so if you're interested in hacking on the platform backend, it's now easier than ever to do so:

  • Install XCode
  • Clone Banshee from GNOME git
  • Run ./bootstrap-bundle at the top of the checkout

This process will magically build everything that Banshee requires, and from there hacking on Banshee is just like it is on Linux. I recommend using MonoDevelop of course to get real work done though.

Enjoy!

Update: There was a lame bug preventing startup of Banshee 1.5.3 on OS X. This has been fixed and the DMG image has been respun. If you had problems running the release, download the updated image. My bad ya'll!

iPad - Inspirational Hardware

iPad - Inspirational Hardware

As a software developer, I find the iPad inspirational.

Apple's iPad is not a new idea. They are not the first ones to think of a tablet and as many blogs have pointed out the Apple iPad is not everyone's dream machine, the hardware is lacking gadgets and the software is not that amazing.

Five elements come together to revolutionize software:

  1. Price
  2. Multi-touch centric development
  3. Standard hardware available for consumers
  4. Apple's AppStore
  5. Large form factor.

The iPhoneOS is a multi-touch centric operating system. For years application developers have been subjected to the tyranny of the mouse and keyboard. This has been the only input technology that developers could reliably depend on and expect to be available on the user's system. Any software that requires different input mechanism sees its potential market reduced.

The mouse is a great device for certain class of desktop applications. But it has also led to applications that are incredibly frustrating to use. Software for editing music and audio is cumbersome. Find the target, drag it, move it, find the other button, click it, scroll, drag, click. Anyone that has used Garage Band to try to play along knows this. The same applies to software to paint or draw. The mouse and keyboard are poor substitutes for using your hands.

On the iPhone, and now the iPad, the situation is reversed. Multi-touch is the only input mechanism that developers can depend on. Apple's iPhone helped create a community of developers that think in terms of taps, pinches and twirls instead of clicks, double-clicks and right-clicks. It is no longer an after thought. It is no longer a feature that is added if there is enough time in the schedule or enough budget. It is the only option available.

Taps, pinches and twirls allow us to use the full expression of our hands to drive an application. And it is not just any multi-touch, it is multi-touch over the same surface where the application is providing feedback to the user. Software that respond to user input in the same way that a physical object responds to our physical contact is the key to create new user experiences.

This is a whole new space in which we can research, a new space that we can explore and where we can create a whole new class of computer/user interactions. With the new form factor, we can now create applications that just made no sense on the iPhone.

It is fascinating.

The standardized hardware means that software developers do not have face testing their software with dozens of combinatorial options. There are only a handful types of systems. If the software works on the core systems, they will work on all consumer devices. Standardized hardware is at the core of the success of the console gaming market, developers test and develop against a uniform platform. Price is the cherry on top of the cake, this device will be mass produced and the affordable price means that it will have a deep reach.

The possibilities for new computer/user interactions are no longer dampened by this market reality. As developers, a new door to invention and innovation has been opened for us. No longer will software developers have to cripple their user experiences based on the mouse and keyboard.

For the past couple of years I have had some ideas for some software that I wanted to build on a touch-based computer, but the specter of having a small user base for my experiments always discouraged me. Ever since I heard the rumors about Apple producing a tablet computer I have not cared about what the device looked like, or what the software stack for it was going to be. I wanted to try new touch-based UI ideas, I have dozens of ideas that I want to try out. And with Mono, I get to do it in my favorite language.

New Development Snapshot

I've modified ikvmc to use IKVM.Reflection and largely rewritten ikvmstub to directly work with the ikvm internals instead of using the java reflection API. Both ikvmc and ikvmstub can now process assemblies independent from the .NET runtime they run on. This opens up the possibility to start investigating the possibility of Silverlight support.

Changes:

  • Drag-n-drop fix by Nat.
  • Fixed regression introduced in previous development snapshot, related to field accessors.
  • Removed caching of inner classes.
  • Fix for bug #2908683.
  • Various AWT fixes by Volker.
  • Changed JNI to use standard caller ID mechanism.
  • Various JNI optimizations.
  • Fixed http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41696
  • Fixed exception sorter bug exposed by recent Mono sorting change.
  • Fixed Thread.getAllStackTraces() to resume threads that it suspends.
  • Integrated new IKVM.Reflection implementation.
  • Added AllowMultiple = true to RemappedClassAttribute.
  • Fixed atomic update helper nested types to be invisible from Java.
  • Removed support for "ikvm.stubgen.serialver" property that is no longer needed now that ikvmstub doesn't use the runtime to generate stubs.
  • Removed pre-generated stub jars from cvs and modified build process to generate them during the build.
  • Removed "constant" instance field support (which was only used by ikvmstub and doesn't make any sense anyway).
  • Removed ReflectionOnly support from runtime. Now that ikvmstub no longer requires it, there's no good reason to allow Java code to see ReflectionOnly types.

Binaries available here: ikvmbin-0.43.3681.zip

iPad Support for MonoTouch!

We did it!   MonoTouch for iPad!

24 hours after we got the iPad SDK we completed the support for the iPad for MonoTouch!

To get started with iPad development, go to http://monotouch.net/iPad and follow the instructions.

Let the iPad# hacking begin!

Release-o-Rama

Nice new releases of software that I use in the last few days.

Banshee 1.5

A new Banshee release, now supports new device syncing options, audiobooks, eMusic and GIO for non-local files. Gabriel has more details as well.

Now with a fully self-contained Mono and Gtk+ stacks on OSX. On the OSX note, I recommend Michael Hutchinson's blog entries on how to package your Gtk# app for use in OSX as well as his article on how to make your Gtk# app integrate with OSX. Both based on the lessons of bringing MonoDevelop and MonoDoc to OSX.

Jeroen Frijters released his IKVM.Reflection API. His API could be very useful for Reflection-Emit compiler writers, perhaps we could even use it in Mono's C# compiler to solve our long standing issues with Reflection. More research is needed on this area.

Maurits Rijk has published a new version of GIMP# his Mono-based plugin engine that lets you write plugins in any Mono supported language. There are samples in C# 3, F#, Boo, Nemerle, Oxygene, IronPython, Java/IKVM and Visual Basic.

Sandy released a new version of Tomboy, now supports exporting data in HTML format to the clipboard and jump Lists on Windows 7.

January 28

24 hour race

Another Mono-race, in 24 hours we are aiming to:

  • Support the iPad SDK from Apple (freshly baked and published).
  • Add MonoDevelop support for it.

When FarmVille == Productivity

Update 2010-02-08: Jonathan Pryor has merged many of my extension methods into Cadenza. I’d strongly suggest checking it out. It’s no secret to my friends that I love to program… even more so as I’ve been developing a FarmVille client in C# and having them test it. (As much as you might hate FarmVille, [...]

January 27

Taking All Bets

With the massive success of the iTunes App Store (over 3 billion apps downloaded), I think it's safe to assume the next version of OS X will include an App Store for Mac software.

The question is:

How many iterations of OS X will it take before Mac software can only be distributed (without "jailbreaking") through the App Store, thus ensuring Apple gets their cut of all Mac software sales?

Tomboy 1.1.1 Released, Tomboy Online Plans Solidify

Tomboy 1.1.1 Brings New Ones

After a brief release hiatus, I bring you Tomboy's latest development release: version 1.1.1!

Probably the coolest new feature in this release, courtesy of Stefan Cosma, is support for Windows 7 Jump Lists, which are totally awesome and should be added to GNOME.

Jump Lists In Action


Another cool fix that will make Dave Richards (and everyone else who has ever wanted to copy and paste a Tomboy note into an email or OpenOffice.org document) very happy. Gabriel Burt fixed a long-standing problem with gtk# to enable this (requires not-yet-released gtk# 2.12.10), and patched Tomboy to make rich HTML available in the clipboard. Thanks dude!

Pasting rich note content into Evolution (click for OO.o Writer and plain-text email examples)


I was planning on having a preview of automatic background sync in this release, but I just didn't get as far as I wanted on it. I'll be merging that feature in before the next release, though.

But while I was playing with autosync, I was doing a lot of restarting Tomboy, and got tired of the 2 second startup time. Most Tomboy users always run it, so startup time is not a huge deal, but for developers this just gets irritating after awhile. So I rejiggered some startup work to be delayed, causing the Tomboy icon to show up within about 0.5-1.0 seconds on my machine. This pleased me, so I included it in Tomboy 1.1.1. Take that fascist scum!

The Future of Snowy and Tomboy Online

You may have seen Brad's blog last week about our Snowy meeting. If you read the meeting minutes, you'll see that we're shifting our focus to be a little more goal-oriented. Our plan is to get a Snowy instance on GNOME servers as soon as the sysadmin team will let us. This instance will be Tomboy Online, and its needs will drive core Snowy development. We'll start with a private alpha and go from there.

Right now we're working on a Tomboy Online roadmap that breaks outstanding work into basic tasks so that contributors know where they can help. Once this roadmap is in better shape, I'll be blogging again to let you know what our plans are and how you can help us.

In the meantime, if you have any resources to share on automated testing of web sites, REST APIs, and overall web/server security, I'd really appreciate it. Ponies are great...pwnies, not soo much.

By the way, if you have opinions about GNOME hosting Free web services like Tomboy Online, please take Stormy's survey on GNOME Foundation goals for 2010! :-)

Banshee 1.5.3

We've just released Banshee 1.5.3, containing a lot of exciting new features and bug fixes.

New Features:
  • Sync device from playlist option
  • Type-ahead find in track, artist, and album lists
  • Optional cover art in lower-left corner
  • Cover art editable via drag-and-drop and right-click
  • Audiobooks library extension
  • Library-folder watcher extension
  • eMusic importer/downloader extension
  • GIO file backend, supports non-local files

Read the 1.5.3 Release Notes for the full scoop and some screenshots of the new features.

screenshot showing manual cover art editing, ipod sync-from-playlist options, and lower-left cover art

This release is what will become Banshee 1.6 and be picked up by distros; your help testing it and filing bugs is important and appreciated!

Try It

You can get packages for your distro, grab the source tarball, or follow the bleeding edge by trying it from git master.

Aaron worked hard to bring back the OS X build this release, too.

Digg It!

January 26

The country next door

I'm going to FOSDEM, the Free and Open Source Software Developers' European Meeting
I'm going to FOSDEM, and I'll be in Brussels for the whole week-end. I'm really looking forward to see again some of the people I've met in Gran Canaria, and to meet new faces.

I just have to decide if I'll be going by car or by train. One thing's for sure : I won't be driving after the Beer Event !

GIMP# 0.16 released

Before I summarize the changes in GIMP# 0.16 I need to apologize to Alexandre Prokoudine. He is a great guy that updates the SourceForge news for GIMP#, reminds me very friendly on a regular basis that I really should release a new version, handles all kinds of feedback from users that somehow end up in [...]

Parallel Development Environments? Pulque!

By Claire L. Evans / CC BY-ND 2.0 This is an updated version of Multiple Parallel Mono Environments. What is Pulque? Pulque is a collection of applications written in Ruby and Bash scripting to maintain parallel development environments. Why does Pulque exist? Three reasons: I need to keep multiple versions installed of the same software, I need to know what Version Control [...]

Monologue

Monologue is a window into the world, work, and lives of the community members and developers that make up the Mono Project, which is a free cross-platform development environment used primarily on Linux.

If you would rather follow Monologue using a newsreader, we provide the following feed:

RSS 2.0 Feed

Monologue is powered by Mono and the Monologue software.

Bloggers