Blog Closed

This blog has moved to Github. This page will not be updated and is not open for comments. Please go to the new site for updated content.
Showing posts with label Parrot4Newbies. Show all posts
Showing posts with label Parrot4Newbies. Show all posts

Thursday, January 28, 2010

GSoC Idea: Asynchronous IO System

I talked to Coke briefly yesterday evening about GSoC. I hadn't heard specifically that Parrot would be applying for GSoC again this year and even though I was hopeful I didn't want to presume. He didn't have a firm answer about whether Parrot was planning to apply as a mentoring orgnization, but he did say "I think we'd be crazy not to". That's good enough for me.

There are a few topics that I've covered more than others on this blog. One of them has been asynchronous IO. I've covered that topic at length, and was hoping to have the time to implement the system myself. Regrettably I don't think I will have time to do it before summer, which means it's ripe for prospective GSoC students to gander at.

Parrot has a basic, synchronous-blocking IO system right now. This is all well and good but let's all face facts: IO tends to be among the slowest operations that a program performs. IO represents a huge bottleneck, especially for certain types of IO-intensive programs. To alleviate this, Parrot's design documents describe an asynchronous system where IO operations are performed in the background while the program itself can continue performing non-IO operations at the same time.

I'm purposefully conflating ideas of "asynchronous" and "non-blocking" ideas, though strictly speaking there are differences between the two. What Parrot really needs is an "asynchronous non-blocking" IO system, which I will just call "AIO" for short.

In an AIO system, IO requests are dispatched to the operating system and program execution immediately resumes. The dispatch operation returns a request object. There are two ways to keep track of the IO request, if you need to keep track at all: First is to poll the request object to see if it's completed (or had an error). The second is to provide a callback with the request and the OS will execute the callback when the request has been satisfied (again, with error information if the request was not successful).

A current Parrot print operation looks like this:

print "Hello World\n"

An AIO implemention would add new forms like this:

request = print "Hello World\n", callback

This presents a lot of flexibility, and could potentially improve performance significantly for IO-intensive programs.

The IO system could use a few miscellaneous cleanups but is generally not in bad condition. A good implementation of AIO will be well-integrated with Parrot's event scheduler, and possibly with with the threading implementation as well. The scheduler is in good condition but the threading system is not. The aspiring AIO developer may find herself making fixes to any of these systems along the way. If AIO sounds like the job for you, you may want to start reading through the source code now so there are no surprises over the summer.

Wednesday, November 18, 2009

Trac Ticket Hunt

Yesterday, after a herculean effort, the Parrot devs closed out the remaining old tickets from the RT system. Many of the tickets were vague and uncloseable, or unreproducible. Many of them were translated into Trac tickets for futher monitoring.

Of course, we still have a lot of open tickets in Trac. Over 600 of them, as Coke pointed out in an email this morning. That's quite a huge number of open issues, and really too many for our current development team to deal with in a reasonable amount of time. We need help dealing with this huge backlog, and this is a great opportunity for new interested people to get involved in Parrot.

Preparing for 2.0

The 1.8 release went out the door on Tuesday, and I think it went much more smoothly than 1.7 did last month. Not completely without hiccups, but better. Now we're in the home stretch for the big 2.0 release in January where the mantra is "production ready".

What does it mean to be production ready? First and foremost I think of stability and reliability. Nobody is going to invest time and effort in software that isn't stable. Next, I think about performance. Computer hardware isn't cheap, and we can't be shipping a piece of software that hogs processor cycles and costs companies more money to support.

With these goals in mind (and I would love to hear what other people think "Production Ready" means), I think there are two big things we need to focus on: Testing and Profiling.

Testing

Test reports are good, and we're starting to get a very large volume of test reports flowing in, including test reports on new or exotic system. Bravo to anybody who has set up an automatic build bot in the past few months. It is sincerely appreciated.

Test reports are a good and necessary first step, but are by no means the end. Tests are good when they all pass, but that's boring (and unfortunately, it's not usually the case). What's really interesting and important is finding the failing tests and writing up Trac tickets for them so they can get fixed. So here are some things you can do to help:
  1. Monitor the stream of incoming Smolder reports and look for failures
  2. If the failure is happening on a platform that you can test on, try to verify it
  3. See if you can isolate the code from the test that is failing. Bonus points: See if you can write your own small test that demonstrates the bug. The smaller the better.
  4. Open a Trac ticket including information about your platform, the revision where the failures first start appearing (as close as you can tell), and any test cases you've produced that exercise it.
  5. If you're able, submit patches to fix the issue, patches to improve testing of the issue, or patches for documentation to explain what the desired behavior is
All of these things would be very awesome, and are all great ways to get involved in Parrot without having to dive into the source code head first.

Profiling and Benchmarking

