The Blocks C extension and GIO asynchronous calls

December 27th, 2011

So, I intended to be completely away from my computer during my vacations, but hey. I have been interested in this new extension Apple added to the C language a little while ago which introduces the equivalent of closures to C. Today I spent a few minutes looking into it and writing a few tests with the help of clang.

Here’s something I came up with, to use a block as the callback for a GIO asynchronous call:

#include <Block.h>
#include <gio/gio.h>

typedef void (^Block)();

static void async_result_cb(GObject* source,
                            GAsyncResult* res,
                            gpointer data)
{
    Block block = (Block)data;
    block(res);
}

int main(int argc, char** argv)
{
    g_type_init();

    if (argc != 2) {
        g_error("Blah.");
        return 1;
    }

    GMainLoop* loop = g_main_loop_new(NULL, TRUE);
    GFile* file = g_file_new_for_path(argv[1]);

    g_file_query_info_async(file,
                            G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                            G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT,
                            NULL, async_result_cb, (gpointer) ^ (GAsyncResult* res) {
        GError* error = NULL;
        GFileInfo* info = g_file_query_info_finish(file, res, &error);

        if (error) {
            g_error("Failed: %s", error->message);
            g_error_free(error);
            return;
        }

        g_message("Content Type: %s",
                  g_file_info_get_attribute_string(info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE));

        g_object_unref(info);
        g_main_loop_quit(loop);
    });

    g_main_loop_run(loop);
    g_object_unref(file);

    return 0;
}

Pretty neat, don’t you think? To build you need to use clang and have the blocks runtime installed (libblocksruntime-dev in Debian). Here’s the command I use:

$ clang -fblocks -o gio gio.c -lBlocksRuntime `pkg-config --cflags --libs gio-2.0`

AIClass and vacations

December 22nd, 2011

One of my side projects for these last months was to enroll on the online Introduction to AI class, with Peter Norvig and Sebastian Thrun, professors at Stanford. Through it I also learned about the Kahn Academy. I must say that getting to know these efforts made me feel similar to when I found Free Software: it’s hard to believe that such great things exist!

I learned some really cool stuff, and was also introduced to the amazing work of Sebastian Thrun with self-driving cars, it was an awesome experience! Last weekend I took the final exam, and today I got the certificate of accomplishment. It was delivered as a signed PDF which can be checked with a certificate they provided, pretty neat. I’m very happy, and motivated to enroll on more such courses in the future =). Now it’s time to cool down, though. My vacations start today, and on the weekend I’ll travel to the sunny Fortaleza, in northeastern Brazil, to enjoy some nice beaches and get some tan. See you next year!

Statement of Accomplishment - AIClass 2011

Statement of Accomplishment - AIClass 2011

WebKitGTK+ hackfest \o/

December 7th, 2011

It’s been a couple days since I returned from this year’s WebKitGTK+ hackfest in A Coruña, Spain. The weather was very nice, not too cold and not too rainy, we had great food, great drinks and I got to meet new people, and hang out with old friends, which is always great!

Hackfest black board, photo by Mario

I think this was a very productive hackfest, and as usual a very well organized one! Thanks to the GNOME Foundation for the travel sponsorship, to our friends at Igalia for doing an awesome job at making it happen, and to Collabora for sponsoring it and granting me the time to go there! We got a lot done, and although, as usual, our goals list had many items not crossed, we did cross a few very important ones. I took part in discussions about the new WebKit2 APIs, got to know the new design for GNOME’s Web application, which looks great, discussed about Accelerated Compositing along with Joone, Alex, Nayan and Martin Robinson, hacked libsoup a bit to port the multipart/x-mixed-replace patch I wrote to the awesome gio-based infrastructure Dan Winship is building, and some random misc.

The biggest chunk of time, though, ended up being devoted to a very uninteresting (to outsiders, at least), but very important task: making it possible to more easily reproduce our test results. TL;DR? We made our bots’ and development builds use jhbuild to automatically install dependencies; if you’re using tarballs, don’t worry, your usual autogen/configure/make/make install have not been touched. Now to the more verbose version!

The need

Our three build slaves reporting a few failures

For a couple years now we have supported an increasingly complex and very demanding automated testing infrastructure. We have three buildbot slaves, one provided by Collabora (which I maintain), and two provided by Igalia (maintained by their WebKitGTK+ folks). Those bots build as many check ins as possible with 3 different configurations: 32 bits release, 64 bits release, and 64 bits debug.

In addition to those, we have another bot called the EWS, or Early Warning System. There are two of those at this moment: one VM provided by Collabora and my desktop, provided by myself. These bots build every patch uploaded to the bugzilla, and report build failures or passes (you can see the green bubbles). They are very important to our development process because if the patch causes a build failure for our port people can often know that before landing, and try fixes by uploading them to bugzilla instead of doing additional commits. And people are usually very receptive to waiting for EWS output and acting on it, except when they take way too long. You can have an idea of what the life of an EWS bot looks like by looking at the recent status for the WebKitGTK+ bots.

