Archive for June, 2008

kdesvn-build 1.6.1

June 28th 2008

kdesvn-build 1.6.1 has been released. It’s basically a compilation of bugfixes but it also makes it easier to build Phonon 4.2 instead of Qt’s or kdesupport’s Phonon as well.

Posted by mpyne under KDE & Personal & kdesvn-build | No Comments »

It’s the end of the world as we know it?

June 23rd 2008

On Slashdot (don’t run!), there is an article about whether or not a particle accelerator being built called the Large Hadron Collider (LHC) could actually generate particles that “might destroy the world”.

I thought the very notion sounded stupid on its face, but had no non-intuitive way to explain way. But someone went and made a more logical argument based on the fact that the Earth is being constantly bombarded by much more powerful streams of energy constantly (called cosmic rays). I’d known about cosmic rays since in theory they can show up on our radiation detectors, and indeed you could tell if we were submerged or surfaced based just on the radiacs in the engine room thanks to the shielding provided by the ocean.

The more powerful cosmic rays are many, many times more powerful than anything the LHC would be able to produce, and since no particles have been created in the upper atmosphere that went and “destroyed the world” in the millions of years the planet has been around, seems like an open-and-shut case to conclude that the LHC wouldn’t be able to do any worse.

But ARGH, lots of the commenters on Slashdot seem to have some kind of logical disconnect. One guy says that LHC is still dangerous because it has “multiple high-energy” particles, as if cosmic rays were single-threaded or something and the atmosphere only every has had one cosmic ray at a time?? Apparently this is also “the most important experiment in human history”. Whiskey. Tango. Foxtrot, over. Some other armchair expert in particle physics has decided that the difference between LHC and cosmic rays is that cosmic rays and the particle produced from their collisions travel faster and therefore this is somehow waaaaay different from LHC. But collisions is not the concern as any kind of collision or series of collisions that could destroy the Earth would require much much more energy than LHC could deliver based just on conservation of energy and momentum. If he’s worried about black hole production, then that’s something that would have already happened by now if it were a valid physical mode of interaction.

Luckily the article does have a lot of insightful comments overall, including some of the variety “well if a black hole *could* do us in, here’s how it would happen”.

Posted by mpyne under Personal | 1 Comment »

Improved crossfadiness

June 16th 2008

So I’ve made a few more changes to the crossfading code in JuK. This should hopefully fix crossfading issues completely for people. However, life is weird sometimes. phonon-gst went from being completely unusable (it would crash with JuK) to being the best option right now (perfect crossfading, at least here). phonon-xine, due to the way crossfading is now implemented sounds slightly crackly sometimes while playing music back. Even with the new crossfading routine, incoming music starts out at a high volume before fading in, although it does sound smoother.

Basically what used to happen is that JuK would pipe the music directly from the file to the Audio Output object. Phonon allows you to insert effects into that audio path, which is how crossfading works. You simply start playing the next song with a fader effect, set to fade in, and at the same time insert a fader effect into your currently playing stream set to fade out. Unfortunately phonon-gst has issues with removing effects from an audio path it looks like, which is why I was getting crashes. Even when I fixed the crashes by simply leaking the object as an experiment, the crossfading was horrid under phonon-gst as it takes seemingly forever to setup the fader and insert it into the audio path.

So what I’ve done is to simply insert the fader effect into the path from the start, and simply tell it to fade at the right time. Presto! Except that doing this seems to cause artifacts with phonon-xine output sometimes… *sigh*. But for now now it looks like phonon-gst has gone from unsupported to the best option for JuK at this point, hopefully all the backends will work equally well by KDE 4.1 though.

In other news, kdesvn-build in /trunk will allow you to build the Phonon pseudo-module. I say pseudo because there is no phonon module. It is developed in kdesupport. However I’ve been informed that the correct place for most users to build phonon from would be /branches/phonon/4.2. kdesvn-build has a couple of hacks that would support pulling it from the right location but still wouldn’t be able to build it due to the module layout. So I’ve added a bit of special support for it. I also changed the sample rc file to show how to build Phonon 4.2. If it’s important enough I’ll go ahead and make a 1.6.1 release.

Is there anyone looking forward to C++0x more than I am right now? :) The linked Wikipedia page has tons of changes, some which worry me a bit due to syntax (for example, lambda functions). Then again, I’ve never seen a good syntax for lambda functions, although I’m sure it’s just me.

But things like an auto keyword to allow for automatic type deduction? Very nice. For example, instead of doing:

for ( QList<QWidget *>::ConstIterator it = list.begin(); it != list.end(); ++it() ) {
  // use *it
}

you could do:

for ( auto it = list.constBegin(); it != list.constEnd(); ++it ) {
  // use *it
}

I did have to change begin/end to constBegin/constEnd to make sure that the non-detaching forms of the iterator are used, but this may be something that g++ is able to deduce as well someday.

Probably the biggest other feature I’m looking forward to is the “rvalue references”, which will allow for constructors that “move” data instead of having to copy them over. Qt has kind of mitigated the problem somewhat in their shared classes but you can benefit from this even in non-Qt-using code. There’s many other improvements too, I just wonder how long they’ll take to get into a g++ which we can use for KDE development. :)

