Issue 1-53, December 11, 1996

Newsletter First Anniversary

By Valérie Peyre

The Be Newsletter celebrates its first anniversary this week. This gives me the opportunity to thank all those at Be and in the developer community who have contributed to the Newsletter, and to reflect on how things have changed in the last year...

1996 was an exciting year at Be - The company has grown really fast and has gained in popularity. We've done our best, through the Newsletter, to keep pace and to communicate the growing interest—by adding new columns, finding interesting developers to profile, and letting you know where we are and what we're doing.

But throughout this excitement, we've tried to keep the Newsletter focused on its primary goal: To keep our *developers* informed about Be, the BeOS, and what some people call the "Be Philosophy."

Developers are important to us—yes, I know, you've heard that before. But this is the reality: Our developers are our future. This doesn't mean that we're passively waiting for you to do all the work of developing great applications. Rather, we want to earn your trust—in our product and our support—so that you'll continue to develop on the BeOS. In addition to providing technical and marketing support for your efforts, we'll also listen to (and incorporate) your suggestions for improvements to the OS.

It's our hope that the Newsletter has been part of the exchange of ideas that has helped Be grow. Since the first issue a year ago, we've encouraged you to speak about your work and your experiences with the BeBox. Some of you have been profiled in the Developer Profile column in the last year—we hope to hear from even more of you soon. If you haven't contributed an article yet, consider this:

On December 6, 1995, the first Be Newsletter—in hardcopy—was printed and mailed to about 300 people. One year later, we send out our weekly online Newsletter to 8000 Be subscribers (Forty percent of them are registered Be Developers). Plus, we count something between 3000 and 5000 Newsletter hits on our website every week...and the numbers are growing. So, please, send us information to publish your profile.

To conclude, I will let you know that the Be Newsletter is a %100 percent internal product, and has been a real team effort. Okay—it's not always easy to get an engineering team to write every week...believe me, some of them have shown great imagination in trying to avoid their assignments—chronic amnesia, religious holidays, flowers, lunch—but they've all done a great job. Thanks guys!

Thanks also to all the regular columnists (Jean-Louis, Alex, William, Doug).Two people have been especially helpful: Doug fulton, who has done incredible work summarizing BeDevTalk every week and editing sections of the Newsletter in his own unique style, and Roy West who has also done a lot of very good work with his weekly editing.

I hope the Be Newsletter will continue to serve and inform all of you. If you have any comments, please feel free to send them to newsletter@be.com.


Be Engineering Insights: The Compute-Bound Be Application

By Rico Tudor

One of the hardest aspects of BeOS programming is making use of multiple processors within one application. To coax N CPUs to work for you, the BeApp must create at least N flows- of-control (threads), and keep them busy. Once created, a thread that wants to run will be allocated an available CPU by the BeOS kernel. The trick is factoring a problem into such threads. For full-screen games, this has been discussed recently by Pierre's fine article "A Typical Multithreaded Game Architecture".

This article discusses compute-bound programs in general, even if they have no graphics component. While BeOS provides a Posix environment, threads are not available: multiple threads are, formally speaking, a feature of the BeOS kernel and the Kits. Therefore, a BeApp is required to maximize CPU usage.

A toy version of the Mandelbrot app is included for illustration.

The Problem

Assuming that your problem is well-defined, the first step is determining an algorithm. In a uni-processor system, sequential algorithms will suffice. In the multi-processor BeBox, this is usually sub-optimal; the desirable algorithm will be parallel. Unfortunately, such an algorithm may be difficult to write, difficult to find, or may not even exist.

A simple example is the binary search, which involves successive comparisons from a sorted array. The next element to compare depends on the result of the previous comparison, ruling out a parallel approach.

Another example is the alpha-beta tree search algorithm, used by complete-information games like chess. If a brute-force search visits N leaves in the tree, the alpha-beta search can visit as few as sqrt(N). This staggering improvement is achieved because certain branches are ignored, based on earlier search results. To compete, the brute-force algorithm would need sqrt(N) more CPUs, currently unavailable in the BeBox product line.

Note that while the search examples above are resistant to parallel processing, you can perform two separate searches in parallel. This is the key to multi-threaded programming: factoring the problem into UNRELATED parts. Unrelated means there is no interaction, except at the beginning or end.