Maintaining all of those bots is at times a rather daunting task. The tests require a very specific set of packages, fonts, themes and icons to always report the same size for objects in a render. Upgrades, for instance, had to be synchronized, and usually involve generating new baselines for a large number of tests. You can see in these instructions, for instance, how strict the environment requirements are – yes, we need specific versions of fonts, because they often cause layouts to change in size! At one point we had tests fail after a compiler upgrade, which made rounding act a bit different!

So stability was a very important aspect of maintaining these bots. All of them have the same version of Debian, and most of the packages are pinned to the same version. On the other hand, and in direct contradition to the stability requirement, we often require bleeding edge versions of some libraries we rely on, such as libsoup. Since we started pushing WebKitGTK+ to be libsoup-only, its own progress has been pretty much driven by WebKitGTK+’s requirements, and Dan Winship has made it possible to make our soup backend much, much simpler and way more featureful. That meant, though, requiring very recent versions of soup.

To top it off, for anyone not running Debian testing and tracking the exact same versions of packages as the bots it was virtually impossible to get the tests to pass, which made it very difficult for even ourselves to make sure all patches were still passing before committing something. Wow, what a mess.

The explosion^Wsolution

So a few weeks back Martin Robinson came up with a proposed solution, which, as he says, is the “nuclear bomb” solution. We would have a jhbuild environment which would build and install all of the dependencies necessary for reproducing the test expectations the bots have. So over the first three days of the hackfest Martin and myself hacked away in building scripts, buildmaster integration, a jhbuild configuration, a jhbuild modules file, setting up tarballs, and wiring it all in a way that makes it convenient for the contributors to get along with. You’ll notice that our buildslaves now have a step just before compiling called “updated gtk dependencies” (gtk is the name we use for our port in the context of WebKit), which runs jhbuild to install any new dependencies or version bumps we added. You can also see that those instructions I mentioned above became a tad simpler.

It took us way more time than we thought for the dust to settle, but it eventually began to. The great thing of doing it during the hackfest was that we could find and fix issues with weird configurations on the spot! Oh, you build with AR_FLAGS=cruT and something doesn’t like it? OK, we fix it so that the jhbuild modules are not affected by that variable. Oh, turns out we missed a dependency, no problem, we add it to the modules file or install them on the bots, and then document the dependency. I set up a very clean chroot which we could use for trying out changes so as to not disrupt the tree too much for the other hackfest participants, and I think overall we did good.

The aftermath

By the time we were done our colleagues who ran other distributions such as Fedora were already being able to get a substantial improvements to the number of tests passing, and so did we! Also, the ability to seamlessly upgrade all the bots with a simple commit made it possible for us to very easily land a change that required a very recent (as in unreleased) version of soup which made our networking backend way simpler. All that red looks great, doesn’t it? And we aren’t done yet, we’ll certainly be making more tweaks to this infrastructure to make it more transparent and more helpful to the users (contributors and other people interested in running the tests).

If you’ve been hit by the instability we caused, sorry about that, poke mrobinson or myself in the #webkitgtk+ IRC channel on FreeNode, and we’ll help you out or fix any issues. If you haven’t, we hope you enjoy all the goodness that a reproducible testing suite has to offer! That’s it for now, folks, I’ll have more to report on follow-up work started at the hackfest soon enough, hopefully =).

Accelerated Compositing in webkit-clutter

November 29th, 2011

For a while now my fellow Collaboran Joone Hur has been working on implementing the Accelerated Compositing infrastructure available in WebKit in webkit-clutter, so that we can use Clutter’s powers for compositing separate layers and perform animations. This work is being done by Collabora and is sponsored by BOSCH, whom I’d like to thank! What does all this mean, you ask? Let me tell me a bit about it.

The way animations usually work in WebKit is by repainting parts of the page every few milliseconds. What that means in technical terms is that an area of the page gets invalidated, and since the whole page is one big image, all of the pieces that are in that part of the page have to be repainted: the background, any divs, images, text that are at that part of the page.

What the accelerated compositing code paths allow is the creation of separate pieces to represent some of the layers, allowing the composition to happen on the GPU, removing the need to perform lots of cairo paint operations per second in many cases. So if we have a semi-transparent video moving around the page, we can have that video be a separate texture that is layered on top of the page, made transparent and animated by the GPU. In webkit-clutter’s case this is done by having separate actors for each of the layers.