Let's not fool ourselves: Parrot is not speedy fast right now as far as VMs are concerned. We don't have JIT, we don't have a good GC, we don't even have PIC. We don't do enough caching, our startup time is still terrible, etc. There are lots of big optimizing features that we need to implement in the coming months and years if we truly want to be a viable and even formidable alternative to other VMs.

However, this all doesn't mean that the only performance benefits that we need come from these huge projects with weird acronyms. There are plenty of small implementation and algorithmic improvements that we can make throughout to start slimming this bird down, some of which will have serious effects on our performance. Parrot is so large though that we can't necessarily find all these little optimization opportunities easily. We need to narrow the search. This is where profiling and benchmarking come in. This is where we need you.

Parrot has a fancy new profiler tool that can be used to profile programs written in PIR or any of the HLLs that run on top of Parrot. It still needs lots of documentation, but it should be mostly easy to use for people willing to poke around in it. If you can find a good example program that demonstrates some real-word usage patterns, we would love for you to profile them and send us the reports. Knowing where the bottlenecks and slowdowns are will help us to target, refactor, and improve them, and that's a big help.

To start up the profiler, run Parrot with this incantation:

> parrot -Rprofiling

For more information about what to do with it, hop onto the IRC channel and ask around. I haven't used this much myself, but it would be cool to get started.

To prove that we are indeed making things faster, we need benchmarks. Good benchmarks are programs that perform lots of very repetitive work and target a particular Parrot subsystem. We want programs that really exercise Parrot, and can do it in a consistent way. Then, we can use timings on these benchmarks to show whether Parrot's performance is improving or getting worse over time. This is very important.

Ticket Triage

As Coke mentioned in his email, we can't sit back and congratulate ourselves now that RT is empty. We need to focus our attentions now on the growing backlog of tickets in Trac. Some of the issues documented there are very serious and will definitely prevent Parrot from being stable and "production ready" by 2.0.

As Coke outlined, we need people to go through old tickets and answer a few questions:
  1. Can we reproduce this issue now with Parrot 1.8.0? Many tickets were filed weeks or even months ago, and may have disappeared in the course of normal development
  2. Look at RFC tickets (requests for comments) and weigh in. Do the changes described make sense? Would they be beneficial? Many of these tickets are simply waiting for some kind of discussion before they get closed.
  3. If the ticket involves an HLL, see if you can reproduce the issue using pure-PIR code instead of high-level code. Parrot operates on PIR natively, so Parrot developers are most easily going to be able to fix problems that can be demonstrated in PIR
  4. If you see a ticket with a segfault, sigbus, sigfpu or other system error condition, see if you can provide a backtrace.
  5. If a ticket contains a patch, see if the patch still applies cleanly to trunk. If so, see if the patch fixes the problem.
  6. Add comments or set other information to make sure the ticket stays up-to-date and informative. Even if the information you add is small ("Still a problem!" or "fixed!"), that's still something. If nothing else, make sure the ticket is properly categorized by component, milestone, etc. You'll probably need to create a Trac account (free and easy!) in order to make modifications
  7. Look for duplicates. If two tickets describe the same problem, one of them can go.
  8. If the ticket can be legitimately closed (fixed, no longer a problem, a duplicate, etc) make sure that happens. Hop on IRC or the mailing list and harrass people until it gets closed. It may be a little bit annoying, but it will get results.
Conclusion

I haven't done a Parrot4Newbies post in a while, and I know some people have been looking for ways to get involved. With 2.0 on the horizon testing, profiling, and ticket triaging are all great and incredibly pertinent ways to get involved. And more importantly then just being involved, these are all great ways to help Parrot grow and get ready for the big milestone. So if you are interested in Parrot and have a few spare moments, take a look at some tickets and see what you can accomplish. I can guarantee that anything you get done will be much appreciated.

Wednesday, November 4, 2009

Libraries And Extensions

Parrot is just a virtual machine, an engine that's intended to run other programs and facilitate inter-operation between them. It's a facilitator for other programs and compilers and technologies; a linchpin for a whole new software environment. Getting compilers to run on it and communicate with each other is one goal: Getting them to all work seamlessly with a large assortment of native libraries is another.

We don't just want Parrot to be a cool program, we want it to enable a whole ecosystem of cool languages, programs, and libraries. I write a program in Perl6, use your framework that you've written in Cardinal, include it in a PHP webpage, and everybody gets to use system libraries written in C. To do that, we need people to create cool compilers, write cool programs, and write wrappers around cool native libraries. Seriously, everything cool.