Fortunately, many problems are inherently parallel. Scientific and statistical modeling often involves large numbers of independent calculations on particles, waves, pixels, bank accounts, etc. This is the easiest problem to factor, since you write one piece of code and then invoke it, in parallel, on each piece of data.

A second, more difficult, approach is possible. If the calculations are not independent, you can form a "pipeline" of computation, where data flows from one stage to the next. Each stage grinds on the data in a particular way. Mother Nature has chosen this approach for the alimentary canal. The challenge is to design each stage such that the workload is reasonably balanced, meaning that all CPUs are in use at all times. Since each stage is itself sequential, no stage should be disproportionately compute-intensive; data should be delivered in manageably small increments. A good design will avoid constipation, and requires the programmer's gut feeling as much as science. The handy Pulse app provides a diagnosis.

Given space restrictions, this article will avoid the second approach. The Mandelbrot app is an example of the first approach: each point in the Mandelbrot set can be calculated independently of the others. Note that the calculations for a given point must be sequential.

The Approach

It is desirable that a long computation be divided into a sequence of short ones. This allows the computation to be aborted, allows progress reports, and changing parameters on- the-fly. Some problems, like Mandelbrot, divide naturally.

In most programming circles, polling is a dirty word. It conveys the image of a CPU spinning single-mindedly in a loop, flying in the face of the modern GUI and the modern multi-tasking OS. Nonetheless, the essence of digital computation is the poll: if the hardware isn't polling, it's the kernel; if not the kernel, then the Kits. When you write compute-bound code, you are polling, too.

Polling may have an explicit form, such as checking the amount of time expended, or it may be implicit, such as counting the number of results accumulated.

In one style of programming, the poll appears in the code as a function call, e.g. to get the time, or deliver some results. The return value may specify new parameters, or an indication to abort. In event-driven programming, the poll appears as a return from the event handling function. New parameters are supplied by the next invocation of the handler; If the calculation is aborted, the handler is simply not called.

To demonstrate the power of the Application Kit, Mandelbrot uses the event-driven style. The polling is implicit: one scanline is calculated and displayed.

The Code

Mandelbrot does a lot in 110 lines of code, thanks to the powerful Application Kit. Threads are harnessed by BLoopers, while BMessages provide synchronization and communication between BLoopers. No other facilities are required.

#include        <Application.h>
#include        <Bitmap.h>
#include        <unistd.h>
#include        <string.h>
#include        <stdlib.h>
#include        <stdio.h>

#define YMAX    600
#define XMAX    800
#define NLOOPER 2
#define N       500
#define XBASE   -.166025425237824
#define YBASE   -.651236716536372
#define XLEN    .003661029815804
#define YLEN    .003044479089232

static uchar ctab[] = {
         0, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,
        23,24,25,26,27,28,29,30,63,30,29,28,27,26,25,24,
        23,22,21,20,19,18,17,16,15,14,13,12,11,10, 9, 8,
};
struct L: BLooper {
        L( BView *view, uint i) {
                v = view;
                id = i;
                Run( );
        }
        void MessageReceived( BMessage *m) {
                switch (m->what) {
                case 'calc':
                        DetachCurrentMessage( );
                        calc( m->FindLong( "y"));
                        v->Window( )->PostMessage( m, v);
                }
        };
        void calc( uint ycur) {
                for (uint xcur=0; xcur<XMAX; ++xcur) {
                        constdouble a = XBASE + xcur*XLEN/XMAX;
                        constdouble b = YBASE + ycur*YLEN/YMAX;
                        double x = 0;
                        double y = 0;
                        uint i = 0;
                        while ((x*x+y*y < 4)
                        && (++i < N)) {
                                double newx = x*x - y*y + a;
                                y = 2*x*y + b;
                                x = newx;
                        }
                        results[xcur] = ctab[(N-i)%sizeof(ctab)];
                }
        }
        BView   *v;
        uint    id;
        uchar   results[XMAX];
};
struct V: BView, BBitmap {
        V( BRect r): BView( r, 0, B_FOLLOW_ALL, B_WILL_DRAW),
                BBitmap( r, B_COLOR_8_BIT) { }
        void AttachedToWindow( ) {
                ycur = 0;
                for (uint i=0; i<NLOOPER; ++i)
                        startcalc( new L( this, i));
        }
        void MessageReceived( BMessage *m) {
                if (m->what == 'calc') {
                        L *l = (L *) m->FindLong( "l");
                        display( m->FindLong( "y"), l);
                        startcalc( l);
                }
        };
        void startcalc( L *l) {
                if (ycur < YMAX) {
                        BMessage *m = new BMessage( 'calc');
                        m->AddLong( "l", (long)l);
                        m->AddLong( "y", ycur++);
                        l->PostMessage( m);
                }
        }
        void Draw( BRect) {
                DrawBitmap( this, BPoint( 0, 0));
        }
        void display( uint y, L *l) {
                for (uint i=0; i<10; ++i)
                        l->results[i] = l->id * 63;
                SetBits( l->results, XMAX, y*XMAX,B_COLOR_8_BIT);
                BRect r( 0, y, XMAX-1, y);
                DrawBitmap( this, r, r);
        }
        uint    ycur;
};
struct W: BWindow {
        W( BRect r): BWindow( r, "m", B_TITLED_WINDOW, B_NOT_CLOSABLE) {
                MoveBy( 5, 0);
                Show( );
                AddChild( new V( r));
        }
};
struct A: BApplication {
        A( ): BApplication( 'abcd') {
                Run( );
        }
        void ReadyToRun( ) {
                new W( BRect( 0, 0, XMAX-1, YMAX-1));
        }
};
main( )
{
        A a;
        return (0);
}

