Issue 3-4, January 28, 1998

Be Engineering Insights: On Horses' Bones, or the Need for Glue

By Mani Varadarajan

Some days, I wish I were a user interface or graphics guy. Not that life as a kernel engineer at Be is uninteresting; far from it. But the kernel, sitting behind the scenes, isn't as sexy as something users interact with on a daily basis, or something that onlookers drool over during demonstrations. It's the fancy, colorful demos of Pierre and Benoit, the whizziness of the Tracker and interface widgets that get the "ooh, ahh", "come on baby" attention.

But the feelings of jealousy don't last long. My brief forays into non-command line applications have been satisfying to a point, but the incessant attention to aesthetics leaves me exhausted. In the end, I'm more than happy to get back to working on the nuts and bolts of the system.

Well, more than just nuts and bolts. There's also some "glue" that's fundamental to the BeOS system. Many of you may have noticed the existence of a "glue" library living in /boot/develop/lib on your system. This glue library (either libglue.a, glue.a, libglue-noinit.a, depending on which version of the BeOS you have) is independently linked into every application or library on the system.

So, what's in this glue code? Essentially, it contains routines used during the startup and tear down of each loadable segment of an address space.

Let's visualize a typical address space:

HIGH +---------------------------------+
     |           libn.so               | Other libraries
     +---------------------------------+
     |              .                  |
     |              .                  |
     |              .                  |
     |                                 |
     +---------------------------------+
     |           libbe.so              | Be kits
     +---------------------------------+
     |                                 |
     |          libroot.so             | C library, core
     |                                 | functionality
     +---------------------------------+
     |                                 |
     |          application            |
     |                                 |
 LOW +---------------------------------+

Each element or box of this address space is known as a "container," since it is self-contained. The containers of this address space are loaded and initialized in some order at startup. Since each container has its own data, etc., each container needs its own "glue" that contains an initialization routine (and termination routine, during address space tear down or unloading).

For applications and libraries written purely in C, there really isn't much initialization necessary; the glue code for applications just contains the official starting routine of the application (__start), sets up some basic data structures, and then jumps to main().

For C++ applications and class libraries, however, the situation is more complex. There may be static C++ objects which need construction at startup and destruction at tear down, before the application starts. In addition, each container needs to register itself as a possible place where C++ exceptions can occur. Both of these must obviously be per-container, and therefore live in the glue library.

At startup, then, the sequence carried out by the glue code for each container is as follows:

STARTUP/LOADING

  if application container
     set up basic data structures and hooks
  register exception tables
  construct C++ objects, if any
  jump to main()

TEAR DOWN/UNLOADING

  destroy C++ objects, if any
  unregister exception tables

This may not deliver the visual excitement of a three-dimensional book with real pages that contain movies and images, but what the heck -- Pierre's better at that stuff anyway.


Developers' Workshop: Time Lapse

By Doug Wright

You just noticed it's 4 AM, even though there's a clock right there in the corner of the screen. Last time you looked it was something like 1 AM, but you're not really sure. It doesn't seem like four. You're not really tired. In fact, you're just starting to feel that second wind coming on. It's finally working now, but you're not finished. Just one more little tweak and a build shouldn't take more than five minutes, right? Yeah, right! ;-)

And now a word from our sponsor:

With the Intel release looming, and with our desire to provide ever increasing levels of support to our developers, we're looking for a few good women and men to come to work with us in Developer Technical Support.

Here's what you should bring:

Here's what you'll be doing:

If you're interested in joining up with the company that is leading the computer industry into the next century, e-mail an ASCII copy of your cover letter, resume, your e-mail and postal addresses, and both day and evening phone numbers, in the body of an e-mail to jobs@be.com. Put "Developer Technical Support Engineer" in the subject line of your message.

And now back to our regularly scheduled program.

This week my so-late-yer-an-early bird sermon is about timing. Just because you have no concept of time doesn't mean your app doesn't need to. That's why our engineers are hard at work on the next Media Kit. Things like video, audio, and MIDI need to be synchronizable with each other. The code this URL leads to should whet your appetite for some seriously geeky timing work:

ftp://ftp.be.com/pub/samples/media_kit/obsolete/timecodeticker.zip

The first thing you need in order to do synchronization is something that gives you regularly timed ticks. How often do you need these ticks? Well, if you'd like to do full motion video it'll be around 30 times a second. That's every 33,333 microseconds. Fortunately the BeOS has timing resolution down to the microsecond, so you don't have to round off those extra 333. That doesn't mean it's always accurate to the microsecond, but you can always tell how far off you are. ;-)

