Posts Tagged macruby
About concurrency and the GIL
Posted by Matt Aimonetti in ruby on October 3rd, 2011
During RubyConf 2011, concurrency was a really hot topic. This is not a new issue, and the JRuby team has been talking about true concurrency for quite a while . The Global Interpreter Lock has also been in a subject a lot of discussions in the Python community and it’s not surprising that the Ruby community experiences the same debates since the evolution of their implementations are somewhat similar. (There might also be some tension between EngineYard hiring the JRuby and Rubinius teams and Heroku which recently hired Matz (Ruby’s creator) and Nobu, the #1 C Ruby contributor)
The GIL was probably even more of a hot topic now that Rubinius is about the join JRuby and MacRuby in the realm of GIL-less Ruby implementations.
During my RubyConf talk (slides here), I tried to explain how C Ruby works and why some decisions like having a GIL were made and why the Ruby core team isn’t planning on removing this GIL anytime soon. The GIL is something a lot of Rubyists love to hate, but a lot of people don’t seem to question why it’s here and why Matz doesn’t want to remove it. Defending the C Ruby decision isn’t quite easy for me since I spend my free time working on an alternative Ruby implementation which doesn’t use a GIL (MacRuby). However, I think it’s important that people understand why the MRI team (C Ruby team) and some Pythonistas feels so strongly about the GIL.
What is the GIL?
Here is a quote from the Python wiki:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) [...] The GIL is controversial because it prevents multithreaded CPython programs from taking full advantage of multiprocessor systems in certain situations. Note that potentially blocking or long-running operations, such as I/O, image processing, and NumPy number crunching, happen outside the GIL. Therefore it is only in multithreaded programs that spend a lot of time inside the GIL, interpreting CPython bytecode, that the GIL becomes a bottleneck.
The same basically applies to C Ruby. To illustrate the quote above, here is a diagram representing two threads being executed by C Ruby:
Such a scheduling isn’t a problem at all when you only have 1 cpu, since a cpu can only execute a piece of code at a time and context switching happens all the time to allow the machine to run multiple processes/threads in parallel. The problem is when you have more than 1 CPU because in that case, if you were to only run 1 Ruby process, then you would most of the time only use 1 cpu at a time. If you are running on a 8 cpu box, that’s not cool at all! A lot of people stop at this explanation and imagine that their server can only handle one request at a time and they they rush to sign Greenpeace petitions asking Matz to make Ruby greener by optimizing Ruby and saving CPU cycles. Well, the reality is slightly different, I’ll get back to that in a minute. Before I explain “ways to achieve true concurrency with CRuby, let me explain why C Ruby uses a GIL and why each implementation has to make an important choice and in this case both CPython and C Ruby chose to keep their GIL.
Why a GIL in the first place?
- It makes developer’s lives easier (it’s harder to corrupt data)
- It avoids race conditions within C extensions
- It makes C extensions development easier (no write barriers..)
- Most of the C libraries which are wrapped are not thread safe
- Parts of Ruby’s implementation aren’t threadsafe (Hash for instance)
Should C Ruby remove its GIL?
- No: it potentially makes Ruby code unsafe(r)
- No: it would break existing C extensions
- No: it would make writing C extensions harder
- No: it’s a lot of work to change make C Ruby threadsafe
- No: Ruby is fast enough in most cases
- No: Memory optimization and GC is more important to tackle first
- No: C Ruby code would run slower
- Yes: we really need better/real concurrency
- Yes: Rubber boots analogy (Gustavo Niemeyer)
How can true concurrency be achieved using CRuby?
- Run multiple processes (which you probably do if you use Thin, Unicorn or Passenger)
- Use event-driven programming with a process per CPU
- MultiVMs in a process. Koichi presented his plan to run multiple VMs within a process. Each VM would have its own GIL and inter VM communication would be faster than inter process. This approach would solve most of the concurrency issues but at the cost of memory.
Finally, when developing web applications, each thread spend quite a lot of time in IOs which, as mentioned above won’t block the thread scheduler. So if you receive two quasi-concurrent requests you might not even be affected by the GIL as illustrated in this diagram from Yehuda Katz:

This is a simplified diagram but you can see that a good chunk of the request life cycle in a Ruby app doesn’t require the Ruby thread to be active (CPU Idle blocks) and therefore these 2 requests would be processed almost concurrently.
To boil it down to something simplified, when it comes to the GIL, an implementor has to chose between data safety and memory usage. But it is important to note that context switching between threads is faster than context switching between processes and data safety can and is often achieved in environments without a GIL, but it requires more knowledge and work on the developer side.
Conclusion
Hey Apple, please be nice and share
Posted by Matt Aimonetti in macruby on March 7th, 2011
My name is Matt Aimonetti, and in my free time I work on Apple’s open source Ruby implementation named MacRuby. I’m also the author of O’Reilly’s MacRuby book. As you can imagine, I’m very thankful that Apple initiated the MacRuby project a few years ago and have been an avid supporter. MacRuby is awesome to develop OS X native applications using the Ruby language and even allows you to compile down your apps to machine code. It’s a great alternative to Objective-C.
MacRuby is so awesome that Apple is even using it in its upcoming OS. The only problem is that Apple apparently decided to not share MacRuby with other OS X developers and put MacRuby in the OS private frameworks. While this doesn’t affect the project itself, it does affect OS X developers like myself who can’t link to Lion‘s private MacRuby framework and are forced to embed MacRuby with their applications.
That’s why I have opened a ticket on Apple radar system to ask that MacRuby be made a public framework.
If you also want Apple to make this change, please take a minute and let them know.
Automatically generating BridgeSupport files
Posted by Matt Aimonetti in macruby on February 19th, 2011
Today I was helping someone write an Objective-C framework around cocos2d.
C/Objective-C code can be called directly from MacRuby. However the Obj-C code you would like to use might be using some ANSI C symbols that are non-object-oriented items such as constants, enumerations, structures, and functions. To make these items available to our MacRuby code, you need to generate a BridgeSupport file as explained in this section of my book.
In our case, we were working on the framework and I didn’t feel like manually having to regenerate the BridgeSupport file every single time I would compile our code. So instead I added a new build phase in our target.
And I added the following script to run at the end of the build:
# This step generated the bridgesupport file for the framework
PATH="$PATH:/usr/local/bin"
mkdir -p $TARGET_BUILD_DIR/$PROJECT_NAME.framework/Resources/BridgeSupport/
gen_bridge_metadata --64-bit -f $TARGET_BUILD_DIR/$PROJECT_NAME.framework/ -o $TARGET_BUILD_DIR/$PROJECT_NAME.framework/Resources/BridgeSupport/$PROJECT_NAME.bridgesupport
The script just executes the steps required to add the BridgeSupport file to your framework. I can now rebuild my framework without having to worry about BridgeSupport.
MacRuby book update
Posted by Matt Aimonetti in macruby on January 15th, 2011
I just pushed a major update to my MacRuby book.
If you already purchased an electronic copy (thank you!), go to your product page and download an update. Note that if you are on an iPhone or iPad and you click on the .epub link, the file will automatically load in iBooks, same thing if you have the kindle app installed and you are clicking on the .mobi file.
If you haven’t purchased an electronic version yet, you can still read the book in HTML format here. If you choose to do so, please still think about leaving a review on the O’Reilly site to show your support to myself and to my publisher.
What’s new in this update?
- I refactored the introduction to the book, you know have a new Chapter 2 which introduces you to GUI app development and lets you build a full app right away to give you an idea of what is available.
- Chapter 3 covers more advanced concepts and was updated to reflect changes made on trunk.
- The chapter on Core Data is now almost done, I will soon push an update with the end of the chapter, but between the chapter content and the example app, you should be good to go today.
- GitHub repo with the code used in the book. (work in progress, I need to move more code there)
- The book is now divided in two parts, one more theoretical and more practical. Even if part 2 isn’t written yet, the table of contents shows some of the examples I will cover. I hope to have some of these chapters written in a few weeks.
- Lots of small fixes and updates thanks to the readers comments and to my editor.
Finally if you are interested in pre-ordering the book, Amazon runs a great deal on the book:
Thank you for your support!
Writing an open licensed book
Posted by Matt Aimonetti in macruby, Misc on May 9th, 2010
To celebrate last week’s release of MacRuby 0.6, O’Reilly and I started publishing the draft of my MacRuby book online: http://macruby.labs.oreilly.com/
I started thinking about working on “MacRuby: The Definitive Guide” last year when I realized that the project had a great future but there was a serious lack of documentation. With the support of the MacRuby team, I worked on a table of contents and a pitch. The next step was to decide what we wanted to do with the book.
I know a lot of technical book authors and most of them will tell you the same thing: if you think that you are going to make money writing a book, you are wrong. Even if your book sells well, because of the time invested in writing the book, you are probably better off doing consulting work and charging by the hour.
So since day one, I knew that this project would not make me rich. The goal was to share knowledge not to reimburse my mortgage or save California from bankruptcy. While publishing a web book is great, distribution is quite limited, especially if you try to reach people outside of your network. That’s why I decided to start talking to a few publishers. Most publishers I talked to were interested in working on the book, however they were not really keen on publishing a Creative Commons Attribution-Noncommercial-No Derivative licensed book.
Let me explain why I think releasing technical books under a CC license is important. As you might know (or have figured out by now), I am not a native English speaker. I actually learned my first English words thanks to the computer my dad had at home. The problem when you don’t live in an English speaking country and you want to learn about the cutting edge technology is that you have to understand English. Thanks to the Internet, learning and practicing English is now much easier that it used to be. However, if you want to have access to books, most of the time you have to wait until someone translates the book and publishes it in your country or you have to manage to get an English version delivered to your country. This is often a pain because of national credit card limitations, international delivery restrictions etc… If you manage to find a way to get a copy, the book ends up costing a lot of money.
What does that mean in practice? Most of the technical books are first available in the English speaking western world, then slowly translated and/or distributed around the world. By the time you get a legal copy in Bolivia, Algeria or Vietnam, a new edition is probably out in the US probably because the technology evolved. Maybe that explains some of the book piracy worldwide?
Think about it for a minute: knowledge is power and time is money. And what do we do? We delay knowledge distribution. This is why I am a big fan of the Khan Academy and its awesome free online courses.
Turns out O’Reilly shares my vision and has already published a lot of books under various open licenses: http://oreilly.com/openbook/ I was also interested in publishing the content of my book ASAP so people could access it right away even though there would be lots of typos and missing content. This is also something O’Reilly has already done with the CouchDB and the Scala books.
Talking with Jan Lehnardt about his experience working with O’Reilly on the ‘CouchDB: The definitive guide’ book, I realized that we seem to have some shared interests. I contacted Jan’s editor and we decided to start working on the MacRuby book. The book will be available later on in all the usual commercial formats and I hope people will show their support so O’Reilly will be encouraged in their choice to continue publishing CC licensed book. At the end of the day, purchasing a CC licensed book helps supporting the authors, the publishers but also all the people who can’t have access to the latest technical books.
Finally, working on a book is not an easy thing, especially when you have to write it in a language that’s not yours. But I have to say that the community support has been amazing. Even John Gruber sent a fireball my way. And since the announcement was made, I have received a lot of comments, tweets, emails etc… It is very encouraging and it gives me the motivation needed to work on the book after a long work day.
Undo/Redo in MacRuby
Posted by Matt Aimonetti in macruby on February 2nd, 2010
As I’m working on my upcoming O’Reilly MacRuby book, I’m writing quite a lot of example code. I have spent the last few weeks digging through most of the Foundation framework classes to hopefully make Cocoa more accessible to Ruby developers.
In some instances things might look quite weird to someone new to Cocoa in some cases, things seem almost too easy. Here is an example implementing a undo/redo functionality using Foundations’ NSUndoManager.
framework 'Foundation' class Player attr_accessor :x, :y def initialize @x = @y = 0 end def undo_manager @manager ||= NSUndoManager.alloc.init end def left undo_manager.prepareWithInvocationTarget(self).right @x -= 1 end def right undo_manager.prepareWithInvocationTarget(self).left @x += 1 end end
Which you can use as such:
>> lara = Player.new => <Player:0x200267c80 @y=0 @x=0> >> lara.undo_manager.canUndo => false # normal since we did not do anything yet >> lara.left => -1 >> lara.x # -1 => -1 >> lara.undo_manager.canUndo => true # now we can undo, so let's try >> lara.undo_manager.undo # undo back to initial position => #<NSUndoManager:0x200257560> >> lara.x => 0 >> lara.undo_manager.canUndo => false # we can't anymore which makes sense >> lara.undo_manager.canRedo => true # however we can redo what we just undone >> lara.undo_manager.redo # redo to before we called undo => #<NSUndoManager:0x200257560> >> lara.x => -1
The above example was tested in macirb but as you can see, actions can be undone and redone very very easily. This is just a quick preview of what you can do using Ruby + Cocoa and hopefully it will give you some cool ideas to implement.
How to detect Cylons with MacRuby
Posted by Matt Aimonetti in macruby on January 18th, 2010
Over the weekend, MacRuby’s trunk became version 0.6 and the bug fixing is currently done in both the 0.5 branch and trunk. Based on MacRuby’s usual release cycle I would expect a 0.5 beta3 or 0.5 final to be released soon so most of the work can be focused on trunk.
I’ll let you check on the TODO list to see what was done in 0.5 and what is in the plan for 0.6.
However, there is one feature in 0.6 that I know lots of you will just love! The good news is that Laurent already committed a very early version of his work so I figured, I should share the good news with you:
Introducing MacRuby’s debugger!
If you were expecting to read: “a Cylon detector!”, keep on reading.
Again, this feature is in really early development since it’s scheduled for 0.6 and 0.5 final is not out yet. But if you install MacRuby using the nightly builds or build from trunk, you can already play with the debugger.
Let me give you a really quick tour of the debugger.