Explanation Of The Code

The Mandelbrot team consists of four threads, all of them derived BLoopers: BApplication A, BWindow W, and two L BLoopers. Note that BView V, while being its own BObject, is operated by W.

The L code does all the grinding. By changing the NLOOPER constant to 1, you can observe how only one CPU is working. If NLOOPER is larger than the number of CPUs, no further gains are achieved.

While the L loopers are grinding, the A looper responds immediately if the user pulls down the app menu. Similarly, the W looper can redraw the window immediately while the user drags it around.

The V view is the coordinator of the enterprise. It directs the computations, scanline at a time, to each L looper. To indicate how V is dividing the work, the particular L looper's signature is drawn on the left edge of the scanline. V accesses the calculation results directly from each L. This data sharing between loopers must be conducted with care. If the data quantity is small or infrequently shared, it should be passed using a BMessage. Sharing becomes more dangerous as program complexity grows.

On a dual 66 MHz BeBox, the app runs at 8 scanlines per second. If the polling rate is too high, efficiency will deteriorate. If the rate is too low, the responsiveness of L will suffer. Changing N, XBASE, YBASE, XLEN, or YLEN can drastically alter the polling rate. The program does not address this important issue: a general Mandelbrot app needs a flexible polling method. A workable implicit method is to count the iterations of the inner loop, instead of calculating the whole scanline. The explicit method could use the astonishingly efficient system_time() function. Cost: 1 microsecond per call!

Flexible polling requires more programming work. It must be possible to start and stop work in the middle of the scanline. The housekeeping would occur in the V view.

Hacking The Code

For thrill-seekers, certain constants control the image appearance. The Mandelbrot set is defined for real x and y, where -2 < x < 2 and -2 < y < 2. Much of this area is featureless, so you want to zoom in by changing XBASE, YBASE, XLEN and YLEN, such that XBASE < x < XBASE+XLEN and YBASE < y < YBASE+YLEN. The distinguishing behavior of the Mandelbrot set is the infinite detail as you zoom. With sufficient magnification, you can observe the demise of floating-point precision. A fancy version of this program should allow zooming with the mouse.

The constant N determines the amount of detail: detail requires more compute time. More detail does not always produce an aesthetic image, since the clutter is distracting.

XMAX and YMAX determine the image size, in pixels. The fancy program should allow the user to set the values, by way of the resize icon.

A different way to control the image appearance is through the colormap, ctab[]. The grayscale can be replaced with your favorite colorscale, or something random. Colormaps can radically alter the appearance of the same bits, with no further calculations.

Conclusion

BeOS provides numerous low-level synchronization facilities for threads. Most notable are semaphores and message ports, both in the Kernel Kit. While these are fast, compute-bound threads still require the programmer to address the polling issue.