Most of the time, you can be sure to be "woken-up" within 2000 microseconds of the time you wanted. That's less than 7% of one frame. More often than not, it's more like 2 or 3%, and we're working hard on improving that accuracy!

The ticker class compensates for the inaccuracy that exists from sample to sample, a.k.a. jitter, so that it doesn't compound into drift over time. It's derived from William Adams' nice Thread class (available from BeWare in the bebits package ):

ftp://ftp.be.com/pub/contrib/libraries/bebits980105.zip

The ticker class outputs ticks. Each tick has information about the number it is in a series, the time it was generated, the period of its generation and sometimes, a timecode. There is also a timecode class. This is a stripped down version of one that Steve Sakoman has put together that includes every standard frame rate including the hard to come by Brazilian PAL rates (unless of course you're in Brazil ;-) He's not quite done with it, though, so I yanked out the part that does plain old 30 frames per second and put that in the sample, so you could have a taste. Yum.

Where do these ticks go when the ticker ticks? The ticker maintains a list of ports that is managed by a couple of obvious enough functions: Connect() and Disconnect(). When it comes time to tick, the ticker sends a TICK_MSG along with a tick object to all connected ports.

On the other end of the port is another object derived from William's thread, the Chaser. A chaser can be passed a function that it calls each time it receives a tick. In that function, you can play audio, MIDI video, whatever. To keep this sample uncluttered, I just display the current frame count in the app's window. No, it's NOT very exciting (unless it's four in the morning, and you wrote it), but it does demonstrate the concept. ;-)

As an exercise for the reader, try yanking out the TCIn class and the chaser class and sticking them in another app. Then send a message from the chaser app to the ticker app with the port_id of the chaser. We use port_ids so we can have chasers in different apps all listening to the same ticker. Next time I'll show you how multiple apps can be synchronized properly, and maybe I'll even make some noise. Woohoo!

See you early!


The Dawning of the Age of BeOS for Intel

By Dave Johnson

Recently a Micro Center super store opened in Silicon Valley. It's huge and sells literally everything. There are computers for maybe $10, keyboards, motherboards, mice, furniture, books, software, magazines, mousepads, green and white printer paper with perforated edges, you name it...huge.

I was in this huge store looking around for a certain game I had been commanded to buy for a certain 12-year-old and I got to thinking. (Uh-oh.) I've noticed that if you go to any computer or bookstore you see so many computer books and magazines. Aisles. Shelves. Windows. Unix. Linux.

But...there's no BeOS section yet. No BeOS software, no BeOS books (there aren't many yet). The BeOS has been seen as a sort of Mac add-on, but it's about to become a name in its own right, in that vast Intel world.

Am I getting through? Yes, it's about to hit the fan. BeOS for Intel will be available very soon, and the world of Be developers is going to change dramatically. We're taking steps to publicize the Intel version of the BeOS. It's innovative, exciting, fast, interesting and NEW—and all of these factors combined with the sheer size of the Intel marketplace will translate into commercial opportunities for the experienced BeOS developer community.

To give you some idea of the reach of Intel, I just read that the Mac currently has 3.1% of the computer market. That means that BeOS is about to enter the marketplace that holds that other 96.9%. There will be bookshelves, and software shelves, and magazines waiting to be filled with BeOS books, software, and information.

There's a train rolling and we want you to be on it. We're already hearing from software publishers who are looking for BeOS applications and programmers. We're hearing from book publishers looking for authors. Technical magazines will need informational articles.

You—the existing BeOS developer community—are the knowledge base that software companies, book publishers, and magazine editors are going to look to for information.

And now, some suggestions to help you get ready to take advantage of the coming bonanza:

Finally, if you are thinking about entering the market with a product or you were working on a product when the bottom dropped out of the Mac market, remember this: 3.1% vs 96.9%.


Returning to the Source

By Jean-Louis Gassée

Last week, Netscape made important news. One of the items involved the public release of Navigator source code. This was well received as a smart move, a good reaction to the situation created by the availability of the free Internet Explorer, bundled with Windows or not.

The reasoning is that since Netscape is forced to give away the browser, they might as well release the sources. In doing so, Netscape gets an immediate shot of goodwill. Over the longer term—the theory being there are many more smart people not working at Netscape than inside -- to quote Jim Barksdale, smart programmers will improve the browser in a myriad of creative, unforeseeable ways that will benefit users, Netscape and the industry in general.