Posted by mpyne under C++ & KDE | 3 Comments »

Hey, check it out

June 13th 2008

Apparently someone has decided that the best use of their advertising money would be to purchase ads on the term “KDE”. Ads that have nothing to do with KDE, but everything to do with programming with Gtk/WebKit…

Now obviously this was likely not paid for by the GNOME foundation or even anyone associated with the GNOME project as they’re all around a good crowd in my experience. But I’d be interested in knowing who is doing this, as it is very poor form.

This kind of thing has happened before apparently, before my time. There was an article on Linux.com. And Kurt Granroth, who was one of the people who noticed the first time still has his page about it up.

Update 02:34: Not as soon as I’ve posted it, and it disappears on me. I don’t know if it was taken down, expired, too many people clicked on it, or if Google rotates ad words or something. But I’m still intrigued…

Posted by mpyne under KDE | 1 Comment »

Programming tips

June 3rd 2008

So I finally fixed a bug which has been causing some people a bit of grief, bug 160284. This bug involves crashes due to a couple of different things:

  1. A memory address was casted to a larger sized type, which was not aligned properly for that size.
  2. In addition, there were issues handling memory which was mapped from a file using mmap(2).

What’s the deal with alignment you ask? It deals with computer architecture. Pretty much every major computer architecture I can think of requires memory accesses of a datatype of a certain size to be on a memory address that is a multiple of the datatype’s size. For instance, if you were trying to read a 32-bit integer, the CPU would expect a memory address to be divisible by 4, since the integer takes up 4 bytes in memory.

Note that this is a glossing-over. Just because a datatype is 4 bytes long doesn’t mean that as long as your memory address is divisible by 4 that it’s good. An architecture could require all memory access to happen on 8 or 16 byte boundaries for instance. In addition, the predominant architecture, x86, for the most part does not have these restrictions. Certain instructions do require aligned memory however, and unaligned memory access is slower even when it’s allowed.

The reason you never hear about this is that the compiler knows about the alignment restrictions for the architecture it’s building for, and takes care of it for you. Unless you try and go around it…

In our case, we had code to read in a file by mmap-ing it. The first 17 or so bytes were read to ensure that the file we were reading in is correct. Then the very next 4 bytes were cast to a 32-bit integer for a version check. This access is unaligned, but works for most systems since x86 does not crash, but instead is merely slower.

The solution is to add padding between the 17-byte magic string and the version integer. There are two obvious ways of doing that:

  1. Do it yourself. Calculate the next memory address that the CPU expects an integer access to fall on and insert padding until you get there. Unfortunately there is no easy way to determine alignment restrictions at build or run time that I can see.
  2. Let the compiler do it for you. What you need to do is make your header data a struct or class. By default each member will be correctly aligned, and better yet if you simply read and write a header at a time you won’t need to do tricky pointer arithmetic. The hard part is ensuring that the struct / class contains the character data and not merely a character pointer.

What I used in my fix was something like this:

static const char KPC_MAGIC[] = "KDE PIXMAP CACHE DEUX";
struct KPixmapCacheDataHeader
{
    KPixmapCacheDataHeader() :
        cacheVersion(0),
        size(sizeof(*this))
    {
        magic[0] = '\0'; // In case of inadvertent strcpy or something.
    }

    // -1 from sizeof so we don't write out the trailing null.
    char    magic[sizeof(KPC_MAGIC) - 1];
    quint32 cacheVersion;
    quint32 size;
};

Other fun programming tips:

  • Dealing with endianness conversions? Don’t reimplement it yourself! Qt includes template functions to do it for you in QtGlobal.
  • Want to know the alignment of a datatype at compile time? Tom Lokovic has an interesting C++ solution.
  • Are you using QDataStream? Please make sure that unless your data types are the C++ basic types (i.e. basically the Qt integer types) that you are explicitly setting a binary version on your QDataStream and sticking with it. This is all described in QDataStream’s documentation. I’ve fallen afoul of this before which broke JuK in KDE 4.0 where you couldn’t load KDE 3.5 data, and I’ve seen a lot of non-trivial uses of QDataStream without setting the version. If you don’t set a version then Qt will pick one for you, and it’s likely to change without notice. It’s up to you to do it, Qt doesn’t/can’t encode QDataStream version info into the stream.
  • Although I wasn’t required to go this route, if you want to create a C++ object in shared memory (like a QMutex for shared mutual exclusion) then placement new might be for you. With placement new you handle allocating the memory, all new does is create the object where you tell it to. Of course, you’ll have to manually destruct the object too…
  • The corollary to the compiler handling alignment of structs is that if you make a struct intended to reflect a file header, you may have to tell the compiler to keep the struct “packed”. The flag to do so is implementation dependent however. Your program won’t crash if you do this as the compiler will insert code to fix up unaligned references as necessary. So if you were wondering why the sizeof a struct is different than what you expect, it could be due to alignment.

BTW, if you were annoyed at JuK’s track announcement popup going weird places, it’s fixed now.

Posted by mpyne under C++ & KDE & Programming & Tutorial | 6 Comments »