The Application Kit has the advantage of offering a comfortable environment, with services like sound and graphics from the other Kits. Unless the polling rate is high, a few hundred Hz, the overhead of the slower Application Kit is not a concern.


Be Engineering Insights: Hardware Repair Forum

By Mike Palmer

Enough BeBoxes have gone out that we occasionally see one come back in for service. Some of these returned units may actually be end-user servicable, such as pressing the ASICs down in their sockets to reseat them after they popped up due to thermal cycling. Other problems may not be so easy to fix. For example, flash technology is ideal for changing ROM data in circuit, but the devices themselves are frail. When a system is powered up, but doesn't boot, (either the load indicator LEDS never turn off or the BE logo never appears or the boot doesn't proceed past the BE logo), the cause is a failed flashrom device. Reprogramming it will not work; it needs to be replaced. Usually if a system doesn't boot up all the way, it's the flashrom.

If after booting there is random video data on the screen, the flashrom is of a different firmware release from the startup disk. Both need to be at the same release level, currently DR8.1 at least, although the disk may contain DR8.2 now. Upgrading the flashrom/disk solves this problem.

If the PS/2 mouse hangs, check whether a user installed card is using IRQ12. The mouse needs IRQ12. The solution here is to re-configure the card to use a different IRQ; if the card is hardwired to IRQ12, get a configurable card. Also, in the case of a non-working mouse, check for a blown 2A fuse at F2 on the motherboard.

This about does it for problems that an end-user can diagnose and fix. However, if your BeBox fails for any reason, and YOU can't fix it, call us! Seeing all the different failure modes only helps our engineering effort to make more robust BeBoxes in the future. We will make sure when we get your BeBox here to repair it using the same tests and components as in the manufacturing process. Many times a failure can be traced to a defective component.

So, once again, if your BeBox goes down, let us know and we'll get it right back up.

Happy Computing!


Be Developer Talk: Jos Van Roosmalen

By Jos van Roosmalen

I like multiprocessor hardware. My first experience with a MP computer was the Atari Transputer Workstation (26 Inmos RISC T800 @ 20 MHz), which I got when Atari closed its European Distribution Center in The Netherlands. The ATW is running Helios OS, a UNIX/X-like OS-enviroment designed for multiple processors that was developed by Perihelion Software. I like the ATW—and love the power of multiple processors -- but because there are only 30 Transputer Workstations in the world, I figured it was time to move to a new platform. So I bought a BeBox.

At the 'BeBox/BeOS' demo in Amsterdam last month, a lot of people asked me what word processor I was using on the BeBox. I was asked this so many times, that I decided to port my own. The application is being beta tested now, and should be available as shareware by the beginning of the new year. The fully-featured commercial version of the word processor should be ready sometime in 1997. I hope you'll be pleased with the app, and, just as important, delighted by the price: my commercial software will be priced to move!

In addition to work on the word processor, I'm also finishing some applications that I hope will be ready by the time PowerComputing starts shipping the BeOS on its machines. I'll announce some of these application this week: For example,you'll see a spread sheet and a project codenamed "BeMedia." A lot of this software was already running on the Atari, and it's been quite easy to port to the BeOS.

To help promote, sell, and support these applications, I started a new company that uses the Internet as its primary marketing channel. As Be itself has shown, the Internet is a powerful—and low-cost—medium for getting the word out. My company's Web site will be opened when the first commercial products are available; until then, keep your eye on my own home page:

http://www.stack.nl/~josr.

Coding software for the BeOS is easy! Because of its object orientation and software kits, you don't need to know all the wearying details of the OS. Of course, other environments—Windows NT, in particular—let you code in C++, but the communication between the OS and your application is from the last decade. The BeOS shows us how to design software for the future.

For questions, etcetera: E-mail: josr@stack.nl


News From The Front

By William Adams

Playing with a 19-month-old is a lot of fun. Almost anything you do will bring screams of delight. Just the other night Yasmin and I were doing this on our bed:

"Watch this, fall down, boink! Hee, heee, heeee!"

On and on it went for at least 10 minutes. Falling down is fun. But some day she's going to grow out of it; she'll discover that running without falling covers more ground.

We often say that the BeOS is still in its infancy. Our patient developers, who are no doubt having fun, will eventually get tired of falling. One particularly bumpy path is device driver development.