I have been looking at this code on and off, and recently joined Joone in the implementation of some of the pieces. The accelerated compositing infrastructure was originally built by Apple and is, for that reason, works in a way that is very similar to Core Animation. The code is still a bit over the place as we work on figuring out how to best translate the concepts into clutter concepts and there are several bugs, but some cool demos are already possible! Bellow you have one of the CSS3 demos that were made by Apple to demo this new functionality running on our MxLauncher test browser.

You can also see that the non-Accelerated version is unable to represent the 3D space correctly. Also, can you guess which of the two MxLauncher instances is spending less CPU? ;) In this second video I show the debug borders being painted around the actors that were created to represent layers.

The code, should you like to peek or test is available in the ac2 branch of our webkit-clutter repository: http://gitorious.org/webkit-clutter/webkit-clutter/commits/ac2

We still have plenty of work to do, so expect to hear more about it. During our annual hackfest in A Coruña we plan to discuss how this work could be integrated also in the WebKitGTK+ port, perhaps by taking advantage of clutter-gtk, which would benefit both ports, by sharing code and maintenance, and providing this great functionality to Epiphany users. Stay tuned!

A incrível estória do plano que nasceu morto – Parte 1

July 17th, 2011

Das coisas engraçadas que eu ouvi enquanto assistia o streaming do segundo encontro dos blogueiros progressistas nenhuma superou a resposta do Paulo Bernardo quando questionado sobre por que não se colocava banda larga sob regime público. O Ministro argumentou que o Estado não tinha dinheiro para fazer tudo sozinho, então que precisaria da ajuda das empresas privadas.

Ou o Ministro achou que o questionador não sabia do que estava falando ou não sabia ele mesmo. A diferença entre regime público e regime privado não tem nada a ver com quem faz o investimento ou presta o serviço, mas tem muito a ver com a forma que esse serviço é prestado, que metas são estabelecidas e que recursos podem ser utilizados. Diz a Lei Geral de Telecomunicações:

Art. 63. Quanto ao regime jurídico de sua prestação, os serviços de telecomunicações classificam-se em públicos e privados.

Parágrafo único. Serviço de telecomunicações em regime público é o prestado mediante concessão ou permissão, com atribuição a sua prestadora de obrigações de universalização e de continuidade.

Art. 64. Comportarão prestação no regime público as modalidades de serviço de telecomunicações de interesse coletivo, cuja existência, universalização e continuidade a própria União comprometa-se a assegurar.

Parágrafo único. Incluem-se neste caso as diversas modalidades do serviço telefônico fixo comutado, de qualquer âmbito, destinado ao uso do público em geral.

http://www.planalto.gov.br/CCIVIL_03/leis/L9472.htm

Ou seja, se o serviço está em regime público o Estado está comprometido com assegurar sua universalização e a empresa é concessionária do serviço e tem que se pautar pela regulação do Estado no setor. Não só isso, mas poderá dispor dos recursos do FUST, como já bem lembrou João Brant. Hoje somente a telefonia fixa está em regime público, portanto só as empresas que prestam serviços de telefonia são consideradas concessionárias de serviço público, mas a prestação de serviço de banda larga não.

Então quando o participante perguntou ao Ministro: “por que não colocar banda larga em regime público?” ele não estava querendo saber por que o Estado não atuava como (único?) empresário do setor, mas sim se o governo teria bolas pra chamar pra si os deveres e a queda de braço que transformar a banda larga em serviço público concedido trariam. A própria LGT fala o que é preciso pra isso:

Art. 18. Cabe ao Poder Executivo, observadas as disposições desta Lei, por meio de decreto:

I – instituir ou eliminar a prestação de modalidade de serviço no regime público, concomitantemente ou não com sua prestação no regime privado;

http://www.planalto.gov.br/CCIVIL_03/leis/L9472.htm

Pelo visto o governo não tem bolas pra isso, não. Aí com certeza vai vir alguém e falar de algum impedimentozinho como “a iniciativa tem que partir da ANATEL”. Todos os conselheiros da ANATEL hoje foram indicados por Lula. Além disso, se julgarem necessárias mudanças na lei, ora, façam! Não teve muita dificuldade em mudar o Plano Geral de Outorgas para permitir a fusão da Oi com a BrT, teve?

Se você é petista daqueles que gritaram ForaFHC e adoram colocar nele a etiqueta de neoliberal é um bom momento para se deliciar com as ironias de a ação do governo petista estar se mostrando menos alinhada com um Estado regulador e garantidor da universalização, mesmo que uma lei aprovada por FHC dê a ele os mecanismos para isso.

PNBL: o governo devia começar por fazer o dever de casa

June 8th, 2011
Originalmente publicado no Trezentos

O papel do Estado