One big part of this puzzle is Plumage, Parrot's module ecosystem manager. If you haven't already, check it out. Once registered with Plumage, any Parrot user should be able to download any compiler or any library that targets Parrot with only a few simple commands. It's like CPAN for Perl5, except has the potential to get bigger. Much bigger. With Plumage in place, we can really start building up the addons: PIR code libraries, native code library wrappers, compilers, applications, etc. The possibilities are endless, and provide a huge number of openings for new Parrot developers to get started on.

Library Wishlist

What native libraries do you use? What libraries do you wish Parrot had easy wrappers for? The first thing we need is a list of libraries that people want to use, and possible some use-cases for them (if they are obscure or rare enough that our developers won't be familiar with them). Post suggestions here in the comments of this blog, or on the Wiki, or in Trac, or wherever.

Darbelo put together the DecNum library wrapper for his GSoC project. I've been (with lots of help!) trying to put together wrappers for the BLAS and LAPACK linear algebra libraries. Eventualy we will be able to easily install these things through Plumage, and then other projects will be able to use them as dependencies. These are just two examples, and are both math-centric, but are certainly not the only libraries that need some attention. So ideas and suggestions for new libraries to target would be a great help.

Library Wrappers

Are you familiar with a popular library? Better yet, are you familiar with APIs and internals? We could use your help writing a wrapper around that library for Parrot. The benefit of course is that once you write a wrapper for the library once, it will be usable from programs written in all languages on Parrot. People writing in Ruby, Perl6, Tcl, and even eventually Perl5 will be immediately able to use your work.

Writing a library wrapper is relatively easy and straight-forward, although there isn't a lot of good documentation about the process. Actually, that would be another cool thing for newbies to do: Take a look at the documentation we do have and help point out areas that are confusing or short on details. Tell us what's hard to understand and we can help improve things so other new users will be able to get started faster.

Pure-Parrot Module

Austin has been working on a new project called Kakapo that's a library of runtime helper function specifically for NQP. This is an example of another class of extension: a pure-parrot library module. Pure-Parrot modules are ones that are written in PIR, or another language that runs on top of Parrot. These modules have the benefit that they don't need any other compiled binaries besides Parrot, which is great for platform interoperability. Write once, use anywhere. This is the power of Parrot.

Parrot ships with a small set of libraries, although these are mostly utilities that Parrot itself needs for building or testing. There is plenty of room open for creating new libraries as well to do all sorts of things. Need some ideas? Look at CPAN. There are thousands of libraries there which could be rewritten in PIR or NQP, which would immediately open them up for use with other languages as well. Writing cool libraries like this is a great way to get started using Parrot, and a great way to contribute back to the rest of the community.

Conclusion

The Parrot ecosystem is growing at an incredible rate. New language compilers, libraries, projects, and applications are springing up all over the place that use the tools Parrot provides. It's a compelling platform, and is demonstrably useful for a number of different types of projects. If you're interested in getting started using Parrot, non-core projects like this are a great way to get acclimated.

If you start a cool new project, or if you join a preexisting one, please let me know so I can highlight it on my blog.

Monday, July 20, 2009

Parrot4Newbies: Reporting Problems

In my past few Parrot4Newbies posts, I mentioned several times that new users should do tests and report problems. However, one helpful commenter pointed out to me that I didn't mention precisely how to make those reports. Today I'm going to talk about precisely that.

There are a few good ways to get in touch with the Parrot developers when you have a problem, or an issue, or a suggestion, or even random comments. There is the mailing list, the IRC chatroom, and the Issue Tracker. Each of these are useful for various things, and people from one may direct you to another if your message would be better there.

The Parrot Mailing List

The Parrot mailing list, parrot-dev AT parrot.org, is a great way to get in touch with the Parrot community as a whole with important issues. However, as with any mailing list, there will be a delay in receiving a response. I don't remember all the rules, but you might need to subscribe to the list before you can post to it. You will definitely want to subscribe if you want to read any responses.

When sending an email to the list make sure to use a descriptive subject line, like "test failure on amd64 in packfile.t" instead of something general like "test failure". Describe whatever issue you are seeing and definitely include any log files that help give more information.

Mailing lists are aren't always reliable, so if you send a message you may not receive a reply in a reasonable amount of time. This is just a fact of the medium and shouldn't be taken as any kind of insult or offense. If you're looking for more immediate responses, use the IRC chatroom. If you don't need an immediate response, but don't want your issue to be lost in the sands of the mailing list archive, use the issue tracker instead.

#parrot IRC Chatroom


The Parrot team maintains an IRC chatroom #parrot on the irc://irc.parrot.org network. If you've never used IRC before and don't know what this means, I'm sorry but it's beyond the scope of this post to teach you. However, you want to send me a quick comment or a personal message through some other venue, I would be happy to teach you how to access it.

The IRC chatroom is a great place to go to get immediate responses, but only a small subset of the Parrot team would be online at any given time. Some times of day there are very few developers on at all. If you find a problem that is very small, report it on the IRC chatroom and you may be lucky enough to get an immediate fix for it. If the people online at the time cannot help you immediately they will probably direct to to the issue tracker or to the mailing list in order to get a larger number of eyes looking at your report.

On IRC you can use the nopaste service to post logfiles and backtraces and programs and any other information you have. Just make sure you specify the IRC channel as "#parrot" so people in the chatroom can see it.

IRC is a great medium for immediate communications, and allows a higher bandwidth then either the issue tracker or the mailing list. However, there is a definite lack of persistence and if your issue isn't answered immediately you can't expect people will backlog and answer your question later. There are Logs for the IRC channel, but most conversations are too long, rambling, and interleaved for people to be able to follow after the fact without some specific direction. Again, it's just a fact of the medium. If you don't need an immediate response (or don't expect anybody to have one ready), it may be better to post your issue to the mailing list or the issue tracker instead. If you don't know where to post an issue, ask on IRC and somebody will tell you where to go.

IRC is probably the best place to go if you need help or have questions, because people there can usually answer your questions quickly or point you to the proper documentation. The mailing list may be better for more complicated questions, or questions that the people on IRC cannot answer.

Parrot Issue Tracker

If you have a bug or a report, the best place to go is probably the issue tracker. Creating a bug report on Trac automatically generates an email to the Parrot mailinglist too, so everybody will see it at least once. Plus, all open bugs will stay visible in the tracker until they are resolved.

This is a pretty good system although there are some logistical issues that can prevent older tickets from getting the attention they need. There are also problems where duplicate issues can be take up multiple active tickets, and information isn't always updated in tickets in a timely manner.

If you have an issue and really need it dealt with quickly, make sure to set the priorities appropriately and try to assign the ticket to a specific developer. Choosing the right developer to assign a ticket to can be tricky, so it's probably best to ask on IRC or the mailing list first to find out who is interested in the issue and is capable of fixing it. Keep in mind that developers are very busy people and all have long lists of other tasks that they are working on, so you can't expect overnight results.

To create and be able to edit tickets you will probably want to create an account on Trac. Creating an account is free, quick, and easy, and doesn't require too much information from you.

Conclusion

So there are the three ways to get in touch with the Parrot development team when you need help or have an issue to report. If people need any more details then I have provided here please ask and I will be happy to point you in the right directions.

Friday, July 17, 2009

Parrot4Newbies: Platforms

The problem with Parrot building on so many platforms, or attempting to build on so many, is that the different platforms have different APIs and different capabilities that Parrot needs to be aware of. Several systems, especially IO and IPC, need platform-specific implementations, along with associated multi-platform testing. Simply put, we need lots of people to be looking at Parrot on lots of platforms. Here are some jobs that a newcomer to Parrot can get to work on, especially if you have access to a rare system.

Setup a Smoke Tester


I mentioned this in a previous post. Even though I don't want to repeat myself generally, setting up an automatic smoke tester is really a great and easy way to get involved in Parrot and to be a huge immediate help for the community. Since my last post went out we've seen a few new IRC bots showing up to inform us automatically about build and test failures, and we've seen a few new platforms showing up in the smoke test results. I can't overstate how valuable this is, seriously!

Interprocess Communication

Know anything about IPC? More importantly, know anything about IPC on your rare system? Parrot has basic functionality built in to spawn new processes, and our first real pipes implementation should be landing into trunk this week. However, a lot could benefit from people with solid know-how getting to work on some of the nitty-gritty issues. Parrot has several tickets dealing with IPC, some of them are among the oldest tickets in RT.

Ticket #31144 has to do with the arguments to our spawn and exec functions, which need to be cleaned up and parsed in a platform-independent way.

Ticket #36619 likewise involves the return values from these two operations, which should be returned as platform-independent values so Parrot can make use of them at a higher level.

Files and Filesystems

Parrot has a special OS PMC, which is a singleton type that allows some interaction with the operating system. The most important among these operations are file interaction operations. Unix people may know a utility called "touch", and Perl 5 people may be familiar with the utime builtin. Parrot doesn't really have a way to update file times like this, and you're able we would love for you to add one. Ticket #38145 discusses this particular need.

Likewise, Ticket #38146 discusses the creation of a file copying utility, although discussion there has since degraded into a general discussion about what's the best architecture to use for implementing these kinds of functions. Input on that discussion, or a solution to the problem, would both be appreciated (and moving the ticket from RT to Trac where it can be even more visible would be a big plus!)

Are you a Win32 person? There are lots of tickets around that deal with some of the idiosyncracies of that platform. Ticket #39853 specifically deals with the way forward slashes and backslashes are used in Windows, and how they should be standarized in file names.

Libraries and Dynamic Loading


Parrot aims to be very dynamic and pluggable, and a number of items from PMC types to opcodes to libraries can be loaded in to Parrot at runtime. But for all this to work, Parrot needs to have a robust mechanism for finding and loading libraries, including installed system libraries and local libraries.

Ticket #37258 involves problems loading libraries with periods in the filename. It's a practice that's far more common on Linux then in Windows, but important to get right in a platform-agnostic way.

Compilers

Any good with Compilers? Parrot builds really well with GCC, but when you start talking about other compilers the situation isn't so rosy. We always need lots of help (including fixing errors/warnings and setting up automatic smoke testers) getting Parrot to build with other compilers. Here are some of the ones that we need more testing and work on, specifically:
  • Microsoft C Compiler, 64bit systems
  • LLVM and Clang, 32- and 64-bit systems
  • Intel C Compiler, 32- and 64-bit versions
  • G++
Other compilers would be great too, but these are some of the big ones that we would love to get more help with. If you're good with your compiler, and it's on this list, we would love to hear from you!

Tuesday, July 14, 2009

Parrot4Newbies: Encapsulation

If you were anything like me, you probably rolled your eyes when your professors talked about all sorts of abstract concepts like "abstraction" and "encapsulation". At the time they were just words that didn't seem to have a lot of meaning; big, new vocabulary words that made the lectures more difficult to follow.

Well, now that I've worked on bigger projects then "Implement a merge sort algorithm on an array of 100 integer values in Java", bigger projects like Parrot, I have a better appreciation for what encapsulation is and why it's important.

There are many systems in Parrot which were written hastily and not always to the highest coding standards. I say that with full knowledge that often times concerns about performance and deadlines outweigh the need to produce beautiful and maintainable code. And in many cases a system is prototyped "quick and dirty" with the intent that it would be redone eventually, but immediately thereafter the coder moves on to different projects. This is a normal part of the development process (especially in the world of Perl!), but eventually is now.

Several of Parrot's subsystems are poorly encapsulated, if any attempt has been made to encapsulate them at all. For people who are decent with C, and are good at cleaning up code without having to make all sorts of functional changes, I have some jobs for you:

The Strings System

The strings subsystem is a big offender in terms of non-existant encapsulation. The "guts" of the STRING structure are poked at directly throughout the codebase, and many different locations throughout handle them differently. Parrot doesn't even really support read-only strings like it should right now, because there are too many places where strings are accessed to check for a read-only flag in all of them.

The string system needs to be encapsulated so we can make some much needed improvements to stability, performance, and capability in the future. Cleaning the API and abstracting the details behind a clean interface are the first steps in any future development efforts. The best part is that these fixes can be made incrementally, a perfect task for a new hacker.

Contexts

Contexts are very important things. They represent the current execution environment, containing the current register set, the set of scoped lexical variables, etc. Because of their importance as a central component in Parrot, and because the API is so woefully unencapsulated, any improvements to the Contexts subsystem are slow or even undoable.

And I've discussed on this very blog some of the big projects we have planned for Contexts.

Contexts are very central to Parrot, so working to clean and properly encapsulate them will take the intrepid coder on a whirlwind tour of the Parrot core internals: the calling conventions, JIT, runcores, lexical variables, exceptions, etc. It's a big job, and a great opportunity to explore the Parrot codebase and get your feet wet. It's also another task that can be done in small incremental steps.

The benefits however are many, and I'll be happy to talk at length about them to anybody who is interested.

GC String Allocator

I've got a dirty little secret to share: Parrot really has two separate GC cores. Or, two facets of a single core (the terminology doesn't really matter). The first, which people talk about the most, is the fixed-size header allocator. The second, which goes oft-unmentioned, is the string buffer allocator.

The GC system itself is pretty well encapsulated, but the individual internal components of it are not. Specifically, the string allocator relies on intimate internal knowledge of the fixed-size header allocator core, which means replacing one requires massive edits (if not complete replacement ) to the other. Separating the two out to use a cleaner interface and enabling one to be updated without affecting the other would be a major boon for Parrot. This one task would be a major help in writing new GC cores, which in turn would have a major performance boost for Parrot.

Conclusion

These aren't the only systems and subsystems in Parrot that need better encapsulation, almost all of the systems do. This is just a good representative set of such systems that are in the most dire need. Hackers new to the Parrot community should definitely try their hands and cleaning up interfaces to some of our systems, because a little bit of cleanup work can go a long way to helping Parrot grow.

Friday, June 26, 2009

Parrot4Newbies: PMCs

This is the third installment in my series of Parrot4Newbies, and today I am going to talk about PMCs. As a general reminder, if you're interested in any of the topics I've discussed so far, make sure to keep track of the comments. I'm going to post more tasks on each topic in the comments, and I hope other people will post new ideas there as well.

I've talked about documentation and the test suite as great places to get involved in Parrot quickly. However, neither of these involve a lot of code, especially not a lot of C code which many people know very well. If you know C pretty well and want to get right into Parrot's guts, I can't think of any place better to get started then the PMC system. PMC types are defined in /src/pmc/*.pmc files. Parrot's core API for dealing with PMCs is located in src/pmc.c, and our implementation of objects (which are based on the Object PMC) is located in src/oo.c. The current compiler tool for converting PMCs from their strange C-like language into pure C is located in lib/Parrot/Pmc2c/*.

Refactor Messy Code

Several of the core PMC types are very old and in need of a major cleanup. Some things need to be refactored for readability and to maximize code reuse. Other things, especially critical core types, need a little bit of optimization lovin'. Some good candidates here for general cleanup are Integer, Float and String PMCs, which are used frequently to autobox INTVAL, FLOATVAL, and STRING* core primitive types. Also, some of the newer types such as Socket and Sockaddr could use some tweaking to become more mature and stable.

Certain types that deal with the underlying system, such as OS, Env, and File, always need tweaking, extending, and testing to provide all the functionality that users are going to expect in order to examine and manipulate the underlying machine in a consistent way.

Verify the Spec

The various design documents in docs/pdds/* refer to some of the Core PMC types and discuss some of the important components of each. Of specific interest are PDDs 15, 17, 20, 21, 22, 23, 24, and 28. Also, there are several design documents still in draft in docs/pdds/draft/*. Take a look through some of these documents to see how the drafts compare to the current implementations. Feel free to make one conform more to the other, and submit patches for both the PMC types and the spec documents to update them. Of particular interest here are PDDs 8 and 14.

Rename API Functions

This is a task that actually applies to multiple subsystems, not just the PMC system. There is a page on the Parrot Wiki that we're editing right now to provide more details about other projects in this area.

Basically, functions in src/pmc.c need to all be renamed to Parrot_pmc_*. We also need to evaluate which functions represent the public-facing PMC API (which should all have the PARROT_EXPORT directive), and which items should not be part of that API. So the function pmc_new, should be renamed to Parrot_pmc_new.

Renaming just one function at a time (which would be ideal in terms of small, easy-to-review patches) should be a trivial matter for a coder who's any good with Perl5 (or even sed, if you're into that kind of stuff).

Also, the file src/pmc.c should probably be moved to src/pmc/api.c, and broken into subfiles depending on functionality. Check out the page on the wiki for details about a move like this.

Conclusion

PMCs are Parrot's basic aggregate structure, and the various core PMC types encapsulate a large amount of Parrot's functionality. Unfortunately, many of the central PMCs and PMC mechanisms are old and in need of some tender loving care from a decent coder. It's a system that's easy to get involved in, and there are some real benefits to the project that won't cost more then a small amount of time with the right tools and right knowhow.

Thursday, June 25, 2009

Parrot4Newbies: Test Suite

The second post in my Parrot4Newbies series, today I am going to talk about Parrot's test suite. This is another great way for the average new user to get a deeper understanding about Parrot's capabilities because the test suite is, in theory, a comprehensive exercise of Parrot.

Parrot's test suite has historically been written in Perl 5, with a series of modules derived from Test::More and Test::Builder and others with some custom methods to handle creating, compiling, and executing PIR and PASM code. Now don't get me wrong, we do like Perl 5. However, we want to get rid of as much Perl 5 from the Parrot repository as we possibly can. For one thing we want to reduce the number of dependencies. For another, we have to look forward to a future where Perl 5 is actually running on Parrot, which would create a very fun bootstrapping problem. Maybe that's just wishful thinking on my part, but it's a fun goal to have in mind (and a fun project for an adventurous team of new developers to attempt!)

Run Tests, Report Problems

The fastest way to get started with tests is to get the current version of Parrot from SVN, and run this little script:

perl Configure.pl [args]
make
make test

The "test" target runs the core functionality tests, the documentation tests, and the coding standards tests, plus a few others. This can take quite a long time to execute, so running the "make coretest" is probably more attractive for most coders. The "coretest" target only runs tests of the core functionality.

If you're looking to really optimize and run tests quickly, you will want this incantation:

make -j9 [testname] TEST_JOBS=5

Where [testname] can be "test", "coretest", "fulltest", "distro_tests", or any of the other test targets. This particular command executes testing in 5 threads in parallel, which can go very very quickly on some systems.

When you run tests and see failures, you can either submit a bug report to trac, or you can be ambitious by fixing it and submitting a patch. Patches are always very nice to have, but even reports of failures (including information about your system and build options) are very good too.

Upload Smolder Reports

The smolder service maintains an online log of test progress, so we can see what tests are doing on each platform. If you're running tests regularly, please consider "make smolder_tests". This will run through the test suite and upload the results to the smolder server so our developers can keep track of them.

Even better would be to set up a smolder slave bot. Set up a script on your system to run this sequence at intervals:

cd $HOME &&
svn co https://svn.parrot.org/parrot/trunk parrot-smoke &&
cd parrot-smoke &&
perl Configure.pl &&
make &&
make smoke


This is especially important if you're on a rare system (something that isn't x86+Windows, x86+Linux, or x86+Darwin). We can never have enough reports from rare systems.

Convert Tests to PIR

Many of our tests are written in old-style PASM, and many of them are still managed by Perl 5 scripts. We need to rewrite all these test files to use pure PIR instead. Here's an example of a Perl 5 test:

use strict;
use warnings;
use Test::More
use Parrot::Test tests > 1;
pasm_output_is( <<'CODE', <<OUTPUT, "gt_ic_i_ic" );
set I0, 10
gt 11, I0, ok1
print "nok gt\n"
ok1:
print "ok 1\n"
gt 9, I0, nok1
print "ok 2\n"
branch ok2
nok1:
print "nok gt 2\n"
ok2:
end
CODE
ok 1
ok 2
OUTPUT

And here is that same test rewritten in PIR:

.sub main :main
plan(2)
gt_ic_i_ic_1()
gt_ic_i_ic_2()
.end

.sub gt_ic_i_ic_1
I0 = 10
if 11 > $I0 goto ok_1
ok(0, "gt_ic_i_ic1")
goto end_1
ok_1:
ok(1, "gt_ic_i_ic1")
.return()
.end

.sub gt_ic_i_ic_2
$I0 = 10
if 9 > $I0 goto ok_2
ok(1, "gt_ic_i_ic1")
goto end_2
ok_2:
ok(0, "gt_ic_i_ic2")
.return()
.end

So the transformation isn't entirely straight forward but the end result is pure PIR, not a hard-to-read mixture of PASM and Perl 5. Notice that I am not line-for-line translating the PASM into PIR, I rearrange it a lot to make it more readable. The end result, the features being tested, are absolutely the same.

PMC Testing

As the policy stands right now, every file in src/pmc/ should have an associated file in t/pmc/. There is actually a test to verify that we have all these necessary tests! Just having these test files isn't enough, we need to make sure the tests are actually giving the PMCs a good workout. Look through the various tests and make sure each PMC is well tested. Some PMCs such as Integer implement many VTABLEs, and we want at least one test to exercise each of them. Writing tests like this helps not only to figure out what all the core PMC types do, but you're also forced to trace through some code to figure out where the various VTABLEs are called from so you can figure out how to test them.

Conclusion

The test suite is a key part of the Parrot development process. It helps us to find small regressions and bug earlier so they don't grow and fester into larger bugs later. The more comprehensive our test suite is, the more comfortable we can be making Parrot releases because we know that HLLs and other users of Parrot that use the features we test for will work as expected. It's also a great way for new developers to get involved and start getting an idea about the capabilities, current state, and limitations of Parrot. Once you see for yourself the areas where Parrot needs some work, you'll be more able to start making the necessary fixes yourself.

Wednesday, June 24, 2009

Parrot4Newbies: Documentation

In response to some requests I received and some signs of interest that I saw at YAPC, I decided to start a little series of posts that I am going to call Parrot4Newbies. The goal of these posts are to take a look at some particular subsystems and projects in Parrot-land, describe what kinds of jobs and work need to be done, and break down these tasks into small steps that new users can follow in order to become acclimatized and familiarized to the Parrot development process. I will be publishing these posts pretty frequently, in addition to my "normal" posts which I try to put out at least 5x per week, so the volume here may be getting pretty heavy. I will be using the "Parrot4Newbies" tag on these posts, so you can filter them if you want.

The first area where Parrot needs help, which is actually a common need of most open source software projects, is documentation. Writing and improving documentation is a great way to get familiarized with the codebase for people new to Parrot internals. There are actually several components to our documentation, all of which need help.

There are two good ways to help: (1), open a bug report (requires a username) when you find a problem that you would like somebody else to fix. (2) Even better is to fix the problem yourself and create a bug report with an attached patch.

Project Documentation

We have a lot of documentation in the repository in the folders docs/. However, our documentation is far from comprehensive. Find files that look incomplete, out-of-date, or just plain confusing and misleading, and fix them up.

Our design documents in docs/pdds/ are the documentation that describes what Parrot is and how it is implemented. Read through these to get a good understanding of Parrot, and look for places that are incomplete, not true to reality (which may mean the code is wrong or the specs are wrong), or misleading.

Parrot Book

We have a book at docs/book/ that needs work. We have a first edition being published soon, but it needs a lot of work so we can put out a second edition after Parrot 2.0 is released. Read over the book and find things like core topics that aren't covered (or aren't covered well), typos, out-of-date errors, etc.

When you see code examples, try them and make sure they work too! Don't just trust our word for it make sure it does what it says it does!

Examples and Tutorials

We have a large amount of examples in examples/, and a PIR tutorial in examples/tutorial/ that need lots of help. Read through the examples, try them out locally to see if they work and how, and clean them up a little. Our tutorials especially are incomplete and don't cover all the topics that a new user needs to know. Feel free to write new tutorial pages entirely if a particular topic isn't well covered already.

File- and Function-Level Documentation


All our .c files contain POD-formatted documentation. This is broken into two distinct types: File-level which is the stuff at the top of the file that describes the particular system in a high-level overview; and Function-level which provides documentation for each individual function. Both of these things are required and are verified by our test suite. To run these tests, you type "make codetest" from the parrot repo, after configuring and building Parrot. This will run through a series of tests in addition to the documentation ones. Specifically, the test t/codingstd/c_function_docs.t covers the function-level tests, and there are several files failing this test:

compilers/imcc/instructions.c
compilers/imcc/optimizer.c
compilers/imcc/parser_util.c
compilers/imcc/pbc.c
compilers/imcc/pcc.c
compilers/imcc/reg_alloc.c
compilers/imcc/symreg.c
compilers/pirc/src/bcgen.c
compilers/pirc/src/pircapi.c
compilers/pirc/src/pircompiler.c
compilers/pirc/src/piremit.c
compilers/pirc/src/pirmacro.c
compilers/pirc/src/pirpcc.c
compilers/pirc/src/pirregalloc.c
compilers/pirc/src/pirsymbol.c
config/gen/platform/ansi/dl.c
config/gen/platform/ansi/exec.c
config/gen/platform/ansi/time.c
config/gen/platform/darwin/dl.c
config/gen/platform/darwin/memalign.c
config/gen/platform/generic/dl.c
config/gen/platform/generic/env.c
config/gen/platform/generic/exec.c
config/gen/platform/generic/math.c
config/gen/platform/generic/memalign.c
config/gen/platform/generic/memexec.c
config/gen/platform/generic/stat.c
config/gen/platform/generic/time.c
config/gen/platform/netbsd/math.c
config/gen/platform/openbsd/math.c
config/gen/platform/openbsd/memexec.c
config/gen/platform/solaris/math.c
config/gen/platform/solaris/time.c
examples/c/nanoparrot.c
examples/compilers/japhc.c
examples/embed/lorito.c
src/atomic/gcc_x86.c
src/debug.c
src/gc/gc_malloc.c
src/gc/generational_ms.c
src/gc/res_lea.c
src/io/io_string.c
src/jit/amd64/jit_defs.c
src/jit/arm/exec_dep.c
src/jit/i386/exec_dep.c
src/jit/ppc/exec_dep.c
src/nci_test.c
src/pbc_dump.c
src/pbc_info.c
src/pic.c
src/pic_jit.c
src/string/charset/ascii.c
src/string/charset/binary.c
src/string/charset/iso-8859-1.c
src/string/charset/unicode.c
src/tsq.c
src/jit/alpha/jit_emit.h
src/jit/arm/jit_emit.h
src/jit/hppa/jit_emit.h
include/parrot/atomic/gcc_pcc.h
src/jit/ia64/jit_emit.h
src/jit/mips/jit_emit.h
src/jit/ppc/jit_emit.h
src/jit/skeleton/jit_emit.h
src/jit/sun4/jit_emit.h


Some of these files are complicated, which is why nobody has been brave enough to document them. However, while documenting things you should feel free to clean the code up a little bit so it becomes easier to document and understand. Also, most of these are not core files, they tend to be files on the edge of the codebase in some of our complicated systems: JIT, the IMCC and PIRC compilers, etc, so you're going to need to read up on some core systems in order to what is going on in all of these. More reading and looking at code means you learn more, more quickly!

Most of the rest of the code files in the repository have some documentation, but it might not be high quality. Feel free to look into other files that interest you as well and improve existing documentation to be easier to read and more accurate. This is a great way to get started as well!

Conclusion

So that's a quick list of things that a new user should feel free to take a look at as a way of getting familarized with Parrot and it's documentation. Documentation is a great way to learn the code because you have to understand it and describe it in your own words in order to write the docs. It's a great way to get involved and will have an immediate impact on the quality of Parrot and our ability to attract even more new developers. Fixing some documentation

Please do not hesitate to send in patches, however small. Also, if you have questions and need clarifications, please feel free to ask on #parrot or on the parrot mailing list. We would love to help you help us.