You've also no doubt heard (again and again) our battle cry of "Raid the PC Organ Bank!" We support standard PCI-based video, we have on-board SCSI 2, and we have ISA slots. Given this environment the BeBox is a ready recipient for many of the inexpensive PC organs found at computer mega stores. But, in order to prevent rejection, someone must smooth the path by convincing the BeOS that the new device isn't an invading antigen that must be surrounded and destroyed.

This is the job of the device driver writer.

If you've ever written a device driver for a video card, you'll understand what a hassle it can be. As was spelled out a few newsletters ago by Pierre, it's a difficult process even when you have all the information that you need. Currently, one of the most annoying bumps when you're developing a video driver is that you must put your driver on a floppy and reboot your machine every time you make a change. If your driver doesn't work, you *might* be able to debug it over the serial port —but you're flying blind because son, you just done smashed your video.

Is there a better way? Why, yes.

A few newsletters back we threatened to provide you with some tools to help in this process. They're ready; come and get them:

ftp://ftp.be.com/pub/Samples/vidtest.tgz

What you'll find is a test harness that will exercise your budding video driver while you are still looking at a clean UI. It does this by letting you plug two video cards into your BeBox. Mind you, there are all sorts of caveats to doing this correctly; for example:

There are instructions for usage in the package. This test harness is used to test the IMS graphics board on the Mac, so it does have some value.

Another area of particular pain is the production of drivers for SCSI devices. Robert Polic, creator of SCSIProbe and other critical parts of the BeOS, has put up the source for the SCSIProbe driver for those intrepid souls who dare to tread in this territory:

ftp://ftp.be.com/pub/Samples/scsi.tgz

The sample source should go a long way toward helping you create a SCSI device driver of your own. The code is very clean and documented. Together with the device driver documentation, you should be on your way.

On To The Show

Boom, Boom, BOOM! Hear that? 20 some odd days left until the Big Event. We will have a modest sized booth at MacWorld this year. There will be 4 workstations available for showing your wares. What we want to do is show as many of your apps as possible, so get them ready. Send us your best and we'll do the rest. If you are actually attending the show and want to do some booth duty to show your own app, drop us a line and we'll make you a star.

Be will also be demonstrating in the PowerComputing booth. Again, applications that show off the BeOS is what we'd like to show. Our own demo apps are great—that's what has excited so many people—but the show will be even better if we can show the applications of third-party developers who actually want to ship a product. And I'm sure that there will be many visitors anxious to see what's possible on a Macintosh running an OS for the 90's.

Conclusions

The year is rapidly coming to a close. The Be demo tour is over for now. The world, or at least Silicon Valley, seems to know Be Inc. exists. We made it through infancy, and are beginning our toddler phase. With more support from your friendly DTS staff, and more applications from hard working developers, it seems like this child will grow to adolescence. This will be a good thing, and we should all look forward to what is sure to be a fun, exciting, and profitable time ahead.


One Year

By Jean-Louis Gassée

It was almost as lunatical as starting the company itself.

Or so said some respected members of our engineering community.

Who were we to publish a Be Newsletter (weekly, yet!) when we barely had a product? Do we want to look like we had people lying around with nothing better to do than pound the company chest through the keys on their word processors?

And when, a year older, we look back—we have to admit they were right.