O Brasil tem um fenômeno interessante. Nós tendemos a transformar qualquer discussão a respeito de uma política ou prática específica em discussão genérica a respeito de conceitos mais gerais, filosóficos, acadêmicos. Uma discussão a respeito de como avançar na disponibilidade, preço e qualidade da Internet no país acaba se tornando uma discussão a respeito do papel do Estado e não faltam teorias conspiratórias e pré-concepções a respeito dos modelos que podem ser adotados. Normalmente os problemas mais mundanos e reais, como o governo sendo simplesmente incompetente para cumprir qualquer que seja a escolha ficam de fora. Para evitar essa discussão cito a lei 9.472, de 1997, que organiza os serviços de telecomunicação e cria a ANATEL e que usarei como ponto de partida da minha argumentação:

Art. 2° O Poder Público tem o dever de:

I – garantir, a toda a população, o acesso às telecomunicações, a tarifas e preços razoáveis, em condições adequadas;

II – estimular a expansão do uso de redes e serviços de telecomunicações pelos serviços de interesse público em benefício da população brasileira;

III – adotar medidas que promovam a competição e a diversidade dos serviços, incrementem sua oferta e propiciem padrões de qualidade compatíveis com a exigência dos usuários;

IV – fortalecer o papel regulador do Estado;

V – criar oportunidades de investimento e estimular o desenvolvimento tecnológico e industrial, em ambiente competitivo;

VI – criar condições para que o desenvolvimento do setor seja harmônico com as metas de desenvolvimento social do País.

O arcabouço jurídico das telecomunicações no Brasil

É do interesse do país que haja Internet de alta velocidade a preço baixo e disponível para todos os brasileiros. O Estado brasileiro decidiu, na década de 1990, que o sistema de telecomunicações do país, até então um monopólio estatal, deveria ser concedido à iniciativa privada para acelerar investimentos e aumentar o alcance do serviço. Sem entrar no mérito da concessão, que mereceria uma discussão separada, vieram com ela algumas mudanças institucionais: a criação de uma agência reguladora, a ANATEL, pela lei 9.472, já citada acima, a criação, no ano 2000, de um fundo para universalização, o FUST, Fundo de Universalização dos Serviços de Telecomunicação, pela lei 9.998 e do FUNTTEL, Fundo para o Desenvolvimento Tecnológico das Telecomunicações, pela lei 10.052, também de 2000.

A ANATEL ficou responsável por fazer a fiscalização das empresas, garantindo que elas cumprissem suas metas de universalização, por regulamentar o setor e por cuidar dos leilões de concessões a novos serviços de telecomunicações que aparecessem conforme a tecnologia se desenvolvesse. Os fundos foram criados para garantir que existiria financiamento privado para que as empresas atendessem os setores menos lucrativos e comercialmente interessantes. Financiamento privado porque o dinheiro que alimenta os fundos vem da receita bruta das concessionárias de telefonia.

A lei 9.998 estabelece que os recursos do FUST deveriam ser usados em “consonância com plano geral de metas para universalização de serviço de telecomunicações ou suas ampliações [...]“. Pela sua descrição o FUST soa como uma boa solução para investimentos em banda larga, mas há quem diga (erroneamente, na minha opinião) que há problemas legais que impediriam esse uso. Esse tema já foi bem discutido no Trezentos pelo colega João Brant, portanto não vou aprofundar muito.

Um primeiro passo em direção a uma melhor Internet para os brasileiros

O Plano Nacional de Banda Larga é uma iniciativa do Governo Federal que pretende levar, com uma rede operada por uma estatal, financiada inicialmente com recursos do tesouro nacional, Internet barata para lugares em que a iniciativa privada não chega. Há também, claramente, a intenção de criar competição no mercado para fazer com que as operadoras privadas baixem seus preços. Eu particularmente acho a ideia interessante, mas acredito que antes de tentar vôos mais longos como esse o Governo precisava começar por fazer a lição de casa com o que já existe.

O descaso com a fiscalização, com os bens públicos e com o FUST

Apesar de o dever do Poder Público ser, como diz a lei 9.472, fortalecer o papel regulador do Estado, o que se viu nos últimos anos foi omissão e descaso com o setor de telecomunicações (e com alguns outros, diga-se). A ANATEL, que devia fiscalizar o setor está há anos e anos com grande parte do seu orçamento contingenciado, impedindo que a agência exerça seu papel. Além de falta de orçamento há também descaso com os bens públicos. As concessionárias tem em sua posse diversos bens chamados “reversíveis”, que devem voltar ao Estado ao final da concessão, que se dará em 2025. É dever da ANATEL acompanhar e aprovar qualquer tipo de transação com esses bens, mas as empresas tem feito o que bem entendem e a ANATEL sequer tem uma lista dos bens considerados reversíveis. Finalmente a ANATEL reconheceu o problema e avisou que vai aplicar multa. A pergunta que fica é: a multa vai ser paga mesmo?