This led an honorable correspondent to write and ask whether or not we would do the same for the BeOS and, in some way, make it the "people's OS." Interesting question, one we've actually asked ourselves several times over the life of our little company. In the end, there must be a simple answer, but it's still a complicated question.

Let's take the case of Navigator. Releasing the sources sounds simple, put the source tree up on the Web site and that's it. In reality, it is safe to assume there is licensed code inside Navigator, bits Netscape got from someone else and isn't at liberty to put in the public domain. This might explain why the public release isn't immediate and poses the problem of how functional the released product will be. Once this is done, we have to assume several competing versions will emerge after a while, a situation similar to the one we have with several public and proprietary versions of Unix.

In other words, balkanization, the fragmentation of the product in many different versions, seems to be the price to pay for the legion of independent improvements. With the versions of Unix, technically proficient users were willing to take the source code of an application, modify it, and recompile it for their version of the operating system.

With the Web, however, the situation might be different. The browser runs programs (or interprets HTML statements) over which it doesn't have the control Unix users had over their code. This constraint might actually limit the multigenerational mutations introduced by many independent versions, it might help some sites experiment with dialects of HTML while still reading whatever the "mainstream" dialect happens to be at the moment.

As we know from history, a single monolithic standard always becomes overly conservative, and we could all benefit from innovations introduced by "nonstandard" versions. Or things could get very messy. Personally, I don't believe so; the market will deal harshly with the really bad code. One might even be able to make money within such a context.

Let's say you set up a site for games played over the Web. You might improve the experience and, therefore, your profits, by enhancing responsiveness or other characteristics of the playing experience. You could do so by writing plug-ins for the dominant, integrated browser, or you might feel constrained by that environment and "offer" (terms of bundling to be determined) a modified browser you've crafted under your total control, based on the public domain sources from Netscape. It's an application; it will run beside, on top, or instead of the integrated browser; and, if it's compelling, it will make you money one way or the other as more people will pay for better gaming.

Back to reality, there might be more than one flavor of the Navigator sources, perhaps Windows, X-Windows, and Macintosh, and we don't know how this will play out and complicate things. In any case, it will be fun to watch what actually happens.

As for releasing the BeOS sources, not at this time. We need to advance the cause of BeOS developers, BeOS users and, as a result, Be shareholders. Keeping the Unix experience in mind, as well as our PC hardware target, we don't see how the problems created by balkanizing the BeOS platform would be outweighed by the many improvements independent programmers would, without a doubt, introduce in our product. I wish we could get the latter without the former and I know from experience how someone walking in on a project "sees" things one has stopped seeing after many months or years of work.

For the time being, we'll have to live by the "vigorous" feedback of developers and users and, perhaps, a few ideas of our own, or from our noble and worthy elders.


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.

NEW

Subject: Running things before UserBootscript?

Let's say you want to launch an app just after you boot but before any other apps—including the Tracker—get into the act. You can achieve this sort of behaviour by modifying the system Bootscript—but is it a good idea?

A chorus of disapproval hummed the Dies Irae: Touch Bootscript and you'll be sorry. Lacrymosa Dies Illa. But see THE BE LINE, below.

The thread led to a discussion of the untouchableness of /boot/beos/etc. As Peter Morgensen pointed out...

The fact that /etc is linked to /boot/beos/etc makes /etc useless for ports of POSIX apps. A lot of major POSIX apps have /etc as the default place for config files.

Dominic Giampaolo administered triage:

If you want install a Unix app that needs to put things into an "etc" directory then feel free to put it in ~/config/etc which is equivalent to /usr/local/etc on a unix system.

Back in the thick of it, Sean Gies beat the installation bete noir with a stick:

I'm a big fan of self-contained applications. I hate it when I install something and it decides to spread itself across my file system. It would be nice to know that everything for my FooBar App is in that single FooBar folder and not in 3 different system folders as well. I'd hate to see BeOS to turn into the clutter that Windows and Unix have become.

In response, Osma Ahvenlampi injected a call for libprefs. With reasonable preferences management (i.e. something more controlled than saving settings in a file) file system clutter is minimized, the developer's job is made clearer, and (multi)users have an easier time setting preferences and uninstalling apps.

THE BE LINE: You can modify Bootscript on your own machine, but don't expect to publish anything that depends on it. As many listeners suggested, the only "official" approach is to petition Be to include a Bootscript hook.

Subject: Replicants and multiple inheritance