But the warm and overwhelming reception accorded our baby had taken us by surprise. We were scrambling to put all our technical documentation on an untested Web server (who's other major customer provided gifs of "Debi" and "Nikki" for the trench-coated Net voyeur).

We sweet-talked our suppliers, serenaded our contractors, and waltzed our creditors in a mad dance to ship the first BeBoxen to developers. "We came here to write code, not short stories", as one articulate (and literate) individual put it.

True. But to achieve critical mass, we needed to communicate our ideas -- what our product and our business was (and is) about—early and often.

And who can better express the why and the how of what we do than the very individuals who create it? I realize the limits of such a statement: Real writers write better than engineers, or even evangelists and marketeers (not to mention immigrant CEOs). But there are benefits in persuading the horse to speak: It helps to calibrate the generative process. It also produces a healthy deflation (when needed)—you may think you're Gigli in the shower, but step up on stage...And, most importantly, for a technically literate audience such as ours stylistic brilliance and polish is less important than getting unfiltered, unspun information directly from the individuals in charge.

These first 52 issues of the Newsletter wouldn't have been possible without the wits and patience demonstrated by Valérie Peyre. She has an innate ability to extract articles from even the most obdurate procrastinators while juggling her other assignments on the team. Newsletter day (Tuesday) rarely finishes early, with Doug Fulton and Roy West, writers by day, performing cosmetic surgery on our prose well into the night. As the team expanded during 1996, especially after we finally got recapitalized, we gained regular contributors such as Alex Osadzinski and, more recently, William Adams.

I hope you can sense that we enjoy presenting the Newsletter to you every week. Putting together an alternative personal computing platform is an adventure and we appreciate this vehicle. It allows us to share ideas at a speed, cost, and in a style no other medium would allow. Thanks for having read us this past year. With luck, the events ahead will make the past 52 issues look tame by comparison.


BeDevTalk Summary

BeDevTalk is an unmonitored discussion group in which technical information is shared by Be developers and interested parties. In this column, we summarize some of the active threads, listed by their subject lines as they appear, verbatim, in the mail.

To subscribe to BeDevTalk, visit the mailing list page on our web site: http://www.be.com/aboutbe/mailinglists.html.

WEEK 3 (or 4?)

Subject: Scripting interface

AKA: Scripting Architecture
AKA: Scripting API - For Public Comment

After disappearing for a week, the scripting thread sprang back to life. Should Be define (or adopt) a scripting *language*, or merely a scripting *interface* (i.e. message prototypes). A new player, IFF, was introduced on the pro- language side. And ARexx seems to be making a comeback.

Just as folks started to tire of the subject, Jon Watte of MetroWerks published his own scripting interface. Poke around in http://www.metrowerks.com/news/ for more info.

WEEK 3

Subject: Better thread control

More discussion of how to coax your application into waiting for more than one event. It was pointed out that a select()- style wait would not only save threads, but would also make porting existing code a lot easier. This was countered with the arguments that 1) threads aren't all that expensive, and so don't need to be "saved", and 2) "porting" should mean fitting existing algorithms into a new platform's native flow control—in other words, get with the program or you'll end up with expensive emulation layers. The counter-counter: The upper limit on the number of threads is unarguably much much lower than that of the number of different conditions a select() can monitor. And as to "porting cleanly," it was pointed out that Be has plenty of sops to tradition (e.g. POSIX); is a generalized select() too much more to ask for?

THE BE LINE: No it isn't—but don't expect it in DR9. We hope to have fd-based select() implemented

WEEK 2

Subject: Preferences and version numbers

More on whether version strings should be (foremost) human- readable. It was contended, with a code example, that version strings should be written to the resource section of a file (in DR9-speak, this will be an attribute), rather than embedding a string in an otherwise binary file. It was pointed out that the resource approach does seem to satisfy the condition of human-readability (or, at least, it doesn't exclude the possibility).

NEW

Subject: Accessing Preferences

AKA: [HEY BE!] filetypes

A vote for a Win95-style (preferences) Registry prompted much discussion on how the system should store preference data, and how an application can access it. Someone suggested a "Preferences Server" that would monitor the preference settings and send messages to interested apps. Also, where should preference values be stored? (consensus: the database); and what format should they be kept in? (consensus: probably a home-grown type/creator/version/etc structure).

Subject: BWindowScreen

Should the graphics support include a text mode? The initial reaction was less-than-encouraging, but a number of folks say "Why not? If it's in the gfx card, bring it out to the screen." This led to a discussion of Terminal's glories and faults. Most folks want line-wrapping.

THE BE LINE: We probably won't do a "text mode driver" ourselves; however, we will work on improving Terminal's performance.

Subject: Home and End keys, MW, or a key remapper

An initial request for mappable key bindings in the MW IDE editor led to a broader discussion of system-wide keyboard mappings.

Subject: Some minor enhancements

Of the three feature requests proposed in the thread's initial message, one piqued discussion: Should the system poll removable media (as it does with the CD) or ask for an explicit mount(a la floppy)? Should the methodology be consistent (i.e. either the CD changed to explicit mount, or floppy changed to poll). For polling devices, should the frequency be decreased—is the current poll too expensive?

Creative Commons License
Legal Notice
This work is licensed under a Creative Commons Attribution-Non commercial-No Derivative Works 3.0 License.