Digo isso porque além de fazer o que bem entendem com os bens públicos, as concessionárias também não tem se dado ao trabalho de pagar as multas que lhes são aplicadas. Esse não é um problema exclusivo do setor de comunicações, diga-se de passagem: segundo estudo do TCU que infelizmente só começou em 2008, de todas as multas aplicadas de 2008 a 2010, só 4,7% foram recolhidas. Era de se esperar que as entidades tivessem entrado na justiça para obrigar as empresas a pagarem, não é? Mas não. Incluindo as cobranças que estão na justiça chegamos a míseros 5,6%.

Com a palavra o TCU:

A reduzida arrecadação de multas afeta de forma significativa a credibilidade do poder sancionador do Estado, exigindo que providências sejam adotadas para que as cobranças administrativa e judicial sejam realizadas de forma mais tempestiva e eficaz.

Em outras palavras, não há incentivo para as empresas agirem de forma responsável e cumprirem suas obrigações, já que mesmo que sejam multadas não precisam pagar e está tudo bem, não haverá sanções. Não é de assustar que bueiros continuem explodindo na cidade do Rio de Janeiro e que metas de universalização estipuladas não sejam cumpridas pelas teles, não é? Metas de universalização que, diga-se de passagem, a ANATEL não parece muito empenhada em defender quando cria novos planos, retirando das metas pontos já estabelecidos anteriormente em troca de benefícios duvidosos para os interesses do país

A falta de concorrência

Existe uma tendência a acreditar que falta de concorrência faz com que os serviços fiquem piores e mais caros. Faz sentido: se você faz questão de ter internet e só tem uma escolha você vai ter que aceitar o que tem. Nas grandes cidades brasileiras hoje há certamente mais de uma opção disponível, mas ainda assim se acredita que a falta de concorrência é um fator importante no geral.

O governo não ajudou muito também nesse quesito. Em 2008 a Brasil Telecom andava mal das pernas e começou um papo de fusão com a Oi. Havia diversas soluções possíveis, inclusive a pulverização das ações dos sócios que não queriam mais participar. Naquele momento, no entanto, uma fusão era uma alternativa que não existia, por ser vedada pelo Plano Geral de Outorgas. O governo federal dizia não comentar o assunto por ser um assunto “privado”, mas não escondia a insatisfação com a pulverização e já começava a falar na importância de ter uma “grande tele nacional”. Pois bem. Acertadas as tratativas entre os acionistas da Oi e da BrT, o governo não demorou em alterar o Plano Geral de Outorgas, permitindo que a fusão acontecesse. A fusão também foi permitida pelo CADE e pela ANATEL e foi financiada com empréstimo subsidiado do BNDES. Belo jeito de incentivar a concorrência, não acha?

Não demorou muito tempo também para o conto da carochinha que era a história da “grande tele nacional” caísse por terra, com o próprio governo brasileiro intermediando a aquisição de um pedaço da Oi pela Portugal Telecom. Me parece que fica claro que o governo é muito bonzinho com aqueles grandes capitalistas que são amigos do rei – isso não é novidade nenhuma, na verdade: o Estado brasileiro é amigo dos grandes historicamente. Triste né? Isso porque eu nem falei ainda de como a Oi ajudou o filho do Lula (um dos que ganhou passaportes especiais e não devolveu até hoje) a enriquecer investindo rios de dinheiro na recém-criada empresa de jogos. O Brasil é realmente o país das oportunidades!

A pura e simples incompetência

Eu costumo brincar que se nós vivessemos no Brasil anunciado nós estaríamos muito bem. Pena que nós vivemos no Brasil real, aquele que acontece de fato, à revelia dos anúncios e promessas de candidatos e governos. Eu não acredito em nada que o governo anuncie, eu espero pra ver. Por quê? Porque algo que é anunciado acontecer de fato é praticamente a excessão. Quando acontece, demora muito mais do que o anunciado. Pra ficar só no PNBL, no meio de 2010 o governo anunciava aos quatro cantos que até o final do ano teria 100 cidades já atendidas pelo PNBL.

Pra quem conhece a lerdeza e a incompetência do governo mesmo para fazer o básico já era bem óbvio na época do anúncio que não passava de um embuste, talvez com a intenção de dar sustância à campanha da candidata da situação, ou talvez fosse só otimismo injustificado mesmo. Eu prefiro não ver malícia no que pode ser visto como pura incompetência, de qualquer forma tenho certeza de que muita gente acreditou no anúncio. Em dezembro a Telebrás fez novo anúncio, como se nada tivesse acontecido, falando que em abril de 2011 seria alcançada a meta das 100 cidades. Eu não sei vocês, mas a mim me parece que já é junho. Foi só em maio que a Telebrás, a Petrobrás e a Eletrobrás conseguiram chegar a um acordo com relação ao uso das fibras das últimas pela primeira. Isso porque são todas estatais, teoricamente controladas pelo poder público. Como se tinha tanto otimismo com o tempo não sei, mas não custa dar a impressão de que o governo é ágil aos mais desavisados, né?