Let’s imagine that we were given the task to debug the cylon detector written by Gaius Baltar which looks like that:
characters = %w{Adama Apollo Baltar Roslin StarBuck Six} def cylon?(character) false end characters.each do |character| if cylon?(character) puts "#{character} is a Cylon!" else puts "#{character} is not a cylon." end end
Here is what happens when I execute the script:
$ macruby cylon_detector.rb Adama is not a cylon. Apollo is not a cylon. Baltar is not a cylon. Roslin is not a cylon. StarBuck is not a cylon. Six is not a cylon.
The only problem is that we all know that Six is a Cylon, the detector isn’t working right so let’s debug it:
$ macrubyd cylon_detector.rb
Starting program.
cylon_detector.rb:1> b cylon_detector.rb:8 if character == 'Six'
Added breakpoint 1.
cylon_detector.rb:1> c
Adama is not a cylon.
Apollo is not a cylon.
Baltar is not a cylon.
Roslin is not a cylon.
StarBuck is not a cylon.
cylon_detector.rb:8> p cylon?(character)
=> false
cylon_detector.rb:8> p "This detector is broken!"
=> "This detector is broken!"
cylon_detector.rb:8> p def cylon?(character); character == 'Six'; end
=> nil
cylon_detector.rb:8> p cylon?(character)
=> true
cylon_detector.rb:8> p cylon?('Matt')
=> false
cylon_detector.rb:8> c
Six is a Cylon!
Program exited.The first thing we do is to add a conditional breakpoint:
b cylon_detector.rb:8 if character == 'Six'
Basically, the debugger will add a breakpoint at line 8 which will only be active when the value of ‘character’ is equal to ‘Six’.
Now that the breakpoint added, we can continue the program execution and just wait until we reach the defined condition.
cylon_detector.rb:1> c
Once we reach the breakpoint, we evaluate the result of “cylon?(character)” by using the p command. We see that the result is “false” when we know for sure that it should be true since the value of the character variable is ‘Six’ and she is a cylon. At this point, you might have guessed that somewhat acted as a cylon agent and I pretended to fix the problem by overwriting the “cylon?” method:
cylon_detector.rb:8> p def cylon?(character); character == 'Six'; end
Now that the method is overwritten, I can check that Six is recognized as being a cylon:
cylon_detector.rb:8> p cylon?(character) => true
and also check that I am not detected a cylon:
cylon_detector.rb:8> p cylon?('Matt')
=> falseI can now continue the execution of the program and see that Six is detected as a Cylon!
Of course this is just a very early version of the debugger and we will see lots of improvement in the next few weeks. Who knows someone might even create a GUI for the debugger and/or a Xcode integration.
Anyway, the point being that MacRuby developers should expect a lot of awesome stuff coming up their way soon. (also be careful about the skin jobs around you, cylon detectors can’t be trusted!)