C++ shop talk. Multiple inheritance appears to stack the deck in favor of the first of the set of inherited-from classes (this is sort of a side- effect of the way the class components are offset, but that's not the issue). Because of this, the Be Book edict that a subclass implementation of BArchivable's Instantiate() should cast its return as an instance of the subclass is, according to Duncan Wilcox, misguided:

I think the fix is that every Instantiate() should always return a BArchivable*, I don't really understand why it was designed to return a pointer to an instance of its class.

THE BE LINE: (From Peter Potrebic) Duncan is correct. We will update the documentation. All Instantiate() implementations should be declared to return a BArchivable*.

Subject: Be's stance on SMB

Does Be Samba? The Session Message Block (SAMBA) protocol lets Windows talk to Linux—or at least lets them share disks and printers. Or something. Does Be or a third party want to get into this rhumba? Some feints, and then this cold water from Chris Herborth:

Samba assumes you're on a UNIX system, where a file descriptor == a socket; this isn't true on BeOS (or Win32, for that matter), so you'll end up re-writing a lot of code.

Not much else, here, except for the demon case-sensitivity which sat grumbling in the corner (how did we get there?). Dominic Giampaolo made an effort to staunch the flow with this reasoned summation (further reduced by the editor):

“When you're using a file open dialog box, the case sensitiveness of the file system doesn't matter because you're clicking on the file name... Case sensitiveness matters most when [you're trying to find a file in a Find panel and you] don't remember the exact case of a filename... We've made the Tracker's Find panel generate case-insensitive queries so that way it doesn't matter if you don't remember the name correctly.

This seems to be a best of all worlds. People clicking on file names don't care about case, people that can't remember a name don't have to remember the case, and shell users get the expected case- sensitive behavior.”

What about internationalization? Is Be preparing for the Spanish language version that will treat "ll" as a single character?

THE BE LINE: We want to do internationalization righter than sooner. It's a complicated problem begging for a simple solution. And so on.

Subject: Desktop

So what is this thing we call the Desktop (ask Sean Gies)? And why are entities from different volumes allowed to live on it at the same time? It's disturbing (continues Mr. Gies) to unmount a floppy and see a bunch of file icons disappear from the Desktop.

Disturbing? It's the way computers should work, says Jeff A. Campbell:

A desktop is for commonly used items. Maybe my commonly used items span more than one disk...

However, Mr. Campbell suggested that the Desktop should be a bit more virtual—it shouldn't be a literal directory. As it is, the Desktop is more amenable to links than to plain files; and creating a link to a file just so you can refer to it from the Desktop is a pain.

Subject: distinguishing between add-ons and applications

A question from Josh J. Berdine:

Is there a good way to differentiate add-ons and applications from the shell or mime types or whatever?

Many listeners wrote in with the bad (for Mr. Berdine) news: Nope. The MIME types (and all other scars and birthmarks) are the same. An add-on can act as an application can act as a library. Most of our listeners applaud the amorphism. Slap Replicants onto this ball of mud and things become even more approbatorially indistinct:

...there is no really clear technical distinction, because with Replicants, any application may be loaded as an add-on to another application. It's more a convenience of naming than a technical specification.” (Jon Watte)

Subject: multiple threads for blitting

A question from Steve LaVietes:

Would the overhead of spawning multiple threads to simultaneously use DrawBitmap on divisions of the total area [of a view] be greater than using just one call?

Marco Nelissen responded, reasonably:

...those calls to DrawBitmap() will effectively be serialized, each thread waiting for the other to complete. You simply can't have two threads drawing into a window at the same time. You might gain something by using DrawBitmapAsync(), which won't wait for the app_server to finish the blit.

Mr. LaVietes mentioned that he was double buffering through a Bitmap. Jon Watte suggested that this might not be necessary:

...double-buffering might be SLOWER than just drawing the stuff you want to draw. Modern graphics card can fill rectangles and draw straight lines much faster than the time it takes to transfer the equivalent bits from memory.

But what about the flicker factor? Mr. LaVietes:

Assuming that a large window needed to be completely drawn over without flicker, what other idea [besides double buffering] would you have?

Mr. Watte's response:

The trick is to ... not clobber an entire area with white and then start filling it in. If you're moving a rectangle, you should draw the rectangle at the new place, then draw whatever was underneath the rectangle in the old place.

Back to asynchronous drawing, Chris Herborth observed that...

“While working on DOOM, I found out that:

DrawBitmapAsync( ... );
Sync();

was faster than:

DrawBitmap( ... );

Strange but true.”

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