Conclusão

Eu acredito que um Plano Nacional de Banda Larga é de extrema importância para o Brasil. As comunicações são um mercado complexo, oligopolizado, que precisa de investimentos vultuosos e exige interferência do governo para corrigir falhas de mercado e garantir os interesses dos cidadãos brasileiros e do país. Acreditar que o plano vai dar certo são outros quinhentos. Eu gostaria de ver o governo pelo menos cumprir o básico daquilo que já está na lei, que já é interesse do povo brasileiro ao invés de continuar sendo bonzinho com os grandes empresários amigos.

Um primeiro passo para a universalização da banda larga é o governo federal fazer o dever de casa.

My experience with GNOME 3 so far

May 13th, 2011

You know, GNOME Shell and I are not really strangers to each other for a long time now. I have been using it almost daily as my main desktop since late 2009, when I started shipping it to Debian experimental. That means that I had ample opportunity to both get used to it and witness the huge improvements it had with every new release.

My general feeling towards GNOME 3 is this: ♥. Yes, I love it! I love the new themes, I love the window borders, I love the top panel, the overview, the dynamic workspaces, I love the Me menu, I love the clock and the calendar, the system indicators with the beautiful symbolic icons, being able to search for applications in such a nice way, the window animations, the multi-screen support, the new nautilus, the dash, looking glass. It’s hard for me to even express how thankful I am and how much admiration I have for the awesome folks who helped bring this to life. Thanks so much!

My GNOME3 desktop

My GNOME 3 desktop

After all this time, there are only two things I can say I dislike about GNOME3, apart from some minor wishlists: the alt-tab behaviour and the message tray. Let me expand on those.

Message Tray

Of the very few things I dislike, there is only 1 I hate and cannot see myself living with: the accordion animation in the message tray. No, really, it’s such a terrible, terrible idea. Every single time I try to use that thing I overshoot while moving the mouse to the left, then overshoot again moving the mouse to the right because the frigging icon has moved. It’s no good knowing that I can click in the text or in the empty area to its right, it feels wrong. It’s terrible that my actual target is moving at all. Every single time I use it is a small frustration for me – it’s as if the message tray was playing games with me, laughing at me for not having good enough mouse pointer driving skills – even more than the infamous sub-menus used to. And I had to go through that penance whenever I wanted to find the person I was chating with to resume the conversation.

I wrote an extension that disables the accordion animation by simply not showing the title at all when you hover the icon, and I patched GNOME Shell’s CSS to make the icons a bit bigger, so that it’s easier for me to hit them with the mouse. It’s clearly not ideal, and you still have to click the various “people” icons to figure out which of your friends who were lazy enough to not add a picture to their IM profiles is that one, but it’s still much better than chasing the (smaller) ones around to figure that out. Perhaps we should have the icons be bigger and always have the title bellow them? I don’t know, I trust the awesome designers who designed the awesomess that’s everywhere else will come up with a great idea.

My Message Tray

My message tray with bigger icons and no accordion animation.

Alt Tab

The number 1 feature of workspaces for me has always been locality – being able to not see all of the other applications and windows that are open elsewhere. This lowers the amount of noise when I’m trying to find something. The overview is very nice in this matter – only windows in the current workspace are shown, and even when you have an extra screen, the windows in there appear in that screen.

The alt-tab behaviour, on the other hand, of showing all windows and apps, even with the separator, bothers me. It’s really useful to have when you want to go to a specific window no matter where it is (I usually use the dash for that, though), but it adds noise when you want to go to a specific window _in this_ workspace, which is the most common use case for my usage. So I copied the alt-tab code over to an extension and modified it so that only windows in the current workspace would be considered.

In addition to that, with the windows in the extra screen always being there no matter what workspace you’re in (which I think is an awesome idea), they are effectively in all workspaces, so they add constant noise even with my extension. It’s also weird to have to look at the main screen to switch to a window in the extra screen. There’s a huge discontinuity. What I would prefer is having alt-tab to follow the mouse regarding screens – only show windows in the extra screen if you hit alt-tab in there, making sure the selector thing appears in there as well.

“Porque eu aprendi na faculdade que alocar memória é caro”

May 9th, 2011

Mais um exemplo interessante a respeito daquilo que falei num post anterior. Recentemente uma pessoa que começou a trabalhar em um projeto em que eu trabalho há algum tempo me pediu que opinasse a respeito de um patch dele. O patch original dele havia sido revisado por um colega de projeto e além de umas bobagenzinhas de estilo havia uma única preocupação: “por quê você quer fazer essa mudança?” A mudança era bastante simples: evitava que uma variável fosse liberada e realocada em alguns casos específicos.

Nesse projeto uma das coisas que as pessoas menos gostam é de otimizações cegas. Se você faz uma mudança, essa mudança tem chances de introduzir bugs e de aumentar a complexidade do código. Se você vai incorrer nesse risco, é melhor saber que está de fato fazendo alguma diferença. Por isso, otimizações em geral só são bem-vindas se forem acompanhadas de um teste de desempenho que mostra melhoria. Se não melhora nada, pra que mudar? É claro que há excessões à regra e algumas mudanças acabam simplificando o código e são bem-vindas mesmo se o único resultado for não piorar o desempenho.

Quando eu falei que não é legal fazer otimizações cegas ele me disse: “Cega ou não, estou fazendo a mudança porque aprendi na faculdade que alocações são caras, principalmente porque causam chamadas de sistema e por isso devem ser evitadas”. Opa. Alocações de memória de fato envolvem o kernel, mas será que todas as alocações de memória causam chamadas de sistema e a consequente (e cara) troca de contexto para modo kernel?

Fácil testar isso. Se for verdade que cada alocação gera uma chamada de sistema o seguinte programa vai exibir 100 milhões de chamadas de sistema quando o executarmos através do strace:


#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
    int i;
    char* data;

    printf("START\n");
    for (i = 0; i < 100000000; i++)
        data = malloc(10);
    printf("END\n");

    return 0;
}

Vejamos:

[...]
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbe62175000
write(1, "START\n", 6START
)                  = 6
brk(0)                                  = 0x1b83000
brk(0x1ba4000)                          = 0x1ba4000
write(1, "END\n", 4END
)                    = 4
exit_group(0)                           = ?

Mas hein? Duas chamadas de sistema entre os dois writes? Pois é. Acontece que o pessoal que escreveu a malloc() já sabe que pedir memória pro kernel é caro e fizeram a libc pré-alocar uma quantidade maior de memória de uma vez e ir entregando pedaços dessa memória conforme a aplicação pede. Isso significa que alocação de memória não é cara? Não. É razoavelmente cara mesmo que não haja troca de contexto, afinal de contas a libc precisa fazer um tanto de trabalho pra saber quanto tem alocado e saber qual o tamanho de cada pedaço de memória que foi alocado para poder liberar depois com free(). Se ao invés de fazer malloc 100 milhões de vezes eu fizer uma só e fizer 100 milhões de memset() o programinha fica 10 vezes mais rápido.

Isso significa que nós devemos evitar qualquer alocação que seja possível evitar? Depende. Pra começo de conversa esse é um teste extremo, não uma carga de trabalho real. Testes são sempre melhores em cargas reais (ou mais parecidas com algo real). Mas principalmente, se for pra piorar muito a legibilidade do código, torná-lo mais complexo, manter memória comprometida por mais tempo que o necessário, é importante que haja um ganho em desempenho para contrabalancear. E esse ganho tem que ser medido, não imaginado =).

Scale Fail

May 6th, 2011

Hoje foi publicado no site Linux Weekly News um artigo de Josh Berkus chamado Scale Fail (part 1) é preciso ser assinante da LWN ou esperar uma semana para que o artigo seja tornado público, mas enquanto isso você pode assistir a uma apresentação que o Josh Berkus fez aqui. O assunto não só é interessante como tem muito a ver com o tema de que eu tratei no meu último post =). O Josh Berkus é um dos principais desenvolvedores do PostgreSQL e também fez uma palestra muito interessante na Linux Foundation Collaboration Summit do ano passado sobre como evitar que seu projeto gere uma comunidade. Recomendo fortemente. Se interessar, também recomendo a palestra seguinte, do Chris DiBona do Android.

Mesa redonda

May 4th, 2011

Anos atrás trabalhei num ambiente em que todos os usuários praticamente conheciam o hostname do servidor de arquivos. Usuários saberem hostnames de servidores de arquivos quase nunca é um bom sinal. Todos reclamavam constantemente do tal servidor, falando sempre de como era lento o acesso aos arquivos. Assim que entrei me informaram das medidas que já haviam sido tomadas: sempre que a reclamação ficava muito grande o administrador de rede colocava uma placa de rede de 100Mbps nova no servidor, mas isso parecia pouco resolver.

Alguns anos mais tarde trabalhei em outro lugar em que havia uma aplicação web acessada por um número bastante grande de usuários de todo o Brasil. Havia um grande porém. Apesar de eu fazer parte da equipe de infraestrutura, todo o ambiente de produção dessa instituição ficava sob a responsabilidade de uma outra empresa. A tal aplicação começou a exibir graves problemas de desempenho e como havia prazos relacionados ao preenchimento de dados na aplicação, cada dia que passava sem que muitos usuários conseguissem fazer qualquer coisa no sistema gerava um aumento considerável na preocupação dos gestores.

Ao contrário do administrador do primeiro lugar a solução da equipe responsável pela TI dessa segunda instituição era menos mão-na-massa: fazíamos reuniões em torno de uma mesa em que eram debatidas as diversas possibilidades e sugeridas possíveis soluções. Alguns achavam que o problema era que a aplicação era lenta, outros que o servidor web estava mal configurado, outros que era falta de banda. Houve quem sugerisse que se substituísse a aplicação web por uma aplicação que rodasse na máquina dos usuários, com acesso direto ao banco de dados, o que supostamente reduziria o uso de banda.

O que há de errado em ambas as histórias? Ninguém nunca havia pensado em coletar dados, medir, saber o que havia de errado para depois atacar o problema. Eles preferiam fazer o pior tipo de tratamento de problemas de desempenho: imaginar qual seria o problema e chutar soluções que pudessem saná-los.

No primeiro caso, logo depois que entramos eu e um colega, a primeira coisa que esse colega fez foi instalar um monitoramento razoavelmente completo de indicadores de desempenho de todo o ambiente de rede com o cacti. Não demorou muito para que nós descobríssemos que o problema do nosso querido servidor de arquivos estava longe de ser banda. A carga de transferência de dados nunca passava dos 30Mbps, o que é muito menos que os 100Mbps que uma única placa de rede comum à época conseguiria de desempenho nominal. Adicionar placas de rede não adiantava absolutamente nada. Nem me lembro exatamente qual era o problema, provavelmente uma soma de fatores que incluíam uma configuração pra lá de absurda do Samba e uma configuração de raid que não fazia sentido, mas isso não vem ao caso. O importante dessa história é que o remédio que estava sendo dado para nosso paciente não ajudava em nada a melhorar a doença que ele tinha ;) .

O segundo caso é um pouco mais triste: depois de algumas semanas tentando brigar com a estrutura burocrática para nos permitir acessar os servidores e saber o que estava acontecendo chegamos a um indicador bastante interessante: a carga média de 1 minuto do servidor de banco de dados estava em torno de 70. A máquina se não me engano tinha somente um processador. A carga média no Linux indica o número de processos que estão na fila para usar o processador ou bloqueados por espera de I/O, em médias de 1, 5 e 15 minutos. Como nós já havíamos investigado (e até tomado o controle) dos servidores de aplicação, nossa investigação sobre qual era o gargalo naquele momento parecia ter chegado a uma conclusão: o banco de dados e/ou o que a aplicação pedia dele precisava de amor e carinho. Acontece que não adiantou nada nós termos descoberto isso: continuamos por mais algumas semanas com todo mundo correndo em círculos como galinhas sem cabeça e sem ninguém com conhecimentos adequados chegar perto de analizar o banco de dados e as consultas feitas, até que finalmente alguém mais de cima decidiu mandar todos os nossos chefes embora e fazer uma intervenção.

Depois de algumas semanas batendo cabeça do mesmo jeito, com mais reuniões inúteis em torno de mesas (mas dessa vez com outros personagens) finalmente conseguimos que alguém com poder de agir nos escutasse e consertasse o banco de dados, embora nossa demanda por melhorias na aplicação (que nossas pesquisas paralelas e sem nenhuma ajuda do DBA indicaram colocar mais peso no banco do que o necessário) tenham caído em ouvidos surdos. As mudanças feitas no banco (otimização de queries, criação de índices e views materializadas, essencialmente, pelo que minha leiguice captou) acabaram dando gás para que o sistema sobrevivesse mais algum tempo sem uma intervenção mais estrutural, que acabamos fazendo quando finalmente assumimos o controle do servidor de banco de dados também, mas essa já é uma história pra outro post de blog.

Problemas de desempenho e otimizações são aquele tipo de coisa em que a pior coisa que você pode fazer é sentar em volta de uma mesa e tentar tirar qual o problema do ar. Agir com soluções de senso comum também só dá certo se você for sortudo. Esse assunto me interessa e por isso estou pensando em fazer alguns posts falando de problemas de desempenho e otimizações prematuras que demonstram que nem sempre o que é intuitivo é a realidade e que mesmo que você tenha uma hipótese bastante plausível é melhor investigar antes de torná-la uma crença. Alguém tem histórias interessantes pra compartilhar? =)

Nota: essa é uma obra de ficção baseada em fatos reais; algumas simplificações foram feitas sem prejuízo do caso em geral