Planet CDOT

February 26, 2017

Mohamed Baig

Scalable System Architecture with Docker, Docker Flow, and Elastic Stack: Backend Services

Fourth part of the scalable architecture series. Make backend services using NodeJS and Mongo

by mbbaig at February 26, 2017 02:33 AM

February 25, 2017

Laily Ajellu

How to Choose the right Algorithm and Compiler Options

Software Optimization Dangers

Software Optimization can make a 10x difference in how fast your code runs, but these optimizations don’t always keep the integrity of your program.

For example,
If you have a program that stores a set of random numbers in an array and then ends:

If you compile with a high optimization flag like -O3 (which says “Optimize even if it’s risky”), the compiler will notice that all you are doing is storing a bunch of numbers and never using them again. Because those values are never accessed again anywhere in the code, the compiler can decide to not even create the random values or the array at all!

In this article, we’ll look at the performance difference between:
  1. multiplication 500 milion times
  2. multiplication x milion times, where x typed in by user on the command line.
  1. Lookup table, that pre-calculates all the possible multiplications at compile time. At run time the value is just looked up.
  2. Lookup table and casting the negative indexes instead of multiplying by -1 (removes a multiplication, therefore theoretically faster)
  3. Lookup table, and casting, but not storing duplicates in the table.

Multiplication at Run Time

Volume Change Example

Real life case: You are listening to music. When you dial the volume up on your laptop, what’s the calculation for that wave’s new frequency? What sound should come out of the speakers?

(The original frequency) X (The current volume)

Let’s set (The current volume) to be a number between 0.0 - 1.0. You can look at it like a percentage out of 100%.

To simulate this, we can use an array of frequencies (integers) instead of feeding in a song:

Some interesting observations:

  • Multiplication at Run Time Algorithm on X86_64 is faster at -O1 and -O2, not -O3, even though -O3 is theoretically supposed to be optimized to use less resources (time and memory).
  • Multiplication at Run Time Algorithm on X86_64 at -O0, -O2, and -O3 consume the least amount of memory. Even though we might guess that -O1 would use less memory than -O0 because it is faster, this did not turn out true.
  • Multiplication at Run Time Algorithm is slowest (8.844 sec) and the fastest algorithm (0.791 sec), depending on the architecture and the optimization flag.

Multiplication at Run Time with Command Line Arg

Instead of defining MAX as a constant that can be swapped out at compile time, we are getting user input and replacing that wherever the value is used.

Some interesting observations:

  • Using a command line argument instead of a constant increases the processing time because it is another task the program must defer to run time.

Lookup Table - Do All Possible Multiplications at Compile Time

Volume Change Example

Looking at the same volume example, we can create a lookup table to access all the values.
In the example below:
  • The lookup table is: multSoundFreqsTable
  • The values are stored in: soundFreqs
  • The user has turned the volume dial to 50% (VOLUME = 0.5)
We can lookup every quotient (soundFreqs[i] *= VOLUME) in the lookup table instead of calculating it at run time.

It might be easy to assume that this lookup table algorithm would run faster, but this is only true in certain conditions. For example, if you examine the table a little ways below, you will find that with -O3 optimization causes the Multiplication at Runtime algorithm to be faster on both X86 and AARCH64!

Lookup Table + Casting

Here, instead of multiplying by -1 twice to turn our random value into an positive-value index, we can use casting. Casting to a unsigned int will always give us positive values. The numbers that were originally negative are indexed starting from the max value of a uint on your system.

Some interesting observations:

  • On both architectures, this algorithm is only second to Multiplication at Run Time Algorithm

Lookup Table + Casting + No Duplicate Storage

Here, we're simply checking if this calculation has been done before. If it has, we just use that value instead of recalculating it.

Some interesting observations:

  • Og compilation is slower than O3 on AARCH64, but faster on X86_64

Table of Run times and Memory Usage

Some General interesting observations:

  • There was not much difference between -O1, 2, 3 or g for either algorithms, but there was a big jump from -O0 to any of the others.
  • In ¾ cases above, using -Og decreased the performance
  • Music usually has a sample rate of 88200 samples/second. If this many samples are being read from the CD onto the computer (44100 samples per second x 2 channels), even our slowest algorithm (44 630 902 frequencies/second) can keep up.

Distribution of Data

What if our samples were distributed differently? Would this affect any algorithm’s performance? First let’s look at some definitions:
  1. Normally Distributed Data: The mean and median in the set of numbers will be the same or similar
  2. Standard Deviation: How far individual observations differ from the mean

Realistically - More Clustered Values

The distribution of the data was random in all three of our algorithms, because we were generating random values with rand(). But if we were analyzing real music, the distribution of data would probably be normal, ie. they would be closer to each other, and at more consistent intervals. If we could narrow the frequencies used in the song to a smaller range, we would only have to do a fraction of the calculation.

In our example:
  1. Our range of values would be smaller than - 32768 to + 32767 (eg. - 20000 to + 20000)
  2. Our lookup table would be smaller
Therefore, only the Lookup Table Algorithm would be affected by differently distributed data.

Only Negative or Positive Values

If the range of values was from 0 to +32767, we could remove our logic for adding the sign to the value after it’s been looked up in the table, decreasing run time.


You never really know what algorithm or optimization flag will result in faster code, or code that uses less memory until you test it!

by Laily Ajellu ( at February 25, 2017 10:54 PM

Peiying Yang

Fixing bug on brackets


This regression is from my previous bug fixed

The toggle can remember UI setting, but it doesn’t actually disable javaScript.

We can play the bug by doing this steps:

  • Open up Bramble in a browser
  • Add somewhere in the tag of the index.html file and watch it pop up an alert every time you hit Enter in your editor
  • Open your dev console and type in bramble.disableJavaScript(). Now, every time you press Enter in your editor, you won’t get the alert.
  • Refresh the page and the alert pops up again and every time you hit Enter in the editor, it will alert.
  • Inspect localstorage for the bramble-property::allowJavaScript and you’ll see that it is false. But the editor clearly does not honor that.

Analyze this issue

When we click on the toggle, it sets the UI, and it disables/enables javaScript.

However, when we load it, it only sets the UI without disables/disables javaScript.

We can call the disableScrpt() or enableScript() function when the brackets is loading.

by pyang16 at February 25, 2017 07:39 PM

Adding feature for thimble


In this issue, they want to add a feature to allow users editing svg file instead of showing a preview.097d6f28-f42d-11e6-95fd-c60da32f8908.png

Analyze this issue

There is a function called findSuitableEditor(), it loops for all editors and returns one suitable editor. We can hack an imageView and let a canOpenFile() function return false when the users want to edit the svg file instead of viewing it.

by pyang16 at February 25, 2017 07:28 PM

John James

OSD Lab5

The lab in OSD last week, was to pick a bug. Since my previous bug was a simple css fix, and not very challenging. I thought I would try to wet my feet in a javascript bug. This bug though, I found very interesting. If the user was running thimble on their computers locally, they could not reload the changes they made without restarting the server.

For example:


After looking through other git issues, this one kept coming back to me and I decided to try this challenge. I don’t have a lot of experience with javascript, only working with it a little bit in INT222 so I thought this was a good bug for the second project. I wanted to pick a second bug, but I decided it would be better if I fixed this bug first, then picked another one.

by johnjamesa70 at February 25, 2017 02:13 AM

February 24, 2017

Henrique Coelho

Test cases, UI for affinity tool, and putting things together - A quick update

This is going to be just a quick update about the progress of our current project, since I don't really have any big news about it.

For the past weeks, I have been working on revamping our test suites: making sure they are still passing, making new tests for new functions that were not previously tested, and build test cases for the frontend (as described in my previous post: Making a test suite for the front-end client). No big news here, it is all working nicely!

I also made another query (an interface...) for getting information about user affinities (which I explained in this post: User Affinity Tool: grouping and finding patterns for users). Now people who are using Rutilus can have a nice interface for querying users based on their affinities. For example: getting all the emails of users who seem to be engineers.

And finally, I was also working on modularizing our project: the modules now seem to be working properly (based on the results we got from our test suites), so I made a new version of Rutilus for our industry partner using the modules we built (instead of the monolithic application we had before). Soon enough, we will deploy this new version for them.

by Henrique Salvadori Coelho at February 24, 2017 06:24 PM

Matt Welke

Matt’s Docker Orchestration 1.0


My ECS (EC2 Container Service) alternative is complete. 🙂

I ended up creating the server portion of the AWS tutorial using a very simple sort of manual Docker orchestration. Long story short, run your Docker containers with “–restart always”. This tells the Docker daemon to automatically restart the containers in the event of a crash, and (and this is key), it tells the Docker daemon to automatically start the containers when the daemon itself is started by the operating system. And when does that happen? At boot.

So with that one little switch added to your “docker run” command, you’ve got something that will just keep going, and going…


To make things simple for the users, we provide a script that runs the Docker commands appropriately. The user never has to actually enter a Docker command to set up Rutilus on AWS. They create the instance through the website, SSH in, and run my setup script, which finishes setting up the instance, installs Docker, pulls from our Git repo, builds the Docker images using the latest NPM modules for the Rutilus modules, and runs the Docker containers.

And for our purposes for Rutilus, at least in the scope of’s implementation of it, it works. It can’t scale (it just restarts the containers, it doesn’t launch more than one of them). It can’t do fancy things like sending one container to one EC2 instance and another container to another, like ECS can. But doesn’t need something so massively scalable. We don’t need to get tons of AWS permissions to encompass the ECS service, just EC2 permissions are fine. And telling them how to maintain it is as simple as “If you want to stop it, just SSH in and run ‘docker stop’. Run the tutorial’s massive script that sets it up for you again to start it up again.”

Of course the process of getting to this wasn’t as simple as the end solution. I had to experiment with startup scripts (I originally thought –restart always didn’t take care of everything we needed) and permissions, and making my start up script I thought I needed executable, and worrying about whether or not the future versions of the AMI would support the startup method I chose… But I’m happy I went through that process. It ends up simplifying our project and making it less tightly coupled to AWS. In theory, because this just pure Docker, the open source community can host our app with that setup script from the tutorial on any IaaS cloud host.

by Matt at February 24, 2017 04:41 PM

Kevin Ramsamujh

OSD600 Lab 5: Preparation for release 0.2

For my second release in Mozilla Thimble, I chose to work on a couple bugs that are related to the projects list which I worked with on my first release. The first issue is providing a link to projects that are already published in the projects list (#1626). The second issue is to provide an option for the user to remix a project straight from the project page (#1766). Both of these issues should deal with the same project and project-list files that I needed to edit before in my first release which I expect will help me get started on these issues.

Some things that I will have to look into that aren’t the same as my first release include: learning how publishing projects works and how they are stored and also learning about remixing a project and how that is handled. The rest of the issue should just be refining the UI and figuring out where to put these links and/or buttons. I am hoping my previous experience with my first release will help with the styling needed for these new issues but I expect that I am going to need some guidance to refine it all in the end.

by kramsamujh at February 24, 2017 01:23 PM

Margaryta Chepiga

Preparing for Release 0.2 in Mozilla Thimble

Here is a time for a second bug fix for Mozilla!

Our Professor provided us with links where we could find an existing bug. Here is a list of them, in case someone is interested:

I browsed trough most of them. To be honest picking a bug is not a simplest thing. I found one that I might be interested in, but I wasn’t sure. I had a lot of doubts. I wasn’t sure that I could handle it. So I asked for some advise from my Professor. That’s how I ended up picking this one.

Users can’t upload files with the size bigger than 3MB, which is great if we are talking about images. However, user should have an opportunity to add a zip file which is bigger than 3MB.

Screenshot from 2017-02-24 00-39-28.png

On the image above, I tried to recreate the issue. It was an easy thing to do. By the way the idea of adding the zip file inside the thimble is amazing. Here you can read a bit more about it.

So we have a bug, we reproduced it. What’s next? My next step is to find as much information as possible. Which parts of the code it affects?

Mozilla Brackets repository had a file named DragAndDrop.js which is apparently responsible for this specific issue.

So what should I do and how can I fix it?

Well, I know with which file I need to work with. I know that there is a specific size (which is 3 MB). And I know that I don’t want to change the size. Since, I want to make a change specifically for a zip files. Which leads me to the idea of checking for a type when user is trying to upload something on thimble. If it is not a zip file and the size is bigger than 3 MB, then I shouldn’t let to upload it. However, if it is a zip file what size should be allowed for a user to add? If 3 MB is not enough, than what size is enough?

That the question I need to find answer for as well as fixing the issue. I am excited and with my new knowledge from previous mistakes I could came up with solution efficiently.

by mchepigaosd600 at February 24, 2017 06:19 AM

Contribution to Mozilla Project

So what happens after finding a bug and setting up the environment ?

Then you need to find the ways to fix it. However, in order to fix any bug, you need to understand the problem and the code.

In order to understand the code I followed my Professor recommendations. Which are the following:

  • I read the manual.
  • Bottom-Up: I looked at the code, directory structure, scanned for files and directory names that related to my specific issue.

And for my case that was enough. The next step for me was to understand the problem and solution.

In my situation the problem was clear as well as the solution, which I should thank for the Mozilla Developers for, since they were the one who clearly stated both the problem and the solution. So I knew the problem and I knew theoretically how to fix it.

The bug itself was about tutorial file. To be more specific, after a user remover a tutorial they couldn’t add the tutorial right away. In order to do that they needed to reload the page.

So I just tried to fix it. However no matter what I did, it wasn’t reflected on the web page when I run the localhost. I am not a person who easily give ups, so I have tried to fix a bug for two days. The result was the same. So on the third day of trying, I decided to break the program. I commented out the whole file which I was working on. Then I restarted the servers and run the localhost which gave me the result of nothing. Literally. Everything runs and works just perfectly, like I didn’t commented out the file which is responsible for application to work. It was expected to fail, but it didn’t. Then I start wondering. Why? What is the reason of this situation to occur? Did I set up the environment properly? Am I working on the right file? What I am doing wrong? I was confused. I didn’t know what to do. So I asked for a help. Mozilla community and my Professor were extremely helpful. However it still took me a couple of days to fix the problem. I got all of the updates from both brackets and thimble. Destroyed virtual machine. Made all of the necessary changes and that’s it. The bug is fixed.

screenshot-from-2017-02-23-19-37-02 screenshot-from-2017-02-23-19-37-10 screenshot-from-2017-02-23-19-37-17


After fixing the bug. I added the file, committed it and pushing it. I send a pull request.

Which you can find here.

It was an amazing experience for me. I struggled a lot. Made a lot of mistakes. I was out of time. But it was great. I did it, not by myself but I did it. I am extremely grateful for all the help and patience I got from the Mozilla Contributors and even bigger thank you to my Professor, who didn’t gave up on me.





























by mchepigaosd600 at February 24, 2017 05:08 AM

Timothy Moy

OSD Lab 5: My Second Bug

Small Update on Previous Bug

At the time of writing, I am almost finished with fixing my first bug and having the pull requests merged. David, Luke and Gideon were very supportive and gave me a lot of constructive feedback in the process. I will post an update soon with the process of how the fix was implemented and issues encountered.

You can also view the pull requests here and here.

So, What’s this about a New Bug?

For the second bug I have chosen, it is adding Instagram filter support to Thimble. This is a different type of bug since I am not fixing anything, but adding a new feature to the existing client. This means it isn’t really a bug I need to spend time to reproduce, but one where figuring out implementation becomes the bulk of the overhead.

The proposed solution is to use CSSGram and somehow implement it into the selfie taker. The library itself needs to be added to this folder in brackets and several files will need to be changed so that the selfie taker allows the user to select optional filters. I believe that the changes that will be made only affect the files in the folder I linked above and possibly lower in existing sub directories.

I’m pretty sure that I will end up playing around a lot to figure out how the code works together to form the selfie-taker and might have to ask questions about it. I will also most likely have questions about layout design as well.

Lastly, you might wonder why I chose this particular bug. To answer that, it is similar to an idea that was brought up by David to integrate piskel into thimble. Although it is a deeper dive than correcting code, the parallel of the two ideas should help with establishing a conceptual idea of how to approach this type of issue.


by Timothy Moy at February 24, 2017 04:35 AM

Andrew Smith

DYI cheap stand-up desk

Standing in front of my new stand-up desk I’m experiencing an unexpected sense of freedom.

I wanted to try a stand-up desk for years. Several people I know recommended them but the problem is: my desk is huge, it’s well organized, and I didn’t want to spend hundreds or thousands of dollars on something I may or may not like.

I spend many hours a day in front of my computer and my posture sucks, always did. I would love to do anything I can to improve my posture, but I didn’t know whether I could physically handle standing in front of a desk for so long.

Need a cheap experiment! Good thing I have a workshop and some left-over MDF.

Figuring out the correct height of the stand-up desk was very hard. I found some advice on the internet telling me to have the desk just under my elbows. Better lower than higher the guy said. Made sense.

My huge L-shaped desk has three legs, so I built three boxes to raise each leg by 40 cm. The MDF was free and it’s not the best looking thing but glued into a box it’s strong enough. My computer and power bar had to be raised together with the desk so a couple of the boxes are wider than they would need to be for the desk alone. The boxes measure:

  • 65 cm deep (legs are 60 cm)
  • 25, 35, and 35 cm wide
  • 40 cm high

And they were assembled like this:

And this is the result:

The 25-cm-wide one looks tippy, but it’s quite stable. I’m not worried about this falling down.

Close-up on the finished box in place:

I just started using it so I can’t comment on how well it’s going to work long-term. But it only took me a couple of hours of work to build and it looks better than I expected. So I’m already happy about this project whether I will end up keeping the setup or not.

by Andrew Smith at February 24, 2017 04:12 AM

Dmytro Sych

Preparing for Release 0.2 in Mozilla Thimble

My first release for Mozilla’s Thimble taught me some invaluable aspects about Open Source contribution. Having experienced the whole pipe line of meaningful contribution to a large project, surfaced multiple crucial points of how to approach code examination.

My intention for the second release is to deeper my understanding of the back-end part of the system by working on introduction of a new feature. My issue talks about restricting user project size.

During the discussion on how this feature is supposed to be realized in the final product, it has become clear that I’ll have to implement a whole new module to Bramble. Have to admit, at first, I felt that I was over my head. However, examination of other Bramble modules has relieved the initial panic. It seems like, this module will need to trigger some kind of event on Bramble based on the current project state. Moreover, I have presumably located a bottle neck function that adds files to a project. My guess is I will invoke my module in that function to preform the check.

This is more or less everything I know right now of which I am at least partially confident. Hopefully, I’ll be able to proceed further.=)

by dsych at February 24, 2017 02:23 AM

Xiao Lei Huang

DPS909 LAB 5

I have chosen an issue that was brought up over a year ago that would be a nice feature if it existed. Today I am writing about this issue and try to describe how I will attempt to fix this problem. My Issue requires me to build onto existing code oppose to what I did for my first fix which was to change what other developers did in the past. Here is the link to the issue.

I have looked into the problem and have come up with a game plan as well as to follow what the experienced developers had to say. I have created a new function that returns the current size of the available hints on the editor depending on the cursor placement. I have added this functionality to Main.js under java in brackets as well as in the RemoteExecutionHandler. After successfully establishing a communication with a thimble, I have noticed that if I wanted to return an array of objects after I call it in thimble from brackets I would need to do something a little different. I have found the global setters and getters inside Main.js that are in charge of sending back information to thimble but have hit a road block because i don’t understand how the code pulls the current state info from that current module. I am currently unable to locate the main.js under client from the inspector on chrome so I cannot find out exactly how they receive that information.

After I establish a successful return back to the thimble, my plan is to then move onto the next step.

by dps909blog at February 24, 2017 02:16 AM

February 23, 2017

Andrey Bykin

Release 0.2 bug fixes

For the 2.0 release I decided to take an issue regarding weird behavior with right click menu on firefox on a mac.

The link to the issue can be found here :

I think this issue will help me get more familiar with the way thimble and bracket interact and will help me explore more of the options on how to figure out an issue within the open source project.

Since this issue may be somewhat small depending on its fix, I will most likely end up grabbing another one once this is all figured out. The next issue I want to tackle, I want it to have more of a complicated fix as in more coding challenge rather than a small condition check.

One small issue I may run into is the problem being only persisted on one operating system. I do own a mac and my first task will be trying to replicate the issue, however I may need to switch gears depending whether or not this issue is able to be replicated on same system/ different system.

I will update on my findings and the next issue that I find on later blog posts.



by Andrey Bykin at February 23, 2017 11:17 PM

Tony Park

About the bug I will work on for release 0.2 is about white space indicators

Actually, it is not a bug if you work individually; however, it allows developers to work more conveniently if there are white space indicatiors such as “.” instead of ” ” by default.


For your information, there is the code extension already implemented in 2015 by DennisKehrig, so what I can do simply is adapt the extension to git project and test it.

In order to fix this bug I plan on following the suggestion given by Dave mentioned below

Since this version of DennisKehrig has a problem that affect the performance of thimble negatively, I am going to look into the code that I will decide better way for white space indicator.

By the way, I have a problem when I add the extended feature to the default directory so I am stuck on this error.

Here is detail information of this bug.

by tonypark0403 at February 23, 2017 09:27 PM

Oleg Mytryniuk

Lab 5. Release 0.2. We are ready to go

Here is the next challenge. After we have published our first release, it is time to start working on the version 0.2.

To be honest, after the first release, I feel more confident, and I started enjoying the process of contribution a lot.

For the new release, I have chosen two issues:

  1. Update node dependencies.

According to the task, I am supposed to check the versions of dependencies in package.json file and to see whether they have any updates.

Why particularly this bug?

I decided to work on it, because it is something different from what I did before (worked on JS), and I would like to learn a little bit more about package.json. I do not have a lot of experience with JS, but what I know that if we are going to create our full-stack project, we must to define all dependencies, and in terms of it, package.json becomes a core of our project.

  1. Project title isn’t displayed when you work anonymously.

Fixing the bug with a project title. When you create or work on your project on Thimble, you see the title of the project at the top of the page. It seems to display the title, when you are logged in, but if you work anonymously , the title is not displayed.


Why I have chosen the bug?  There are a few reasons:

– I like such type of bugs(logic bugs/not design). I prefer to work using JS other than CSS, for example.

– I have worked on Thimble for my previous release, and I feel like it is easier for me to figure out the issue since I have already some knowledges about how the code works.


Talking about the progress, I have already started to work on the second bug. I was able to reproduce it. Luckily, I have two Virtual Machines (the first one runs the old version of Thimble and another – the newest one) and I think it will help me to figure out it faster where the issue happens. However, in my opinion the bug existed before the group started to contribute, I just guess – nobody noticed this issue before, because everybody is supposed to be logged-in.

So far, I do not have any questions; however there are many places where I can ask for clarification/help, including the project community. Last time it helped me a lot, and I already got some help for my 2nd release as well. I am so excited!


At the same time, I am sure, that next time I will work on something different. Right now, I am contributing, basically, to Thimble and I would like to contribute to other projects as well. Brackets or Bramble? Why not? 🙂 Is not cool to have in your resume contribution to such “monsters” as Mozilla or Adobe. It is my last semester and I am so glad to have this course. It makes me more confident in programming and I can significantly “boost” my resume for job-hunting.


In conclusion, I would love to work on the bugs I have chosen and I feel confident that I will be able to solve the issues and to make one more small, but important contribution to Mozilla. WE SHOULD SUPPORT OPEN-SOURCE COMMUNITY!  🙂


by osd600mytryniuk at February 23, 2017 07:46 PM

Theo D

Blog Post 6 – Release 0.2 Choice (Lab5)

This week we were asked to choose another bug(s) to fix and tackle on! I decided to do two bugs this time because the FIRST was one I tried to fix before and I really wanted to finally get it working, while the SECOND I chose simply because I related with the very small bug.

The PHP visual bug (second bug), I know how important it is to stay connected with what you code, and having your code stand out properly can make a night day difference. From context, this bug will be a modification of a styling within a CSS file or  might even be inline coded. This will be interesting to narrow down but also easy to fix once isolated. Communication with Flukeout will be key to properly choosing the ideal color/boldness.

As for the first bug, I just want to see this bug squashed. It’s bugs like these that are taken for granted because the can make all the difference for people that are on a deadline or for those that get inspired and need to be where they last left off or to quickly know the file they are currently on. So far I managed to narrow down part of the code in a sidebar.css  but will most likely have to modify some inline styling to overwrite what the dynamic page changes.


I thought I had it at first, but Flukeout pointed out that when a second file is edited in the IDE, it loses track of which file is opened.


Hopefully the above problem can be squashed along the road of my journey!

I’m curious how scattered some of these problems can be even though they are isolated in the same visual area. I’m looking forward to narrowing down all the pathways, and seeing if fixing these bugs have the potential to either fix other bugs that weren’t listed or possibly even introduce others that weren’t as easy to spot before.


by theoduleblog at February 23, 2017 02:02 AM

Matt Welke

Docker Orchestration Lite Edition

As I create the documentation for Rutilus, the next area I’m focusing on is the tutorial. This is the area that is supposed to be extremely simple, that can get a newbie up and running very quickly. Of course it isn’t useful unless it’s hosted in the cloud. So the tutorial will be on how to get Rutilus hosted on a cloud provider as quickly and simply and possible.

Why not Heroku?

My first thought when I consider a simple, quick cloud solution is Heroku. I’m still in love with the process of deploying onto it:

  • git push heroku master
  • …that’s it

Compared to AWS, it’s a dream. And I thought that since Node.js allows you to use just one process to run multiple applications, we could get away with using one Heroku dyno to run every module. We can’t get a file system on Heroku, but they do have the mLab service which offers Mongo as a service with 500 MB for free. Free Heroku dyno plus free Mongo service… bingo! This could be something that people can get running super quickly and for free too.

Then the problems start happening. 🙂

Heroku only exposes one port. They give it to you internally as an environment variable (and it could be anything) but luckily it always maps to port 80 externally. But it’s still just one port. Rutilus needs a port for the WebSockets connection to the Logger, and at least one port for the Analytics module, which is used for HTTP, to serve up the dashboard and to serve up JSON user profiles/personas etc. Heroku just doesn’t work for this. It could if we used multiple dynos, but now people have to spin up at least two dynos. This starts at $7/month. This means that someone can’t just get started for free. The one free dyno you get and the $7/month “Hobby” dynos are also limited to 500 MB of memory, and we know from testing that the Analytics module in particular can eat up more than that on a big CSV export.

So that brought us back to AWS. The free tier gives you a 1 GB RAM instance for free for one year. And we already used their ECS (EC2 Container Service) to host all the prototype Rutilus modules on individual Docker containers on one instance. I began my quest to recreate that ECS setup with the new open source Rutilus modules. I ran into trouble though, and even after bugging my team mate for help, who definitely is more experienced with Docker and ECS than I was, we both got puzzled by the ceremony involved in setting it up, and the unexpected behavior. It really, really isn’t user friendly for beginners. And there’s no script code you can just run and forget about. It’s a lot of GUI ceremony.

After stumbling across a blog post online that informed me of the –restart switch of the “docker run” command, I had a eureka moment. Docker itself has the ability to manage itself. The pieces are there if you put them together. The “docker run” command is used to start a Docker container. Unfortunately, containers can crash because your application’s process can crash. EC2 manages this if you can get it setup. But the restart switch does too. “docker run –restart on-failure …” will run the container and keep an eye on it to restart it if it crashes. This is perfect! It’s exactly what we need! Now if AWS itself goes down, we need this docker command itself to run automatically when the instance boots back up. Again, ECS handles this. But there’s nothing stopping us from creating a bootup script to do this too. We have the knowledge by now to create our own very basic very simple Docker orchestration tool.

Normally, I’m the type to prefer to use an existing tool. It makes sense to me to delegate the work to someone I know is an expert in it. But in this situation, using that existing tool has proved to be so difficult that rollin our own solution, as long as we test it and know what we’re doing, is definitely the better option. We’ll understand it. And from our user’s perspective, setting up the AWS Rutilus bundle will consist of creating an EC2 instance (which is much, much easier than setting up ECS) and then they’re free from AWS’s GUI. They run our script, which pulls the Dockerfiles from the open source Git repos, builds the Docker images, and creates a startup script with the commands that will run those Docker images as containers that will indeed be restarted in the event of crashing. Create the EC2 instance. Run our script. Done.

I’m in the process of re-creating a Rutilus implementation on AWS using this new method to make sure it’s solid, and so far I’m having a lot of success. Once I finish testing all the modules, I will begin making the tutorial. Our goal is that the tutorial is completely ready by the beginning of March. Our team lead, for whom Rutilus is a black box, will be our guinea pig. He will attempt to set it up and we’ll see how easy this thing is to set up from the perspective of someone unfamiliar with the finer details of its development.

by Matt at February 23, 2017 01:03 AM

Len Isac

More Thimble bugs to work on (for Release 0.2)

The bugs I will be working on for my second Release (0.2) are both related to a previous issue I contributed to. I wrote a blog about it here.

The first one (Issue #1738) involves fixing the event’s callback parameters. The second (Issue #240) is to have the renamed project fully published and actually update on S3. (Amazon S3 is a simple storage service that Thimble stores its projects on).

I will continue with this post once I have finished working on these bugs.

by Len Isac at February 23, 2017 01:02 AM

February 22, 2017

Christopher Singh

Lab 5 – OSD600

This blog is late, but for completion sake and since I have the time right now, I’ll publish this.

The issues I chose were:

The first issue was one I finished early, back in Release 0.1. I had time and the issue looked simple, which it was.

For issue #1333, the problem was simple. The publish URL link in the “Publish Dialog” box, when clicked, launched your published project’s webpage in a new tab. Great. However, when you return to the Thimble tab, the “Publish Dialog” box was still open. This issue fell under design — it was not necessarily a bug. I knew what I needed to do was find the corresponding <a> tag, and create a click event for that to close the dialog box, of which there obviously was a function for since I could mimic this behaviour.

Issue #1755 was also simple, and it had to do with design. We wanted to include the project descriptions (if they had one) under the project titles on the “My Projects” page. What I knew I’d be working with was the corresponding HTML file, and the CSS file. I would have to add a div or a span to store the description in, and in the CSS try my best to style it. I would need guidance on how the issue creator wanted it to look like.

by cgsingh at February 22, 2017 11:47 PM

Wayne Williams

David Humphrey

What Happens when you Contribute

I'm doing some marking today, and one of the labs I gave my students was to contribute a pull request to a node.js module project on GitHub. None of the students knew node.js or had used GitHub before, so I wrote extensively about it here, with detailed instructions to show them how to do it.

A month has passed, so I went back to look at what happened to these PRs. I was interested to see what actually happens in the node community when you throw total beginners at it. I wanted to understand how contributions and contributors are received, how maintainers respond, how long it takes to get a response, etc.

Here are some examples of the PRs the students did, listed by module name:

I left it up to the students which projects to work on, and as you can see, lots of popular node modules have minor issues. So my first conclusion is that it is indeed possible to find lots of first contribution opportunities by focusing on package.json warnings.

Now some numbers:

  • PRs merged: 32%
  • PRs closed or rejected: 43%
  • PRs still open 1 month later: 25%

I found this fascinating. First, I was surprised that only 1/3rd of the students could get their code landed. When I made this lab, I thought the changes were non-controversial and easy wins. Second, I was interested that so many projects just ignored PRs or let them languish. Lots of people in the node community that I hear talking loudly about welcoming newcomers and helping people get started in open source seemed to be absent when it came to responding to real PRs.

If we dig into some of the PRs, there are other interesting things to unpack. I was pleased to see a bunch of maintainers and reviewers taking the time to not only merge the code, but also respond on a human level, saying things like:

"Nice, thank you very much"

"+1, good catch!"

"Congrats on opening your first pull request on GitHub!"

An equal number of people just merged without comment. It's ridiculously easy to add a short message when you merge a PR, and people would do well to add more love to their use of GitHub. It was clear from student blog posts afterward how much a simple "thank" you could do, for example, Maya wrote a great post on her experience:


This has dispelled one of my worries that the moment I start contributing online, I would immediately be shut down. Obviously this is the reality working and contributing to projects online.

But that first friendly interaction from a stranger whose repo I contributed to was a great welcome to the Open Source world.

I saw a lot of the opposite, though: "Our code is fine, closing". I couldn't believe the number of reviewers who got lost in pedantic arguments about whether something is right or wrong, what the point of things like keywords are, etc.

A great example of this is the repository field, which should probably be a full URL even though you can use syntax like GitHub shorthand like npm/npm. I was surprised how many maintainers completely missed the chance to engage a new contributor and take a suggested change (even if not 100% necessary), or went beyond this and took the opportunity to lecture on why the change was wrong. In my experience, needing to be right often leads to being alone. If you're going to close a PR in your project, consider inviting the contributor to work on another similar issue, or help them craft a new version of the fix that could work. Dropping them along with the PR is shortsighted.

As you would guess, I saw lots of formatting mistakes with indenting, tabs vs. spaces, etc. Most students are on Windows, haven't contributed to any open source before, and don't know you're not supposed to use tabs, need 2-spaces, 4-spaces, etc. Some reviewers were patient with this, and helped walk people through fixing things; others weren't. If you see people making indentation errors, it's almost surely a sign that you're dealing with someone new, someone who could use extra attention or mentoring. Maintainers would do well to tailor their feedback based on the presence of such mistakes, which are a great indicator of the experience level of the contributor. No one is putting tabs in their code to annoy you! It's a lack of experience.

A bunch of students ran into bots wanting CLAs signed (13% of PRs), which stopped a lot of students from going further. "Why am I being asked to sign something?" Only 1 of my students signed a CLA. It definitely ended a lot of contributions.

It wasn't all negative, though, and I was encouraged by the behaviour of a few maintainers/reviewers, and wanted to call it out. While others in the community missed the chance to be welcoming and helpful, these people seemed to get it, and I was thankful my students encountered them:

dougwilson who thanked the student for the effort and helped dig into the upstream problem of the package.json validator giving incorrect info on repository fields not being URLs. Open source is at its best when it tries to connect people to solutions beyond the boundaries of particular projects/repos.

danez for responding quickly and being thankful.

DonutEspresso for being positive, and also taking the time to let the student know that they have work to do here (humility).

Overall I think that the experience was useful for the students, because it was real. Even when it didn't work out perfectly, students got to build their skills and confidence. I think Margaryta put it well in her blog post about the experience:

"I was afraid even to try...(But after doing it) I am not afraid to make a contribution to the Open Source community."

I also think the node community could do more to prepare itself to engage with first time contributors. Open source is about code, open source is about process. But open source is also, and always about people. As experienced open source contributors, we tend to forget what it's like to begin, and get lost in the work itself, leaning on unwritten process and practices. All of us need to take more time to help new people we encounter in issues and pull requests. Small moments of kindness, helpfulness, and encouragement go a long way. We should be putting as much time (or more!) into being kind in issues/PRS as we do into fixing linting errors and increasing code coverage.

by David Humphrey at February 22, 2017 05:45 PM

Kert Browne

Term 2 – Week 7

This week I was working on centering the buttons on the actions bar. The visual design of the button placement was decided on to try and keep the buttons on the page a symmetrical with the rest of the app as possible.

There are different scenarios where 2, 3 or more buttons may be visible at a time. The currently implemented solution rendered all the available buttons and then uses css to hide them via the visibility property. Tho the buttons were visibly hidden, the flex box containing them treated them as if they were there, giving the appearance of the buttons not being centered. The benefit here was that the buttons remained in a fixed position.

As an alternative, we can create a service function to return the Boolean variable representing if the user currently has a mic connected. This service is then called in the button container, mute in this case. followed with a simple if condition in the mute component render method.

   return null;

For the rest of the week I have been doing research into the NVDA Screen reader and testing its current functionality with the BBB HTML5 client. Currently non of the NVDA keyboard keys are implemented. For example, if a user presses “B” while NVDA is open it should return the next button available on the page.

There is also a great deal of unexpected behavior from the screen reader itself. From my preliminary research, the biggest hurdle is that screen readers dont generally do well with content being dynamically added to the document model.

In terms of keyboard accessibility, the BBB HTML5 application seems to have most elements sharing a global tab index except for the modals. This can cause a somewhat unpleasant “tabbing” experience when using the chat and navigating certain menus.

the following is a link to the NVDA keyboard commands, user and developer guide:

Keyboard Commands


User Guide

by kdsbrowne at February 22, 2017 12:56 AM

February 21, 2017

Matt Welke

Practicing What I Preach

Documentation is progressing well. By now, I’ve moved on to documenting using the AWS bundle, which is a prepared collection of configuration meant for people to use Docker to set up all of their server side modules and to have that all run on one AWS instance. This mirrors the way we implemented our creation for We’re providing this bundle because we think it will appeal to those who are comfortable with AWS and Docker, and who want a quicker way to get up and running. It also serves as an example to our users how one can arrange a Rutilus deployment. We found our method effective, and we want to share that with the world.

Documenting this means revisiting our prototype that we built for in order to better understand the code and the deployment process. A huge theme I’ve noticed with this documentation part of the project has been revisiting the work done to review it, and ultimately learning it much more thoroughly because of that. I’ve reminded myself how Docker works, how environment variables work (don’t laugh…), how Bash scripting is done. I’ve worked on my English, noticing minor inefficiencies in what I say in my documentation. It’s been a great opportunity to solidify everything I’ve started learning when it comes to being a software developer.

It also made me test what we’ve created. When I create a great paragraph of documentation, with clear instructions and code examples, I don’t trust it until I know it works. So I pretend I’m the user and I do exactly what I told them to do. Sometimes everything works as intended, and sometimes it makes me realize I was forgetting about something important.

A good example is our new unified “config object”, where one JavaScript object literal is used to configure every module they intend to use. There were little problems with pieces of data (ex. a MongoDB connection string) not being formatted perfectly for one module, when working in another.

Another example is our Bash script for deploying to AWS. It reads well as I review it… looks good to me… uses Docker to build Docker images and deploy them. But wait… We were using Docker without sudo. Oh yeah, that’s because we chose the more liberal choice of allowing Docker more access to our machine than is needed. According to the Docker documentation, users who do that should take heed of the security risks. And to be honest, it may not even be a big deal… But things like this stand out to me. I want to err on the side of caution and create a deployment script that all users will feel comfortable using, even those who take their security very seriously.

I have two planned tutorials (one for AWS and one for Heroku) designed to guide users through every detail of getting up and running, no matter how inexperienced they are. I plan to continue this “test as I go” approach as I build the these tutorials to make sure the users are well-equipped when they use the software.

by Matt at February 21, 2017 03:24 PM

February 20, 2017

Badr Modoukh

DPS909 Lab 5 – Preparing for Release 0.2 in Mozilla Brackets

For release 0.2, I decided to chose issues based on the brackets repository rather than Thimble. The issues I choose are:

  1. Remove or Update issue template #593
  2. Update node deps #589

These issues are fairly simple to fix. They do not involve modifying code but rather focus on documentation. I believe having proper and up to date documentation is important in open source projects. This makes it easier for contributors to find the information they need.

The first issue “Remove or Update issue template #593” was an issue filed by humphd. The issue is that when the Brackets repository got merged with the Adobe Brackets repository a file named “” got merged into the repository. The purpose of this file is to provide the user with a template they can use when they want to file an issue they faced with Brackets. Since Mozilla Brackets has different features and requirements than Adobe Brackets, the template needs to be updated to fit with Mozilla Brackets.

Initially there were two options we could take to fix this issue, remove the file completely from the repository or modify the file to fit with Mozilla Brackets. I found the second option better because every repository should have an issue template for users to use and it makes filing an issue easier and more manageable.

humphd suggested some ideas on what information to modify in the file. They are:

  • Get rid of the Prerequisites section
  • Keep the section on Steps to Reproduce, Expected and Actual behaviour
  • Change the Versions section to be about which Browser (name and version) and OS the user is using

I plan on modifying the file by using these suggestions and making sure the formatting of the file is clear for the user to understand.

The second issue I chose is “Update node deps #589”, which was also created by humphd. The issue is that the dependencies and devDependencies in the package.json file needed to be updated. It is important to update the package.json file so that the users know the versions of the dependencies that are used my Brackets.

In order to fix this bug I plan on following the suggestion given by humphd. Which is to examine the dependencies and devDependencies in the package.json file and see which one’s we are using that need to be updated. The professor suggested using a tool to accomplish this task such as npm-check. This tool is used for checking outdated, incorrect, and unused dependencies. Using this tool can make the process of checking each dependency easier. After I find which dependencies need to be updated I plan on changing the package.json file to fit with the updated dependencies and devDependencies.

by badrmodoukh at February 20, 2017 02:39 AM

February 19, 2017

John James

SPO Lab 6 (Vectorization)

In this lab, we had to make a simple program that randomly generated numbers for two 1000 size array, and then get the total sum of those Arrays.

Test Code:

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

#define size 1000
int main(){
int num[size], num2[size], num3[size]
long int arrSum = 0;
for(int i = 0; i < size; i++){
num[i] = rand();
num2[i] = rand();
num3[i] = num[i] + num2[i];
arrSum += num3[i];

printf(“Final Sum of the two arrays: %ld \n”, arrSum);
return 0;


Command lines to Compile code

: c99 -o Lab6.c


Final Sum of the two arrays: 59113227920


To obtain the disassembly code, I used the command objdump -d a.out


Screenshot from 2017-02-19 00-03-56.png

Reflection from the lab

I think overall this lab showed the importance of Vector and how it can increase provide better performance overall and why we could use vectorization in loops.

by johnjamesa70 at February 19, 2017 05:11 AM

Matthew Bell

SPO600 - Lab 5 - Algorithm Selection Lab

For this lab we were required to write a program to multiply a large set of 16-bit signed integers by one floating point value, between 0.0 and 1.0. This simulates how volume scaling works, and it was used to show how the code we write is optimized by the compiler, and also how you can format your code for the compiler to better optimize it.

The lab itself asked us to write two separate implementations, a naive implementation, and a potentially more optimized solution, where we chose to write one using a lookup table. To assist us with our benchmarking,  we created a struct called "Result", and it looks something like this:

struct Result{
        double elapsed, elapsed_middle;
        struct timeval time_start,time_end;
        double sum;

Our naive implementation was about as efficient as expected, taking 2768ms to process a set of 500,000,000 pseudo-random data (from /dev/urandom, and using gcc's -O3 flag). Whereas our custom implementation takes 1852ms. That's a difference of 916ms, or a 33% increase in speed. When compiling without any optimizations, our naive function takes 18080ms, whereas our custom one takes 11756ms, or an improvement of 6324ms, or a 65% improvement.

For reference, here is our naive and custom functions:

struct Result sum_custom() {
        int i;
        struct Result res;
        int16_t table[0xFFFF];
        int idx;

        gettimeofday(&res.time_start, NULL);
        res.sum = 0;
        for(i = -32767; i <=32767;i++){
                table[i & 0xFFFF] = i * VOL;

        int sz = SIZE;
        for(i = 0; i < sz ; i++){
                idx = (unsigned short) data[i];
                res.sum += output[i] = table[idx];

        gettimeofday(&res.time_end, NULL);
        return res;

struct Result sum_naive(){
        size_t i;
        struct Result res;
        int16_t val;

        gettimeofday(&res.time_start, NULL);
        res.sum = 0;
        for(i = 0; i < SIZE;i++){
                val = data[i] * VOL;
                output[i] = val;
                res.sum += val; // we're adding here to prevent the compiler from optimizing
// our whole loop out.
        gettimeofday(&res.time_end, NULL);
        return res;

by Matthew Bell ( at February 19, 2017 02:57 AM

Max Fainshtein

Assignment 1

The issue that I decided to tackle was issue number #1756 it was  a simple css fix to prevent navigation items from collapsing when window was adjusted. The issue was that the only thing preventing from navigation from collapsing was the min-width tag that was entered. Which did its job when there was no tutorial added to navigation bar, but once the tutorial menu item is applied the min with that would of been required 460. Instead of adjusting that though I added the whitespace: nowrap tag in the css nav items which also managed to fix the issue.

by mfainshtein4 at February 19, 2017 02:15 AM

February 18, 2017

Ray Gervais

Brackets Enhancement Proposal

OSD600 Week Six Deliverable

When we were given the instructions to search, locate and eventually implement fixes or upgrades to Mozilla’s Thimble or Brackets, I found what perhaps was the most challenging enhancement I could possible implement. Suggested here by the professor, and assigned to myself at my own request, the user interface discussion can be found here. Like any good IDE, developers utilize space and workflows to be the most efficient they can, often relying on key mappings and high resolution monitors to provide the most content to their view with ease.

The desktop version of Adobe’s Brackets includes multiple toolbars, which are accessible to the left and right of the editing window -thus providing a simplistic way of accessing commonly used tools, setting configurations and relevant functions for your current project. This is not the case on the Web version, which does not sport said toolbar except for on top of the editor, limiting some of the settings and functional elements to be hidden behind menus. The proposal I agree is very useful for the development of Mozilla’s brackets fork, allowing it to become a much more utilitarian friendly online editor while also providing a smooth and clutter free experience for the beginner and hobbyist.

With this proposed enhancement to the interface, the question of what tools, functions or utilities would be placed in the empty space there. As you can see from the image below of the current Thimble editor, there’s quite a bit of space that we can augment to utilize a responsive toolbar. After doing research related to web development tools, including Adobe’s Brackets, JetBrains’ WebStorm, Microsoft’s Visual Studio Community, and Firefox’s developer tools.

Proposed Features

For my first proposal of features which may be added to that space without cluttering the user interface, I focused on augmenting Brimble (Brackets + Thimble) accessible features to be more advantageous to the developer’s requirements, thus allowing them to use utilize Thimble beyond the standard learning platform which is currently proposed. I’m aware that development of related features is also being in discussion now, which is why I claim this as my first set of proposed features for that space.

Quick Settings

Access to the Editor’s settings, including tab spacing, typeset, syntax highlighting styles, and plugin support. This would tie in with the originally implemented preferences manager, allowing the user to custom tailor their experience on their development machine.This would be responsive, my suggestion on how to best utilize the space is to have three different width classes which would display the settings in the following manners:

  1. Icon Text: Value
  2. Text: Value
  3. Icon: Value

Using three different display manners would allow the application to determine which is best to use for the space, thus introducing a dynamic display which could adapt to different widths without changing the familiarity of the layout and icons.

Code Snippets / Templates

Following similar to XCode’s UI Creator, this area could house drag-drop templates for basic HTML code, with the option to extend with framework classes and various other snippets that may be useful in the future. This would allow Thimble to be more accessible to newer developers, while also providing good web standards. Furthermore, it may benefit the average developer looking to utilize Thimble beyond just a learning environment, and instead use it as a basic test environment for their code.
Examples of this can be found in the following sites and applications:


xcode 8 Interface Builder

Bootstrap Studio

Bootstrap Studio Application


Weebly Interface Builder

by RayGervais at February 18, 2017 08:02 PM

John James

SPO lab 5 (Algorithm Selection in C)

This lab required us to implement two different methods to do the same process, to allow us to adjust the volume of a sequence of samples. This program would be implemented in C, and use the time.h library through the entire system.



Implementation One –

This implementation uses the time.h library.  This implementation does all the calculations and assignments in a for loop which would loop the defined “size” amount of times.

Implementation Two –

The other method we use to do this process does the calculations outside of the for loop (data hosting) to improve the efficiency of the code. This way we reduce the number of multiplication calls. We also removed the implementation which prevented the complied from optimizing the loop & ensured that our second implementation would have better performance overall

Final Thought –

From further investigation, we discovered the AArch64 server was the one which benefited the most from the optimization. We discovered the -O3 GCC argument creates the most optimized executable. However on the X86_64 server default optimization   made only minor improvements      to the runtime of the program



by johnjamesa70 at February 18, 2017 07:56 PM

Catherine Leung

Being a Student Again

This semester I decided to audit my colleague Chris Tyler’s Software Portability and Optimization (SPO600) course at Seneca College.   I think it is important to keep learning new things especially in our field that is ever changing.  I remember how as a student and my profs would talk about punchcards (or how they luckily missed having to deal punch cards by one year).  Now I think back to all the things that were true when I was a student that are so not true today (2MB of RAM  was standard on a PC, significantly lower processing speed, no way to get viruses via emails cause its just text…).  Things keep evolving and it is good to keep learning.

I decided to take this course in particular because Chris had told me about how compilers don’t actually translate the code we write into what we think .  I thought it was fascinating how our model of what happens is so different from what actually happens once our code compiles.  I wanted to find out more.

Another reason I wanted to do the course was because I also teach the data structures and algorithms course(dsa555 and btp500) and in that course we talk about algorithms and their implementation at a high level.  We make broad generalizations like division is same speed as addition and we look at run time at an algorithmic level without any consideration of hardware. There, big-O runtime is king.   SPO600 goes to the other end and looks at how optimization works when you get really really close to hardware.  We even look at assembly code (last time I did assembly it was on 68000 ).  I am finding the material fascinating and the next few posts that I write will be about things I’ve learned so far.

by Cathy at February 18, 2017 05:08 AM

February 17, 2017

Ray Gervais

Algorithm Selection in C

SPO600 Week Five Deliverables

During this lab, we were instructed to program two different implementations which attempted the same process; adjusting the volume of a sequence of samples. This program would be implemented in C, and benchmarked using the conventional time.h library available through the system.

Implementation One

This simple implementation utilized the following function, which I’ve included below this description.

struct Result sum_naive(){
        size_t i;
        struct Result res;
        int16_t val;

        gettimeofday(&res.time_start, NULL);
        res.sum = 0;
        for(i = 0; i < SIZE; i++){
                val = data[i] * VOL;
                output[i] = val;
                res.sum += val;
        gettimeofday(&res.time_end, NULL);

        return res;

This simple algorithm did all calculations, and assignments in a for statement which would loop the defined ‘SIZE’ amount of times. SIZE was defined at the time of this post as 500,000,000. The first issue we saw was multiple assignment operators during the loop, which would have an impact on performance that make up a second of the entire runtime.

Implementation Two

struct Result sum_custom() {
        int i;
        struct Result res;
        int16_t table[0xFFFF];
        int idx;

        gettimeofday(&res.time_start, NULL);
        res.sum = 0;
        for(i = -32767; i <=32767;i++){
                table[i & 0xFFFF] = i * VOL;

        int sz = SIZE;
        for(i = 0; i < sz ; i++){
                idx = (unsigned short) data[i];
                res.sum += output[i] = table[idx];
                res.sum += output[i] = table[(unsigned short) data[i++]];
                res.sum += output[i] = table[(unsigned short) data[i++]];
                res.sum += output[i] = table[(unsigned short) data[i++]];
                res.sum += output[i] = table[(unsigned short) data[i++]];

                res.sum += table[data[i++] & 0xFFFF]
                        + table[data[i++] & 0xFFFF]
                        + table[data[i] & 0xFFFF];


        gettimeofday(&res.time_end, NULL);
        return res;

This implementation on the other hand utilized calculations outside of the for statement, effectively reducing the amount of multiplication calls to 65,335 in contrast to the original 500,000,000. This, along with the removal of a line used in the first implementation which negated the compiler from optimizing the entire loop ensured that our second implementation would be much more performant than the previous.

Observations and Analysis

On the AArch64 server, the following code functions each ran with the same input data, and reported the following data metric:

Naive: 5.616 Seconds
Custom: 2.285 Seconds
Time Difference: 3.331 Seconds

In contrast, to the x86_64 server the following data metrics were provided at the end of the application execution:

Naive:2.984 Seconds
Custom: 1.173 Second
Time Difference: 1.811 Seconds

With the above results, upon investigating each executables machine code and attempting optimizations on that level, the AArch64 server was the one which benefited the most from the optimizations. This was discovered after using the -O3 GCC argument, which would create the most optimal executable it could. This in contrast, did not have too much benefit on the X86_64 server which by default optimized much more of the code logic from the very start, making only subtle changes to the runtime of the program.

by RayGervais at February 17, 2017 09:55 PM

Len Isac

GCC auto-vectorization & SIMD on Aarch64 architecture

In this exercise, we will compile a short C program and analyze the disassembly file after enabling auto-vectorization. This will be done on an Aarch64 architecture. Later on, we will also refer to a previous post on scaling a sequence of sound samples and how this can be done using SIMD.

Test code

 * vectorization.c
 * This program creates two 1000-element integer arrays and fills them 
 * with random numbers, then sums those two arrays to a third array, 
 * and finally sums the third array to a long int and prints the result

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

#define SIZE 1000

int main()
    int a[SIZE];
    int b[SIZE];
    int sumArr[SIZE];
    long int totalSum;
    for (int i = 0; i < SIZE; i++)
        a[i] = rand();
        b[i] = rand();
        sumArr[i] = a[i] + b[i];
        totalSum += sumArr[i];
    printf("Total long int sum = %d\n", totalSum );
    return 0;


c99 -o vectorization vectorization.c

Total long int sum = 310282548

Now we’ll disassemble our binary file.


In this article, it explains that vectorization is an approach to speeding up code which contains many loops such as our code written above.

We’ll compile our code with -O3 level optimization which enables auto-vectorization.

c99 -O3 -o vectorization vectorization.c
objdump -d vectorization

Disassembly output with annotation

00000000004004c0 <main>:
  4004c0:       a9bd7bfd        stp     x29, x30, [sp,#-48]!            

/* Init variables */
  4004c4:       910003fd        mov     x29, sp                         // stack pointer to integer array 'a' address (int a[SIZE])
  4004c8:       a90153f3        stp     x19, x20, [sp,#16]              // int array b[SIZE]
  4004cc:       f90013f5        str     x21, [sp,#32]                   // store register x21 to address pointed to by (sp + (32 * 8))

  4004d0:       52807d33        mov     w19, #0x3e8                     // #1000 - SIZE of array

/* Start of Loop 
 * Calculate sum of both random numbers from a[i] and b[i]
 *  store in sumArr[i]
  4004d4:       97ffffeb        bl      400480 <rand@plt>               // generates random number
  4004d8:       2a0003f5        mov     w21, w0                         // store into a[i]
  4004dc:       97ffffe9        bl      400480 <rand@plt>               // generates random number
  4004e0:       0b0002a0        add     w0, w21, w0                     // add a[i] + b[i] store it in sumArr[i]
  4004e4:       71000673        subs    w19, w19, #0x1                  

/* Calculate Total Sum - store in totalSum
 * End of Loop
  4004e8:       8b20c294        add     x20, x20, w0, sxtw              // add sumArr[i] to totalSum
  4004ec:       54ffff41    4004d4 <main+0x14>              // check i <= SIZE
  4004f0:       90000000        adrp    x0, 400000 <_init-0x430>
  4004f4:       aa1403e1        mov     x1, x20
  4004f8:       911c6000        add     x0, x0, #0x718
  4004fc:       97ffffed        bl      4004b0 <printf@plt>
  400500:       2a1303e0        mov     w0, w19
  400504:       f94013f5        ldr     x21, [sp,#32]
  400508:       a94153f3        ldp     x19, x20, [sp,#16]
  40050c:       a8c37bfd        ldp     x29, x30, [sp],#48
  400510:       d65f03c0        ret
  400514:       00000000        .inst   0x00000000 ; undefined


From a previous post on scaling an array of sound samples by a factor between 0.000-1.000, we will now try to write a solution to achieve this using SIMD (Single Instruction Multiple Data).

Original C code – no SIMD

const float scale = 0.5;

void naiveVolumeUp(int16_t* sample_, int16_t* newSample_)
    for (int i = 0; i <= SAMPLESNUM; i++)
        newSample_[i] = sample_[i] * scale;

int main()
    int16_t* sample = malloc(SAMPLESNUM*sizeof(int16_t));


    int16_t* newSample = malloc(SAMPLESNUM*sizeof(int16_t));
    naiveVolumeUp(sample, newSample);
	return 0;

Let’s take a look at our binary’s object dump file for the naiveVolumeUp function:

gcc -O3 -o lab5c lab5.c
objdump -d lab5

0000000000400b90 <naiveVolumeUp>:
  400b90:	48 8d 46 10          	lea    0x10(%rsi),%rax
  400b94:	48 39 c7             	cmp    %rax,%rdi
  400b97:	73 0d                	jae    400ba6 <naiveVolumeUp+0x16>
  400b99:	48 8d 47 10          	lea    0x10(%rdi),%rax
  400b9d:	48 39 c6             	cmp    %rax,%rsi
  400ba0:	0f 82 ba 02 00 00    	jb     400e60 <naiveVolumeUp+0x2d0>
  400ba6:	48 89 f8             	mov    %rdi,%rax
  400ba9:	55                   	push   %rbp
  400baa:	53                   	push   %rbx
  400bab:	48 d1 e8             	shr    %rax
  400bae:	48 f7 d8             	neg    %rax
  400bb1:	83 e0 07             	and    $0x7,%eax
  400bb4:	0f 84 e6 02 00 00    	je     400ea0 <naiveVolumeUp+0x310>
  400bba:	0f bf 17             	movswl (%rdi),%edx
  400bbd:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400bc1:	f3 0f 10 0d eb 05 00 	movss  0x5eb(%rip),%xmm1        # 4011b4 <scale+0x4>
  400bc8:	00 
  400bc9:	83 f8 01             	cmp    $0x1,%eax
  400bcc:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400bd0:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400bd4:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400bd8:	66 89 16             	mov    %dx,(%rsi)
  400bdb:	0f 84 f1 02 00 00    	je     400ed2 <naiveVolumeUp+0x342>
  400be1:	0f bf 57 02          	movswl 0x2(%rdi),%edx
  400be5:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400be9:	83 f8 02             	cmp    $0x2,%eax
  400bec:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400bf0:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400bf4:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400bf8:	66 89 56 02          	mov    %dx,0x2(%rsi)
  400bfc:	0f 84 e1 02 00 00    	je     400ee3 <naiveVolumeUp+0x353>
  400c02:	0f bf 57 04          	movswl 0x4(%rdi),%edx
  400c06:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400c0a:	83 f8 03             	cmp    $0x3,%eax
  400c0d:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400c11:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400c15:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400c19:	66 89 56 04          	mov    %dx,0x4(%rsi)
  400c1d:	0f 84 d1 02 00 00    	je     400ef4 <naiveVolumeUp+0x364>
  400c23:	0f bf 57 06          	movswl 0x6(%rdi),%edx
  400c27:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400c2b:	83 f8 04             	cmp    $0x4,%eax
  400c2e:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400c32:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400c36:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400c3a:	66 89 56 06          	mov    %dx,0x6(%rsi)
  400c3e:	0f 84 c1 02 00 00    	je     400f05 <naiveVolumeUp+0x375>
  400c44:	0f bf 57 08          	movswl 0x8(%rdi),%edx
  400c48:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400c4c:	83 f8 05             	cmp    $0x5,%eax
  400c4f:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400c53:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400c57:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400c5b:	66 89 56 08          	mov    %dx,0x8(%rsi)
  400c5f:	0f 84 b1 02 00 00    	je     400f16 <naiveVolumeUp+0x386>
  400c65:	0f bf 57 0a          	movswl 0xa(%rdi),%edx
  400c69:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400c6d:	83 f8 07             	cmp    $0x7,%eax
  400c70:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400c74:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400c78:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400c7c:	66 89 56 0a          	mov    %dx,0xa(%rsi)
  400c80:	0f 85 3b 02 00 00    	jne    400ec1 <naiveVolumeUp+0x331>
  400c86:	0f bf 57 0c          	movswl 0xc(%rdi),%edx
  400c8a:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400c8e:	41 ba fa 64 cd 1d    	mov    $0x1dcd64fa,%r10d
  400c94:	41 b9 07 00 00 00    	mov    $0x7,%r9d
  400c9a:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400c9e:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400ca2:	f3 0f 2c d0          	cvttss2si %xmm0,%edx
  400ca6:	66 89 56 0c          	mov    %dx,0xc(%rsi)
  400caa:	b9 f9 64 cd 1d       	mov    $0x1dcd64f9,%ecx
  400caf:	41 bb 01 65 cd 1d    	mov    $0x1dcd6501,%r11d
  400cb5:	41 89 c0             	mov    %eax,%r8d
  400cb8:	29 c1                	sub    %eax,%ecx
  400cba:	41 29 c3             	sub    %eax,%r11d
  400cbd:	c1 e9 03             	shr    $0x3,%ecx
  400cc0:	83 c1 01             	add    $0x1,%ecx
  400cc3:	8d 2c cd 00 00 00 00 	lea    0x0(,%rcx,8),%ebp
  400cca:	66 0f ef e4          	pxor   %xmm4,%xmm4
  400cce:	4d 01 c0             	add    %r8,%r8
  400cd1:	31 c0                	xor    %eax,%eax
  400cd3:	0f 28 1d e6 04 00 00 	movaps 0x4e6(%rip),%xmm3        # 4011c0 <scale+0x10>
  400cda:	4a 8d 1c 07          	lea    (%rdi,%r8,1),%rbx
  400cde:	31 d2                	xor    %edx,%edx
  400ce0:	49 01 f0             	add    %rsi,%r8
  400ce3:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
  400ce8:	66 0f 6f 0c 03       	movdqa (%rbx,%rax,1),%xmm1
  400ced:	66 0f 6f d4          	movdqa %xmm4,%xmm2
  400cf1:	83 c2 01             	add    $0x1,%edx
  400cf4:	66 0f 65 d1          	pcmpgtw %xmm1,%xmm2
  400cf8:	66 0f 6f c1          	movdqa %xmm1,%xmm0
  400cfc:	66 0f 69 ca          	punpckhwd %xmm2,%xmm1
  400d00:	66 0f 61 c2          	punpcklwd %xmm2,%xmm0
  400d04:	0f 5b c9             	cvtdq2ps %xmm1,%xmm1
  400d07:	0f 59 cb             	mulps  %xmm3,%xmm1
  400d0a:	0f 5b c0             	cvtdq2ps %xmm0,%xmm0
  400d0d:	0f 59 c3             	mulps  %xmm3,%xmm0
  400d10:	f3 0f 5b c9          	cvttps2dq %xmm1,%xmm1
  400d14:	f3 0f 5b c0          	cvttps2dq %xmm0,%xmm0
  400d18:	66 0f 6f d0          	movdqa %xmm0,%xmm2
  400d1c:	66 0f 61 c1          	punpcklwd %xmm1,%xmm0
  400d20:	66 0f 69 d1          	punpckhwd %xmm1,%xmm2
  400d24:	66 0f 6f c8          	movdqa %xmm0,%xmm1
  400d28:	66 0f 61 c2          	punpcklwd %xmm2,%xmm0
  400d2c:	66 0f 69 ca          	punpckhwd %xmm2,%xmm1
  400d30:	66 0f 61 c1          	punpcklwd %xmm1,%xmm0
  400d34:	41 0f 11 04 00       	movups %xmm0,(%r8,%rax,1)
  400d39:	48 83 c0 10          	add    $0x10,%rax
  400d3d:	39 ca                	cmp    %ecx,%edx
  400d3f:	72 a7                	jb     400ce8 <naiveVolumeUp+0x158>
  400d41:	41 01 e9             	add    %ebp,%r9d
  400d44:	41 29 ea             	sub    %ebp,%r10d
  400d47:	41 39 eb             	cmp    %ebp,%r11d
  400d4a:	0f 84 0d 01 00 00    	je     400e5d <naiveVolumeUp+0x2cd>
  400d50:	49 63 d1             	movslq %r9d,%rdx
  400d53:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400d57:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400d5b:	f3 0f 10 0d 51 04 00 	movss  0x451(%rip),%xmm1        # 4011b4 <scale+0x4>
  400d62:	00 
  400d63:	41 83 fa 01          	cmp    $0x1,%r10d
  400d67:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400d6b:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400d6f:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400d73:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400d77:	41 8d 51 01          	lea    0x1(%r9),%edx
  400d7b:	0f 84 dc 00 00 00    	je     400e5d <naiveVolumeUp+0x2cd>
  400d81:	48 63 d2             	movslq %edx,%rdx
  400d84:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400d88:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400d8c:	41 83 fa 02          	cmp    $0x2,%r10d
  400d90:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400d94:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400d98:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400d9c:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400da0:	41 8d 51 02          	lea    0x2(%r9),%edx
  400da4:	0f 84 b3 00 00 00    	je     400e5d <naiveVolumeUp+0x2cd>
  400daa:	48 63 d2             	movslq %edx,%rdx
  400dad:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400db1:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400db5:	41 83 fa 03          	cmp    $0x3,%r10d
  400db9:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400dbd:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400dc1:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400dc5:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400dc9:	41 8d 51 03          	lea    0x3(%r9),%edx
  400dcd:	0f 84 8a 00 00 00    	je     400e5d <naiveVolumeUp+0x2cd>
  400dd3:	48 63 d2             	movslq %edx,%rdx
  400dd6:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400dda:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400dde:	41 83 fa 04          	cmp    $0x4,%r10d
  400de2:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400de6:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400dea:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400dee:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400df2:	41 8d 51 04          	lea    0x4(%r9),%edx
  400df6:	74 65                	je     400e5d <naiveVolumeUp+0x2cd>
  400df8:	48 63 d2             	movslq %edx,%rdx
  400dfb:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400dff:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400e03:	41 83 fa 05          	cmp    $0x5,%r10d
  400e07:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400e0b:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400e0f:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400e13:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400e17:	41 8d 51 05          	lea    0x5(%r9),%edx
  400e1b:	74 40                	je     400e5d <naiveVolumeUp+0x2cd>
  400e1d:	48 63 d2             	movslq %edx,%rdx
  400e20:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400e24:	0f bf 04 57          	movswl (%rdi,%rdx,2),%eax
  400e28:	41 83 c1 06          	add    $0x6,%r9d
  400e2c:	41 83 fa 06          	cmp    $0x6,%r10d
  400e30:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400e34:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400e38:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400e3c:	66 89 04 56          	mov    %ax,(%rsi,%rdx,2)
  400e40:	74 1b                	je     400e5d <naiveVolumeUp+0x2cd>
  400e42:	49 63 c1             	movslq %r9d,%rax
  400e45:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400e49:	0f bf 14 47          	movswl (%rdi,%rax,2),%edx
  400e4d:	f3 0f 2a c2          	cvtsi2ss %edx,%xmm0
  400e51:	f3 0f 59 c8          	mulss  %xmm0,%xmm1
  400e55:	f3 0f 2c d1          	cvttss2si %xmm1,%edx
  400e59:	66 89 14 46          	mov    %dx,(%rsi,%rax,2)
  400e5d:	5b                   	pop    %rbx
  400e5e:	5d                   	pop    %rbp
  400e5f:	c3                   	retq   
  400e60:	31 d2                	xor    %edx,%edx
  400e62:	f3 0f 10 0d 4a 03 00 	movss  0x34a(%rip),%xmm1        # 4011b4 <scale+0x4>
  400e69:	00 
  400e6a:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
  400e70:	0f bf 04 17          	movswl (%rdi,%rdx,1),%eax
  400e74:	66 0f ef c0          	pxor   %xmm0,%xmm0
  400e78:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400e7c:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  400e80:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  400e84:	66 89 04 16          	mov    %ax,(%rsi,%rdx,1)
  400e88:	48 83 c2 02          	add    $0x2,%rdx
  400e8c:	48 81 fa 02 ca 9a 3b 	cmp    $0x3b9aca02,%rdx
  400e93:	75 db                	jne    400e70 <naiveVolumeUp+0x2e0>
  400e95:	f3 c3                	repz retq 
  400e97:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)
  400e9e:	00 00 
  400ea0:	bd 00 65 cd 1d       	mov    $0x1dcd6500,%ebp
  400ea5:	b9 a0 ac b9 03       	mov    $0x3b9aca0,%ecx
  400eaa:	41 bb 01 65 cd 1d    	mov    $0x1dcd6501,%r11d
  400eb0:	45 31 c0             	xor    %r8d,%r8d
  400eb3:	41 ba 01 65 cd 1d    	mov    $0x1dcd6501,%r10d
  400eb9:	45 31 c9             	xor    %r9d,%r9d
  400ebc:	e9 09 fe ff ff       	jmpq   400cca <naiveVolumeUp+0x13a>
  400ec1:	41 ba fb 64 cd 1d    	mov    $0x1dcd64fb,%r10d
  400ec7:	41 b9 06 00 00 00    	mov    $0x6,%r9d
  400ecd:	e9 d8 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400ed2:	41 ba 00 65 cd 1d    	mov    $0x1dcd6500,%r10d
  400ed8:	41 b9 01 00 00 00    	mov    $0x1,%r9d
  400ede:	e9 c7 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400ee3:	41 ba ff 64 cd 1d    	mov    $0x1dcd64ff,%r10d
  400ee9:	41 b9 02 00 00 00    	mov    $0x2,%r9d
  400eef:	e9 b6 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400ef4:	41 ba fe 64 cd 1d    	mov    $0x1dcd64fe,%r10d
  400efa:	41 b9 03 00 00 00    	mov    $0x3,%r9d
  400f00:	e9 a5 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400f05:	41 ba fd 64 cd 1d    	mov    $0x1dcd64fd,%r10d
  400f0b:	41 b9 04 00 00 00    	mov    $0x4,%r9d
  400f11:	e9 94 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400f16:	41 ba fc 64 cd 1d    	mov    $0x1dcd64fc,%r10d
  400f1c:	41 b9 05 00 00 00    	mov    $0x5,%r9d
  400f22:	e9 83 fd ff ff       	jmpq   400caa <naiveVolumeUp+0x11a>
  400f27:	66 0f 1f 84 00 00 00 	nopw   0x0(%rax,%rax,1)
  400f2e:	00 00 

For a function with one loop this seems like quite a long set of instructions even if it contains two large size integer arrays. Let’s try to use SIMD to help gcc condense this.

Loop Function using SIMD

The article above mentions that gcc does not know our arrays are aligned so it has to do extra work to account for possible cases in which they are not.

Let’s tell gcc explicitly that these arrays are aligned by calling the __builtin_assume_aligned function on the passed in int16_t* parameters and create two new pointers for our 16-bit aligned arrays.


void naiveVolumeUp(int16_t* sample_, int16_t* newSample_)
    int16_t *x = __builtin_assume_aligned(sample_,16);
    int16_t *y = __builtin_assume_aligned(newSample_,16);
    for (int i = 0; i <= SAMPLESNUM; i++)
        y[i] = x[i] * scale;

Compile our code again with -O3 level optimization to enable auto-vectorization.
gcc -O3 -o lab5-simd lab5-simd.c
objdump -d lab5-simd

00000000004008e0 <naiveVolumeUp>:
  4008e0:	48 8d 46 10          	lea    0x10(%rsi),%rax
  4008e4:	48 39 c7             	cmp    %rax,%rdi
  4008e7:	73 0d                	jae    4008f6 <naiveVolumeUp+0x16>
  4008e9:	48 8d 47 10          	lea    0x10(%rdi),%rax
  4008ed:	48 39 c6             	cmp    %rax,%rsi
  4008f0:	0f 82 92 00 00 00    	jb     400988 <naiveVolumeUp+0xa8>
  4008f6:	66 0f ef e4          	pxor   %xmm4,%xmm4
  4008fa:	0f 28 1d 4f 03 00 00 	movaps 0x34f(%rip),%xmm3        # 400c50 <scale+0x10>
  400901:	31 c0                	xor    %eax,%eax
  400903:	0f 1f 44 00 00       	nopl   0x0(%rax,%rax,1)
  400908:	66 0f 6f 0c 07       	movdqa (%rdi,%rax,1),%xmm1
  40090d:	66 0f 6f d4          	movdqa %xmm4,%xmm2
  400911:	66 0f 6f c1          	movdqa %xmm1,%xmm0
  400915:	66 0f 65 d1          	pcmpgtw %xmm1,%xmm2
  400919:	66 0f 61 c2          	punpcklwd %xmm2,%xmm0
  40091d:	66 0f 69 ca          	punpckhwd %xmm2,%xmm1
  400921:	0f 5b c0             	cvtdq2ps %xmm0,%xmm0
  400924:	0f 59 c3             	mulps  %xmm3,%xmm0
  400927:	0f 5b c9             	cvtdq2ps %xmm1,%xmm1
  40092a:	0f 59 cb             	mulps  %xmm3,%xmm1
  40092d:	f3 0f 5b c0          	cvttps2dq %xmm0,%xmm0
  400931:	66 0f 6f d0          	movdqa %xmm0,%xmm2
  400935:	f3 0f 5b c9          	cvttps2dq %xmm1,%xmm1
  400939:	66 0f 61 c1          	punpcklwd %xmm1,%xmm0
  40093d:	66 0f 69 d1          	punpckhwd %xmm1,%xmm2
  400941:	66 0f 6f c8          	movdqa %xmm0,%xmm1
  400945:	66 0f 61 c2          	punpcklwd %xmm2,%xmm0
  400949:	66 0f 69 ca          	punpckhwd %xmm2,%xmm1
  40094d:	66 0f 61 c1          	punpcklwd %xmm1,%xmm0
  400951:	0f 29 04 06          	movaps %xmm0,(%rsi,%rax,1)
  400955:	48 83 c0 10          	add    $0x10,%rax
  400959:	48 3d 00 ca 9a 3b    	cmp    $0x3b9aca00,%rax
  40095f:	75 a7                	jne    400908 <naiveVolumeUp+0x28>
  400961:	0f bf 87 00 ca 9a 3b 	movswl 0x3b9aca00(%rdi),%eax
  400968:	66 0f ef c0          	pxor   %xmm0,%xmm0
  40096c:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  400970:	f3 0f 59 05 28 03 00 	mulss  0x328(%rip),%xmm0        # 400ca0 <scale+0x60>
  400977:	00 
  400978:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  40097c:	66 89 86 00 ca 9a 3b 	mov    %ax,0x3b9aca00(%rsi)
  400983:	c3                   	retq   
  400984:	0f 1f 40 00          	nopl   0x0(%rax)
  400988:	31 d2                	xor    %edx,%edx
  40098a:	f3 0f 10 0d 0e 03 00 	movss  0x30e(%rip),%xmm1        # 400ca0 <scale+0x60>
  400991:	00 
  400992:	66 0f 1f 44 00 00    	nopw   0x0(%rax,%rax,1)
  400998:	0f bf 04 17          	movswl (%rdi,%rdx,1),%eax
  40099c:	66 0f ef c0          	pxor   %xmm0,%xmm0
  4009a0:	f3 0f 2a c0          	cvtsi2ss %eax,%xmm0
  4009a4:	f3 0f 59 c1          	mulss  %xmm1,%xmm0
  4009a8:	f3 0f 2c c0          	cvttss2si %xmm0,%eax
  4009ac:	66 89 04 16          	mov    %ax,(%rsi,%rdx,1)
  4009b0:	48 83 c2 02          	add    $0x2,%rdx
  4009b4:	48 81 fa 02 ca 9a 3b 	cmp    $0x3b9aca02,%rdx
  4009bb:	75 db                	jne    400998 <naiveVolumeUp+0xb8>
  4009bd:	f3 c3                	repz retq 
  4009bf:	90                   	nop

The instructions for our function has now been significantly condensed since we’ve explicitly told gcc that the arrays used inside our loop are 16-bit aligned.

Size of binaries – with and without auto-vectorization:

[lisac@localhost lab6-vectorization]$ size lab5
   text    data     bss     dec     hex filename
   4666     580       4    5250    1482 lab5
[lisac@localhost lab6-vectorization]$ size lab5-simd
   text    data     bss     dec     hex filename
   3222     580       4    3806     ede lab5-simd

by Len Isac at February 17, 2017 03:41 PM

Algorithm Selection – adjusting a sequence of sound samples by a volume scale factor

The purpose of this exercise is to compare the different algorithm approaches for adjusting a sequence of sound samples. We can analyze how the different gcc optimization levels increase or decrease the performance for each of them on both x86_64 and Aarch64 architectures.

Creating audio sample

First, we will create an audio sample to test with. Since we would like to be able to compare the runtimes between each algorithm, a substantial data set is required, so we will create a sequence of 500000000 sound samples. This will be coded in c, and we will store the sound samples inside a signed int16 array (-32768 to 32767 range).

#define SAMPLESNUM 500000000

void createAudioSample(int16_t* sample_)
    for(int i = 0; i <= SAMPLESNUM; i++)
        sample_[i] = rand();

int main()
    int16_t* sample = malloc(SAMPLESNUM*sizeof(int16_t));

Increase Volume

First algorithm – “Naive” approach

The first algorithm written will increase the volume by simply multiplying each sound sample by a volume scale factor then storing the result into a new array.

const float scale = 0.5; // volume scaling factor

void naiveVolumeUp(int16_t* sample_, int16_t* newSample_)
    for (int i = 0; i <= SAMPLESNUM; i++)
        newSample_[i] = sample_[i] * scale;

Second algorithm – Look up table approach

For this approach, we will create a lookup table with all possible values from -32768 to 32767 multiplied by the volume scale factor (in our case 0.5). We can then reference the lookup later on to adjust our volume by the scale factor.

#define MAXSIZE 65536 // maximum size for signed 16 bit integer
#define HALF 32767 // half of max size for signed 16 bit integer


void lookupTableVolumeUp(int16_t* sample_, int16_t* newSample_)
    // Create Lookup table
    int16_t lookupTable[MAXSIZE];
    for (int counter = 0; counter < MAXSIZE; counter++)
        lookupTable[counter] = ((counter - HALF )*scale);

    // Increase using lookupTable
    for (int i = 0; i <= MAXSIZE; i++)
        newSample_[i] = lookupTable[sample_[i] + HALF];

Here is a function to calculate our functions’ execution times:

void printExecTime(struct timeval t1, struct timeval t2)
    double elapsed;
    elapsed = (t2.tv_sec - t1.tv_sec) + 1e-6 * (t2.tv_usec - t1.tv_usec);

    printf("elapsed: %.8lf seconds\n", elapsed);

And our main:

int main()
   struct timeval t1, t2;
   int16_t* sample = malloc(SAMPLESNUM*sizeof(int16_t));

   printf("\nAudio sample\n============\n");
   printSpecifiedRange(sample, 0, 7);

   int16_t* newSample = malloc(SAMPLESNUM*sizeof(int16_t));
   printf("\nNaive volume up\n===============\n");
   gettimeofday(&t1, NULL); // starting time
   naiveVolumeUp(sample, newSample); // start naive test
   gettimeofday(&t2, NULL); // end time
   printExecTime(t1, t2);
   printSpecifiedRange(newSample, 0, 7);

   newSample = malloc(SAMPLESNUM*sizeof(int16_t));
   printf("\nLookup volume up\n================\n");
   gettimeofday(&t1, NULL); // starting time
   lookupTableVolumeUp(sample, newSample); // start lookup table approach 
   gettimeofday(&t2, NULL); // end time
   printExecTime(t1, t2);
   printSpecifiedRange(newSample, 0, 7);

    return 0;

Compile our code:
gcc -o lab5 lab5.c
time ./lab5

Audio sample

Naive volume up
elapsed: 6.56288600 seconds

Lookup volume up
elapsed: 0.11074700 seconds

real	0m16.653s
user	0m11.863s
sys	0m1.145s

We can see the lookup approach is signficantly faster. Now we’ll test the different optimization levels on both Xerxes(x86_64) and Betty(Aarch64) machines.

Runtime w/ optimization levels

I compiled the code with each optimization level from O0 to O3, i.e:
gcc -O0 -o lab5 lab5.c

gcc -O3 -o lab5 lab5.c
c99 -O0 -o lab5 lab5.c

c99 -O3 -o lab5 lab5.c

And recorded the results into a spreadsheet:


The Functions section of the report shows both functions’ execution times, and is displayed in seconds.
The first thing I noticed with O0 optimization was that the ratio between Naive and Lookup was significantly wider on Betty than on Xerxes. The Naive function on Xerxes comparing O0 to O1 improves from 3.84 to 1.18. On Betty, it improves from 8.94 to 1.79. The ratio between the two functions from O1 to O3 begin to even out and are relatively similar between the two architectures.

The time section of the report displays results from the time ./lab5 command. This simply displays the runtimes for the whole program execution in real, user and sys time.

The size section displays results from the size lab5 command.
We can see that all data sizes are equally larger on Betty than on Xerxes. One thing that stands out is the O3 level optimization on Xerxes is 4634 bytes, while on Betty it is 2934 bytes.

by Len Isac at February 17, 2017 12:16 AM

February 16, 2017

Matt Welke

Documenting the Modules

My work on creating the documentation is continuing well. I needed to spend some time at first learning how to use react-router, a library that allows you to get URL routes in your Single Page Application (SPA). We need the documentation to behave as users expect it to. They shouldn’t know we’re making it a React SPA.

I’ve documented how the new central config object (used by all modules) works, as well as how to install and run the individual modules. I’ve also documented how the user accounts work in the Analytics module (my team mate created a much more robust system where usernames and bcrypt-encrypted passwords are stored in the MongoDB database). My next steps will be to document the AWS bundle (I wanted to wait until the individual modules were more polished and tested before tackling this) and then to polish the whole documentation. I want to make it read well, to be as simple as possible. There’s a certain writing style that good documentation uses to accomplish this.

An example of great documentation I’ve read before to inspire me is the MongoDB documentation, including how they describe the database itself, the language-specific drivers, and the language-specific ORMs. From top level concepts to low level code examples, it’s very clear. And it has helped me learn the tools we use on our project, which center around MongoDB.

I also want to make sure the documentation renders well on mobile phones. This is a bit of a stretch goal… Most developers read documentation when they’ve sat down to deep dive into something new and try to code something up, but you never know… We want this to be as welcoming as possible to potential users and open source contributors, including people so busy they only have time to look at the documentation while they’re on their phone on the TTC.

by Matt at February 16, 2017 11:14 PM

David Humphrey

git, with abandon

I really enjoyed reading
The Biggest and Weirdest Commits in Linux Kernel Git History
this week. If you haven't read it yet, it describes some of the edge case merges in the Linux Kernel, including one octopus merge that has 66 parent commits.

the kernel developers are expert git users and tend to use its features with abandon

With abandon: To use git with abandon, one has to have already embraced it.

I've been teaching my open source students how to use git this term, and more, how to use it fearlessly. I used to teach it quickly, but through experience, I've slowed down my pacing, and I spend a lot more time on the concepts. I think it's important to feel in control of git, rather than constantly fearing for your safety as you copy and paste commands into your terminal without understanding what is going to happen. Git isn't easy, but it's not as hard as it seems when you first begin either: you just have to take your time and learn how to handle it.

In an effort to walk-the-talk I decided to take on a fairly large merge that I've been putting off. Two years ago I forked Adobe's Brackets repo, and started reworking it so it would run in a browser--we use it in Thimble. For a long time I kept rebasing our work on Adobe's master branch. But eventually, I decided to keep things stable on our side, and let the two repos drift apart. Since then we (Mozilla, Seneca, and I) have done ~500 commits on our fork. In the same period, Adobe went on to release 4 new versions of Brackets, and added 1,000+ new commits. In other words, our branches have diverged!

There hasn't been any pressing reason for me to update to what's upstream. Everything we want Brackets to do in Thimble, it does now, and does well. However, I also knew that I eventually wanted to get any bug fixes, updates to deps they use, and any new cool features.

So this week I decided to dive in. Because I'm also working on other bugs in the same tree, and had no idea how long it would take to fix the inevitable merge conflicts it would create, I decided to re-clone my repo and do it there. This removed a lot of pressure, since I could take as long as I needed without leaving my tree in a half-merged state. I think this was a great strategy, and I'd recommend it.

For the most part, the merge went smoothly. This was both surprising and expected. On the one hand, I knew that git could do this, but I also feared it might get really messy when the two lines of development came back together. In the end there were 40K new lines of code, and another 27K removed from ~700 files. And of these, there were only 45 files with merge conflicts. At first it felt like a lot, and not something I was going to enjoy. But by spending the better part of a day going through them all, I was able to sort everything out without too much trouble. Very few were huge problems, it was just work I had to do.

On reflection, I actually found the experience very rewarding. It was like reading a history of the development we'd done: every conflict was a feature or fix we'd layered on, and seeing them all in quick succession made the totality of the work come into focus.

I've had to carry big patches before, especially when doing new DOM features in Firefox and Gecko. It's not a ton of fun having to constantly update against a fast-moving, upstream target. I think what I learned with this merge is that you're almost better to just wait, and do it down the road. Since you're going to have to deal with the conflicts anyway, why not queue them up and do it all at the same time? I'm not convinced that dealing with all these merge conflicts spread out over weeks and months would have been any less work. It almost made it easier for me to do them as a set, since so many of them were related, often in subtle ways.

In terms of how I relied on git to get this done, beyond the expected stuff (add, commit, status, checkout, etc.) I relied on all of the following:

  • blame: to see who did what, and why (esp. when trying to find commits that made changes upstream I needed to understand)
  • show: to examine commits in their entirety
  • bisect: to track down regressions introduced by the merge. I knew something used to work and now doesn't, and I let git guide me to the problem commit. I've written about bisect before. It's one of the greatest tools available to you as a git user.
  • grep: to find things in my tree vs. in commits. I'm amazed how many people don't seem to know about this, I use it all the time, and it saved me hours of frustration with this merge.
  • diff: I often needed to understand how what we did had differed from upstream beyond a single commit.
  • log: I needed to follow the flow of a few commits at a time, and track things back to issues.
  • revert: I had to reverse some of the commits that were done upstream because they didn't make sense with what I was doing. I could have hand-edited the files, but it was a lot nicer to let git do it, and also record a commit that explained why I was doing it.
  • GitHub: I also found it extremely helpful to have two browser windows open in GitHub with each of the repos. Being able to quickly jump to files, comparing things across commits/branches, and being able to jump between code changes and discussions in issues/pull-requests, was all great.

The more you do big merges (and this wasn't even that big of a merge compared to some I've seen!) the more comfortable you'll become to make big changes and to branch off from the main line of development. Git was designed for this, and it's worth spending the time to become comfortable with what it can do.

by David Humphrey at February 16, 2017 06:33 PM

Mohamed Baig

Dang Khue Tran

SPO600 Algorithm Selection Lab

For this lab, we are designing two different approaches to simulate the process of adjusting the volume of a sequence of sound samples in the C language.

Two primary approaches that I used were basic multiplication and bit shifting.

On Betty,  with -O3 optimization option, we achieve a faster time on both approaches. Bit shifting has a faster time than multiplication, I even tried division and it is very close to the time of bit shifting surprisingly. Without any optimization, the time is the same as having -O0.

On Xerxes, both approaches had very similar time, although bit shifting still has a slightly faster time. Division was no different than multiplication.

Overall, Betty still requires the user to optimize the code in order to have fast runtime as any optimization I added always makes a different. Xerxes is smart enough to optimize anything that is simple enough to figure it out on its own, since simple optimizations didn’t produce any different.

by trandangkhue27 at February 16, 2017 01:30 AM

Jaeeun Cho

React Router in closing the private chat

At this week, I am struggling with React Router part. My task is removing the private chat from the list when the user select close it. When the user click "X" button(icon) of opened private chat, the link should be moved from "/users/chatID" to "/users/" and the opened private chat should be closed.

Router is used to keep UI in sync with the URL. It is a powerful and simple routing library and helps to add new screen and flows to application quickly, keeping url in sync with what's being displaying on the page. I thought there are some specific logic to handle changing url without reloading a page in server-side, but nothing is in there.

In the Route component, the url will be changed and the private chat window will be opened automatically. And when the user input just user/chat, public chat room is going to be opened instead of opening the private room.

This component is Link which is the primary to navigate the page(url) and it is the similar functionality with <a> tag in HTML5 which is not including reloading the page. If the current route is linked including the descendant, this <Link> will be active.

I am going to implement the part of re-rendering the messages from other when the user close the private chat. I need saving the information of the closed chat and filter by using this information.

by Jaeeun(Anna) Cho ( at February 16, 2017 12:42 AM

February 15, 2017

Jaeeun Cho

CSS Pseudo-elements and SASS

CSS Pseudo-elements

I already took the JavaScript and CSS course in the second semester. Even though I learnt about the basic level of CSS from INT222, I didn't know well about the pseudo-elements of CSS. From the last task, my code was improved using pseudo-elements instead of using huge number for margin or padding.

To display the white line between the title and two circle, my code was

but it is changed to this.

fixed huge number on margin-left and top. Also it changed to use before pseudo-element.

-> it can be used to insert some content before the content of an element.

-> it can be used to insert some content after the content of an element.

:first-line / first-letter
-> it is used to add some specific style to the first line / letter of text.

-> it is to add style which are selected part by user.

More info of pseudo-elements : CSS Pseudo-elements

* !important rule in CSS
-> This rule is used on a CSS declaration, and it can override any declaration in CSS.
It is not recommended rule to use generally, but if specific style / CSS which is overrided by external libraries(Bootstrap) can allow to use !important rule. It can add the same line as CSS. ( padding: 0 !important; ).

!important rule
When using !important is the right choice

Sass (Syntactically Awesome StyleSheets)

* Sass is a scripting language which is interpreted into CSS. This is very useful script to improve CSS by using many function in Sass. There are two types of syntaxes in Sass. The first one is Scss which is extension of CSS. So, CSS can be worked the same meaning in SCSS stylesheet. Also SCSS understands the most CSS hacks and vendor-specific syntax. Another one is Sass which provides a more concise way of CSS writing. It uses indentation rather than brackets for nesting of selectors or classes. The indented syntax has all the same features.

References :  

SASS Style Guide
SASS Reference

by Jaeeun(Anna) Cho ( at February 15, 2017 10:40 PM

Henrique Coelho

Making a test suite for the front-end client

Test cases are a very important tool to have: they help us to know whether or not the program is working properly, and they also assure that future updates will not break what was already done. Making these tests on the backend of a program is relatively simple and common, but when we need to test the user interface, it gets a little more complicated. For our project, we have a JavaScript code that goes in the browser (the Observer), and we need to make sure all its functions that depend on the user input are working properly. In this post I will explain how I used to simulate user interactions for our client module.

Selenium is an application that automates your browser - it provides the tools that we need to create the user interactions, while is a Selenium ported for Node.js; but to use, we need selenium installed. It was simple enough, just using these commands:

$ curl -O
$ curl -L | tar xz
$ java -jar -Dwebdriver.gecko.driver=./geckodriver selenium-server-standalone-3.0.1.jar

And done, Selenium is installed and running.

Now, to install in our node project, we can simply use NPM:

npm install --save-dev webdriverio

And we are ready to go.

In a javascript file - the one we used to run the routines in the browser, we configure and start this way:

const webdriverio = require('webdriverio');

const options = {
    desiredCapabilities: { browserName: 'firefox' }

It is a very simple configuration in our case, since we want to use Firefox to run the test cases, and no other options were necessary. We can also use PhantomJS (an "invisible browser", but I think it is useful to have Firefox appearing, so we can inspect what exactly is happening).

Now to start and make it go to our test page:


When we run this javascript file, Firefox will pop up and open that file specified.

Now some commands we used to simulate user interaction:


    // Telling to click on a link (<a> tag) with the id "my-link":

    // Scrolling 300 pixels to the bottom and to the right
    .scroll(300, 300)

    // Filling an input (<input> tag) with the class "my-input" (the first input with this class, in this case) with the value "text""
    .setValue('', 'text')

    // Selecting the third option of a select box (<select> tag) with the id "my-select"
    .selectByIndex('select#my-select', 2)

    // Pausing for 2 seconds

    // Executing a JavaScript function in the browser and logging "Hello world" in the browser's console
    .execute(function () {
        console.log('Hello world');

    // Closing the browser and ending the tests

That's it! Using was surprisingly simple, and I was able to complete all the tests in a few hours.

Some commands were not available by, for example: selecting a text on the page. But I could overcome this using the .execute command and passing a function to select the text I wanted directly from the browser:

.execute(function () {
    // Element with the text to be selected
    const element = document.getElementById('div-with-text-to-select');

    // Creating a range around the element and setting it as the selection
    const range = document.createRange();

I was also able to fire custom events in the browser using the .execute command:

.execute(function () {
    // I want to fire the event from this element
    const element = document.getElementById('source-of-event');

    // Creating my custom event
    const event = new CustomEvent('eventName');

    // Firing

by Henrique Salvadori Coelho at February 15, 2017 09:19 PM

Kert Browne

Term 2 – Week 6

This week I was given two new UI tasks. The first was to have a label change from “Make fullscreen” to “Exit fullscreen” depending if the browser is in full-screen mode. Second was to fix a bug in the chat component. In some instances when new messages come in, the message list displayed would not auto scroll to the bottom. This meant the user would have to manually scroll down to see new incoming messages.

The Chat bug turned out to be a result of recent updates to the chrome browser. Initially the check to see weather or not to automatically scroll was:

const { scrollArea } = this.refs;
this.shouldScrollBottom = scrollArea.scrollTop + scrollArea.offsetHeight ===

A Boolean variable is set to be true if the scrollTop + offsetHeight equals the scrollHeight. This assumed that the scrollTop variable was an integer, once the update happened scrollTop changed to be a float in certain instances. To account for this and fix the bug the condition was changed to the following:

let position = scrollArea.scrollTop + scrollArea.offsetHeight;

//Compare with <1 to account for the chance scrollArea.scrollTop is a float
//value in some browsers.
this.shouldScrollBottom = position === scrollArea.scrollHeight || (scrollArea.scrollHeight – position < 1);
I Figured out how to switch the full-screen button label buy creating a new Boolean property on the parent component and pass it down to the child. From there i could use that to determine which label to show.

When this was set up and working i found a bug where if “Esc” was pressed to exit full-screen mode the state of the component would not change because the custom event triggered by the buttons onClick function was not being called. The custom events were removed and replaced with the following:

document.addEventListener(“fullscreenchange”, this.fullScreenToggleCallback);
document.addEventListener(“webkitfullscreenchange”, this.fullScreenToggleCallback);
document.addEventListener(“mozfullscreenchange”, this.fullScreenToggleCallback);
document.addEventListener(“MSFullscreenChange”, this.fullScreenToggleCallback);

by using these to detect when full-screen mode for the browser changes we then use the following callback function to affect the component state. :

fullScreenToggleCallback() {
if (screen.height – 1 <= window.innerHeight) {
// browser is probably in fullscreen
this.setState({isFullScreen: true});
this.setState({isFullScreen: false});

I will be revisiting the centering of the action bar buttons now that a design has been settled on. Once that is done i will be moving on to debugging some accessibility related issues.

by kdsbrowne at February 15, 2017 12:47 PM

February 13, 2017

Kevin Ramsamujh

OSD600: Thimble First Release

For my first bug on thimble I chose to work on adding the functionality to favorite or save certain projects and have them appear at the top of the project list when loaded. This bug was deemed not a good first bug shortly after I started working on it and the bug was then changed to create a local storage solution for favoriting projects. I was given great guidance on how to how and where to get started on the bug by other developers making the work load less overwhelming.

For this bug, I had to learn how to use local storage for the first time but the rest of the coding was pretty straight forward. For this first release, I had to edit 3 different files to add html elements to house the “favorite button”, add css styling for the button and then finally actually add in the functionality to save the favorite projects. When I began working on this bug it was a little bit confusing since I felt I was adding in so much new code to the project and I didn’t want to accidentally break anything as I was working on my bug. After I got comfortable with using the test environment, the rest was quite simple. I found the debugger in the Firefox web browser to be extremely useful when I ran into problems.

After getting the functionality of the bug working I realize that this is not just a small bug I am working on but a rather substantial feature and I expect there to be many optimizations to be made to the code that I wrote until it will be worth merging. I plan to continue to work on making changes to the code I wrote to get it up tot he standards needed to get merged into the thimble project.

by kramsamujh at February 13, 2017 02:24 PM

February 12, 2017

John Kim

Lab 3 Complete

Issue #1100

I feel really bad about this lab. I started with little bit of confidence on working on a different issue, which was Issue #1100. But I ended up not being able to solve the issue. I could not find out exactly what I needed to change in the code. I have used the browser inspection to figure it out, but due to lack of experience using it, I could not pin point the exact area in the code where I had to add or edit.

Issue #1722
Due to this, I decided to work on a different issue. This issue was about changing the html element's fade/refade transition time when a user hover overs an icon. To do this, I used the same approach I used for issue 1100. Used the inspector to locate the folders that contained the CSS code for each icon used in html. Then I tried to break the code by figuring out what each classes and elements did. I also had to understand what the CSS specific does did. Then I played around with the code by changing numbers, moving transition class to elements that may or may not require. After, I looked at the code carefully, and found part of the code that holds the actual transition time.

/* Transition time for hover effects */
@transitionTime: 0.15s;

.transition {
-webkit-transition: @transitionTime;
-moz-transition: @transitionTime;
-ms-transition: @transitionTime;
-o-transition: @transitionTime;
transition: @transitionTime;

.transition-only-opacity {
-webkit-transition: opacity @transitionTime ease-in-out;
-moz-transition: opacity @transitionTime ease-in-out;
-ms-transition: opacity @transitionTime ease-in-out;
-o-transition: opacity @transitionTime ease-in-out;
transition: opacity @transitionTime ease-in-out;

Then I came up with the idea to simply add the transition class into appropriate CSS element that required for the animation to occur. Now all I need to do in the end is to change the numbers on both CSS files to change the transition time to the developer's preference.

by pokim8989 ( at February 12, 2017 08:11 PM

February 11, 2017

Lawrence Reyes

Lab 06: Vectorization Lab

Source code:
#include <stdio.h>
#include <stdlib.h>

int main(void){
int a1[1000];
int a2[1000];
int a3[1000];
int i = 0;

long n = 1000000;

for(; i < 1000; i++){
a1[i] = rand()%100;
a2[i] = rand()%100;

a3[i] = (a1[i] + a2[i]) + n ;
printf(“a3[%d] = %d\n”, i, a3[i]);

Compiler command:
gcc -O3 lab6.c

Dissassembly listing:
4004c0:       a9bd7bfd        stp     x29, x30, [sp,#-48]!
4004c4:       910003fd        mov     x29, sp
4004c8:       a9025bf5        stp     x21, x22, [sp,#32]
4004cc:       90000016        adrp    x22, 400000 <_init-0x430>
4004d0:       a90153f3        stp     x19, x20, [sp,#16]
4004d4:       911cc2d6        add     x22, x22, #0x730
4004d8:       52800014        mov     w20, #0x0 //#0

4004dc:       52800c93        mov     w19, #0x64 //#100
4004e0:       97ffffe8        bl      400480 <rand@plt>
4004e4:       2a0003f5        mov     w21, w0
4004e8:       97ffffe6        bl      400480 <rand@plt>

4004ec:       1ad30c02        sdiv    w2, w0, w19
4004f0:       1ad30ea1        sdiv    w1, w21, w19

4004f4:       1b138040        msub    w0, w2, w19, w0
4004f8:       1b13d435        msub    w21, w1, w19, w21

4004fc:       0b0002a2        add     w2, w21, w0
400500:       1143d042        add     w2, w2, #0xf4, lsl #12

400504:       2a1403e1        mov     w1, w20
400508:       aa1603e0        mov     x0, x22

40050c:       11090042        add     w2, w2, #0x240

400510:       97ffffe8        bl      4004b0 <printf@plt>

400514:       11000694        add     w20, w20, #0x1
400518:       710fa29f        cmp     w20, #0x3e8

40051c:       54fffe21    4004e0 <main+0x20>

400520:       a94153f3        ldp     x19, x20, [sp,#16]
400524:       a9425bf5        ldp     x21, x22, [sp,#32]
400528:       a8c37bfd        ldp     x29, x30, [sp],#48
40052c:       d65f03c0        ret

Even though I used the compiler option -O3, highest compiler optimazation option, it did not fully vectorized my code it only did it partially.

I believe it just was not necessary in the case of my code since there is not much to optimize about it. It may, perhaps, have done it if I had perform the calculations in differents loops.

Volume-sampling-via-SIMD solution:
I have no solution yet.

by lawrencereyesoo at February 11, 2017 08:28 AM

Eugueni Antsyferov

OSD600 lab 3

I chose to work on issue 1665 for my first bug. I picked this bug because it seemed rather simple but could be very helpful to most people working on thimble. The first bunch of problems came from trying to set up thimble to run locally. It took me two days with the main problem coming from doing the “vagrant up” command in the wrong palaces. Once that got done I went to editing the html code for the loading project page. I added the link for the help page to show up whenever a project is loading. The text needed to be redone in a format similar to the surrounding text to have it show up it the correct language. I was not sure this was what the main developer wanted so I messaged him and asked when he would prefer the link to show up. He responded and said that for now the link should show up when a project is normally loading. When I tested the link I noticed that the color for it was too hard to read. Then I tried changing the color of the link to orange. This made the loading page not show up. Next I tried changing the link into a button. After this the link was visible. In conclusion even though this bug was fairly simple to fix it was still a struggle to get things just the way I wanted them.

Timble running locally: screenshot-23

by Genya Blog at February 11, 2017 05:39 AM

Dmytro Sych

Contributing to Thimble

Contributing to Open Source could be tricky and I’ve been able to experience how bad it gets over the last week. Choosing an Open Source project to contribute to was not a hard task, it was pretty much decided for us. Mozilla’s Thimble project is an open source online editor for people who are in the process of learning HTML, CSS, JavaScript. There were a bunch of issues labeled as “good first bug” and I thought it was the way to go. The actual bugs looked pretty much the same for me – I did have any clue of how to solve them. Eventually, I ended up picking this issue. The problem was that nav header was moving to a weird position when window was to narrow.

In the issue discussion, there has already been some thoughts on where this problem might be living. You see, Thimble projects actually consists of two sub-projects: Thimble project and Mozilla’s Brackets project. Brackets is the actual editor and Thimble is just a host for the iframe that contains Brackets. This  is done due to certain security concerns, since Brackets is running JavaScript this could lead to a potential breach. To avoid it, Brackets and Thimble are hosted on different services which eliminates a possibility of outside interference.

Installing and running Thimble was pretty easy thanks to this blog post. Here are a couple of screen shot of how Brackets and Thimble works.

Brackets (note names for editor parts in red):


and Thimble (note nav headers of Thimble that are synchronized with Brackets):


Initial comments suggested to look for the issue inside Thimble, so I’ve spent next couple of days looking in the wrong place. I think of it as a great insight on the system, since it gave me vague understanding of how Thimble works. Hours of stepping through the code landed me in Brackets, in the Bramble extension. It was a whole new portion of the system, so it took me an other day to finally find something useful. I’ve stumbled across a set of triggers that listened for layout updated. From there it was easy enough to locate the code that actually updates the layout.

At this point, I thought that my problem has finally appeared. Hours of code tinkering proved me wrong. So I sought help from projects developers. David Humphrey was really helpful in providing some valuable information regarding how modules interact with each other. His comments has also strengthened my suspicions of certain parts of the code. The follow-up talk with a friend, who was working on a new extension for Brackets, has cleared the rest of grey areas and allowed me to pin point the exact cause of the problem.

The issue was caused by the action sequence of how cached width for editor had been initialized. Brackets and Thimble use percentage-based system to update the layout, but it seems that cached values are stored as pixel values. Of course, this wasn’t my initial thought, one my initial pull request I’ve just deleted code that initialized the value of the editor. I admit, it wasn’t my brightest idea. After a couple of comments, I was able to come up with a proper formula for editor’s width initialization.

Thimble issue :
Pull request :


by dsych at February 11, 2017 12:40 AM

February 10, 2017

Matt Welke

Time for Documentation

After completing our interview with Seneca today where they wanted to learn about our project, we uncovered a few bugs in our Analytics module. Seneca wanted a few screenshots of our queries as a demonstration so we had to fix this before we could provide them. We wanted to show them a particular detailed hit with a good variety of actions, but we can’t if it only ever shows one hit, but when you ran a “Hit Story” query (which displays detailed information about the hit along with a time line of the actions for the hit) it would always show you one particular hit instead of the one indicated by the field. It turns out way back when we did our refactor of the Dashboard (then called the Visual Analysis Tool) from pure React to React with Redux, we had that bug show up. We were so focussed on making the newer “entity” queries (which allowed joins and CSV output) that we didn’t notice this being broken. We weren’t testing it (hmm, perhaps time to invest in creating unit tests…).

Now that that is taken care of, we’ll continue with creating documentation (which will include screenshots of the polished Dashboard, so we need to finalize that). I’ll be concentrating on the documentation, meanwhile my team mate will be focussing on creating a more robust user login system for the Dashboard. Right now, we just have usernames and password hashes hard coded in the config. This is unsecure, inconvenient, and not scaleable. We’re going to use authentication libraries and store usernames and hashed passwords in the MongoDB database instead.

For anyone curious, documentation can be found here!

by Matt at February 10, 2017 10:43 PM

Jerry Goguette

Bug fix – release 0.1

For the past couple of days, I spent learning the environments, vagrant, npm and understanding my bug.

This was the bug I decided to work on.
This issue addressing the ability to insert code snippets into files.

For example, when editing HTML, it might be nice to have a dropdown that lets users add…

  • A bulleted list with a few blank items
  • A small form
  • An empty HTML comment
  • A definition list
  • An empty table…

We could have different snippets depending on the type of file being edited.

For this issue  I decided to split it into 2 parts:

  • Bramble Side of things (Functionality)
  • Thimble Side of things(UI)

So far I’ve gotten the Bramble Side of things working. In addition, I’ve submitted a pull request and gotten it successfully merged.
Pull Request:

To get that part of the code working I got helpful advice from Luke Pacholski, David Humphrey, Gideon Thomas. However, it took me a while to fully understand the flow of the program and how to get things working.

After debugging the code I ended with a working solution:


After getting this far, I’m now about to undertake part 2 of this bug/issue.

Stay tuned for the next release!

by jgoguette at February 10, 2017 10:23 PM

Lawrence Reyes

Lab 04: Compiled C Lab

In this lab we were tasked to write a program and compile it with different compiler options in GCC, also check the difference withing the Disassembly part of the code in the objdump output.

Both the code I wrote and the string to be printed can be found in the <main> section of the disassembly part of the objdump output.

/*Added the compiler option -static*/

gcc -g -static -O0 -fno-builtin hello.c
objdump -f -s -d –source | less

000000000040096e <main>:
#include <stdio.h>

int main(){
40096e:       55                      push   %rbp
40096f:       48 89 e5                mov    %rsp,%rbp
printf(“Hello World\n”);
400972:       48 8d 3d cb 6b 08 00    lea    0x86bcb(%rip),%rdi        # 487544 <_IO_stdin_used+0x4>
400979:       b8 00 00 00 00          mov    $0x0,%eax
40097e:       e8 5d 6a 00 00          callq  4073e0 <_IO_printf>
400983:       b8 00 00 00 00          mov    $0x0,%eax
400988:       5d                      pop    %rbp
400989:       c3                      retq
40098a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)


-The size of each section increases.

-Some of the section headers like .gnu.hash, .dynsym, and .dynstr are no longer part of the objdump.

-Each line number ID is now continuous.

-Some of the <main> output changed.

00000000000006c0 <main>:
#include <stdio.h>

int main(){
6c0:   55                      push   %rbp
6c1:   48 89 e5                mov    %rsp,%rbp
printf(“Hello World\n”);
6c4:   48 8d 3d 99 00 00 00    lea    0x99(%rip),%rdi        # 764 <_IO_stdin_used+0x4>
6cb:   b8 00 00 00 00          mov    $0x0,%eax
6d0:   e8 8b fe ff ff          callq  560 <printf@plt>
6d5:   b8 00 00 00 00          mov    $0x0,%eax
6da:   5d                      pop    %rbp
6db:   c3                      retq
6dc:   0f 1f 40 00             nopl   0x0(%rax)

/*Removed the compileroption -fno-builtin*/

gcc -g -static -O0 hello.c
objdump -f -s -d –source | less

The differences in the function call are in these lines:

400972:       48 8d 3d cb 6b 08 00    lea    0x86bcb(%rip),%rdi        # 487544 <_IO_stdin_used+0x4>
400979:       b8 00 00 00 00          mov    $0x0,%eax
40097e:       e8 5d 6a 00 00          callq  4073e0 <_IO_printf>
400983:       b8 00 00 00 00          mov    $0x0,%eax

400988:       5d                      pop    %rbp
400989:       c3                      retq
40098a:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)

400972:       48 8d 3d eb 6c 08 00    lea    0x86ceb(%rip),%rdi        # 487664 <_IO_stdin_used+0x4>
400979:       e8 22 71 00 00          callq  407aa0 <_IO_puts>
40097e:       b8 00 00 00 00          mov    $0x0,%eax

400983:       5d                      pop    %rbp
400984:       c3                      retq
400985:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
40098c:       00 00 00
40098f:       90                      nop

/*Removed the compiler option -g*/

gcc -static -O0 hello.c
objdump -f -s -d –source | less

-Some sections in the objdump output have increased

-The section headers have not changed at all.

-Function call changes:
000000000040096e <main>:
#include <stdio.h>

int main(){
40096e:       55                      push   %rbp
40096f:       48 89 e5                mov    %rsp,%rbp
printf(“Hello World\n”);
400972:       48 8d 3d eb 6c 08 00    lea    0x86ceb(%rip),%rdi        # 487664 <_IO_stdin_used+0x4>
400979:       e8 22 71 00 00          callq  407aa0 <_IO_puts>
40097e:       b8 00 00 00 00          mov    $0x0,%eax
400983:       5d                      pop    %rbp
400984:       c3                      retq
400985:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
40098c:       00 00 00
40098f:       90                      nop

000000000040096e <main>:
40096e:       55                      push   %rbp
40096f:       48 89 e5                mov    %rsp,%rbp
400972:       48 8d 3d eb 6c 08 00    lea    0x86ceb(%rip),%rdi        #
487664 <_IO_stdin_used+0x4>
400979:       e8 22 71 00 00          callq  407aa0 <_IO_puts>
40097e:       b8 00 00 00 00          mov    $0x0,%eax
400983:       5d                      pop    %rbp
400984:       c3                      retq
400985:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
40098c:       00 00 00
40098f:       90                      nop

The disassembly main does not give a detailed description of the code and which lines are related to which part of the code.

/*Added arguments into the code of hello.c so it has 10 arguments instead of 1.*/

gcc -static -O0 hello.c
objdump -f -s -d –source | less

000000000040096e <main>:
40096e:       55                      push   %rbp
40096f:       48 89 e5                mov    %rsp,%rbp
400972:       6a 09                   pushq  $0x9
400974:       6a 08                   pushq  $0x8
400976:       6a 07                   pushq  $0x7
400978:       6a 06                   pushq  $0x6
40097a:       41 b9 05 00 00 00       mov    $0x5,%r9d
400980:       41 b8 04 00 00 00       mov    $0x4,%r8d
400986:       b9 03 00 00 00          mov    $0x3,%ecx
40098b:       ba 02 00 00 00          mov    $0x2,%edx
400990:       be 01 00 00 00          mov    $0x1,%esi
400995:       48 8d 3d cc 6b 08 00    lea    0x86bcc(%rip),%rdi        # 487568 <_IO_stdin_used+0x8>
40099c:       b8 00 00 00 00          mov    $0x0,%eax
4009a1:       e8 6a 6a 00 00          callq  407410 <_IO_printf>
4009a6:       48 83 c4 20             add    $0x20,%rsp
4009aa:       b8 00 00 00 00          mov    $0x0,%eax
4009af:       c9                      leaveq
4009b0:       c3                      retq
4009b1:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
4009b8:       00 00 00
4009bb:       0f 1f 44 00 00          nopl   0x0(%rax,%rax,1)

All arguments are place in registers from 0x1 to 0x9 in reverse order.

/*Moved the printf() call to a separate function named output()*/

gcc -static -O0 hello.c
objdump -f -s -d –source | less

00000000004009ad <main>:

int main(){
4009ad:       55                      push   %rbp
4009ae:       48 89 e5                mov    %rsp,%rbp
4009b1:       b8 00 00 00 00          mov    $0x0,%eax
4009b6:       e8 b3 ff ff ff          callq  40096e <output>
4009bb:       b8 00 00 00 00          mov    $0x0,%eax
4009c0:       5d                      pop    %rbp
4009c1:       c3                      retq
4009c2:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
4009c9:       00 00 00
4009cc:       0f 1f 40 00             nopl   0x0(%rax)

Now instead of givin a different value to an array of directories it only calls the memory address of the function output(), and outputs it.

/*Removed -O0 and added -O3 to the compiler option*/

gcc -static -O3 hello.c
objdump -f -s -d –source | less

00000000004005b0 <main>:

void output(){
printf(“Hello World\n %d, %d, %d, %d, %d, %d, %d, %d, %d\n”, 1, 2, 3, 4, 5, 6, 7, 8, 9);

int main(){
4005b0:       48 83 ec 08             sub    $0x8,%rsp
4005b4:       31 c0                   xor    %eax,%eax
4005b6:       e8 d5 03 00 00          callq  400990 <output>
4005bb:       31 c0                   xor    %eax,%eax
4005bd:       48 83 c4 08             add    $0x8,%rsp
4005c1:       c3                      retq
4005c2:       66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
4005c9:       00 00 00
4005cc:       0f 1f 40 00             nopl   0x0(%rax)

There is not much difference in my opinion. Did not really find anything different in the compiled code.

by lawrencereyesoo at February 10, 2017 10:08 PM

Lab 02: Code Building Lab

Downloading and installing software in a Linux distribution is much different than a Windows or Mac. Since Linux is more of a command line based OS, the user is expected to know all the commands to perform all the task he/she would like perform in their computer.


Installing the gcc software into my linux computer was not hard at all. Just had to find the command to be able to download the software and install it right away, “apt-get install (software)”, and then I was able to use it without any problem.


Downloading and installing Calcurse was just as easy as GCC. Used the same command to install it, “apt-get install Calcurse”. As soon as all the dependencies were downloaded and installed the software was ready for use.

In conclusion, downloading and installing software into a Linux distribution is fairly simple. Sometimes some dependencies must be downloaded separately from the software, other than that it not much of a hard task.

by lawrencereyesoo at February 10, 2017 09:59 PM

Theo D

Blog Post 5 – Merge and Conflicts (Lab4)

This week I got a chance to work with branches, merging them and sorting conflicts. It was definitely an interesting lab, which I had to do twice because I lacked the attention to detail the first time doing it. For example adding and committing, I would forget to do either of them and I would confused to see why my branches weren’t differentiating.

Screen Shot 2017-02-09 at 5.50.09 PM.png

I was able to work with branches that point to other branches, as the example above where water-animals points to animals.

After creating and making sure that all branches were added and properly committed, I was able to move onto merging as seen below:

Screen Shot 2017-02-09 at 6.10.21 PM.pngIn which I was able to simulate the same conflict that was found in the lab instructions, and was able to see the problem directly.

Screen Shot 2017-02-09 at 6.13.27 PM.png

Here you can see the conflicting parts starting with the HEAD and the tail of which belongs to jungle-animals. This problem was fixed simply by using the Vi editor to erase those markers and make sure the file no longer had anymore conflicts.

After creating the final branch and creating an html variant of the file by using copy and paste command in terminal to create the html bullet points. I then proceeded to copy and rename the file using the command mv followed by the filename.html.

Screen Shot 2017-02-09 at 6.27.38 PM.png

Once this was all completed, I was able to push the repository back onto GitHub and have a a fully running html page running at the following link: Which resulted in:

Screen Shot 2017-02-10 at 3.10.56 PM.png


by theoduleblog at February 10, 2017 08:11 PM

Oleg Mytryniuk

Mozilla got a new contributor :)

To be honest at the beginning of the week, I doubted that on Friday I will be writing the post about my successful completion of the assignment. Having some problems with setting up the environment I was not able to start fixing a bug until this Tuesday. Nevertheless, I was able to complete the task щт ешand such things always inspire me to learn and try more things.

As I have described in my previous post, I had some issues with running Thimble on my local machine. I would even say that installing everything was even bigger challenge than fixing the bug. At the same time I really enjoyed trying to figure out the issue and fixing it.

During the class I have chosen the next bug: When you open the list of your projects and click on one of them, by default the project will be opened in the same tab, and there is no option to open it in a separate tab.


Basically it was supposed to be something like this:


I decided to choose the bug, because:
1) this issue seems to be really annoying and as a user, I would definitely want to have two options(opening a project in same or opening it in another tab).
2) it did not look hard on the first look to solve the issue. It was one of my concerns: what if I took a hard bug to fix?

When my environment was ready, the first thing I did – I have reproduced the issue. It is the first step we should do when we start to work on a bug. After that I started to try different solutions to solve the problem. It is important to mention that I was very excited by the assistance provided by my professor and by Thimble Open-Source Community. They helped me with different ideas that I could implement to fix the issue.

First of all, I spent some time to get familiar with Google Chrome Debugger, because it was a tool I was using for fixing the bug. The lecture on last Friday where the professor covered some debugging skills was very useful. I set some breakpoint that allowed me to see the workflow of the app and to see the piece of the code where the issue occurred.

My problem was that when we click on the project name text, it makes a call to the function that generates and opens the link. This function did not have any logic that would allow us to have two options(open in a current vs open in a new tab) to open the link.

At the begging I was thinking to change the link, but based on the advice I got from the professor and the members of the Thimble community, I have just made the project name text as a link, wrapping it in anchor. It was not hard to do that. Once I have completed that, I noticed the small problem: instead of having beautiful button we had before – I got an ugly blue underscored link text.

I guessed that solution for the problem is to fix .css class that is responsible for the class where our anchor is placed in. Again, using Chrome Debugger, I have found the class called ‘project title’, as well as a css source file for the tag. In my next step I have updated the css file adding this line:

.project-title a{
color: #000000;
text-decoration: none;

Instead of overriding the particular class or tag (that can cause some problems), I have decided to create a separate style for our Project Name tag only.

The last step was to delete the listener that was listening when we click on the project name. Since, we use a regular link now, there was no reason to keep the listener. I have double checked whether other parts of the app use the listener, but I did not find another usage of it. DELETED it 🙂

Basically, after that I have confirmed that the app is stable after my changes. My code was ready to be committed and I have pushed it to my fork. I could do it successfully.

The last step was to merge my changes with the main Thimble repository. I did that and   ….my code did not pass Trevis.
Since I have deleted the listener, there were a few variables that were used by the listener function, and after the deletion these variables were not used anywhere else in the code and because of these warnings github did not submit my code. Information about the bugs were clearly provided by Trevis and it was not hard to find the issue and to fix it.

Then I did another commit and pushed and … my code was automatically was picked up for merging! Is not it awesome?!! 🙂

Just in case I have decided to check again the changes I made and I have noticed that in my css code:

.project-title a{
text-decoration: none;

1. I did not put a space after color:
2. I used color name instead of hexadecimal value of colors (I checked the css style the community uses).

That is why I have changed my code again and commited/pushed my final changes afterwards:

.project-title a{
color: #000000;
text-decoration: none;

We should follow the community style and do not make our community disappointed 🙂

To sum up, it was great experience to contribute to the Thimble community. I did many things: improved my git skills, learnt Chrome Debugger, reviewed JS. It was a very interesting assignment the result of what is my first contribution to Mozilla Community!

The course starts to become more and more interesting. I really enjoy it.





by osd600mytryniuk at February 10, 2017 07:39 PM

Rahul Gupta

Release 0.1 – Fixing issue #1703

The bug i chose to fix on mozilla was – Cursor property is not changed when hovering on a folder #1703. 

The problem with the bug was that whenever we hover the mouse over any folder in the file tree, the mouse coursor is set to default instead of pointer.


The fix to this issue was in the css file. The general idea that comes in mind was to set the cursor property to pointer instead of default. I had to do two major changes first change the sidebarTheme.css file and add the cursor: pointer !important; keyword in the two folders but later on as suggested there was even a simpler fix to that where i just need to change the default cursor pointer in the jsTreeTheme.css file. 


My fix and release is detailed here –

I really enjoyed working on one of the bug at mozilla. It was really successful and accomplishing. Overall it was really encouraging to contribute one of the mozilla’s project. This would definitely motivate me to work on other projects.


by rahul3guptablog at February 10, 2017 06:38 PM

Margaryta Chepiga

Finding a Bug to Fix in Mozilla Thimble

Moving forward to the new horizons of Open Source world. To get more familiarised with Open Source and the way it works. For the past week I’ve been working on couple of things.

  1. Introduction to Thimble

We are going to fix a bug in the Thimble project. In order to do that, my Professor provided us with a walkthrough blog post. Which I can certainly say, was extremely helpful.

First, I got familiar with a Thimble project as well as Brackets. Then I went to this github page to see what bugs are open. There were a big variety of bugs, even bugs with Virtual Reality, which looks extremely interesting. However, I was looking on something that I can handle with the amount of knowledge I have. Which was not an easy thing to do, since most of the easy bugs were taken really fast. So I choose this one.  The reason I choose it, was not because I am extremely good with JavaScript, but because it looked interesting and not way out of my league. I decided to try my best and see how it goes.

2. Setting up Bramble and Thimble

So I picked a bug that I want to fix. What next?

The next step is setting up the environment. The installation instructions that I followed were provided by Thimble here. Instructions are clear and straightforward. However, I was still able to run into problems. I followed the instructions and everything was going great until I got to the Vagrant part. To be more specific vagrant up command. The problem that I got was that my port number was occupied, and I couldn’t run the Vagrant. I tried to fix it in different ways. Changing the port number, restarting my laptop, trying to figure out why the port number is occupied and with what. However, nothing of this worked. I was getting upset, I didn’t know what to do. Then situation got even worst. My only laptop got broken. So I gave to my friend who was fixing it, while I was trying to set up the environment on the laptop that I borrowed from my friend. And I got the exact same issue again. So I tried again and again. I end up reinstalling all of the components required, but it didn’t help. Did I end up setting up the environment? Yes. How? My friend fixed my laptop, and with a fresh just installed Ubuntu everything finally worked.

thimble loginsuccesful brackets


by mchepigaosd600 at February 10, 2017 04:57 PM

Andrey Bykin

Release 0.1 Fixing a bug in Thimble

For the first release of class OSD600, I choose to fix a bug found in the thimble project ran by mozilla. The issue located here:

Was a minor bug in the code editor which caused the font size to have a minimum of 1px and maximum of 72px when using the increase/decrease font size buttons. The first real challange was installing the necessary components in order to reproduce the bug locally. To go about this, I installed thimble and brackets locally and after some debugging was able to get the server running and able to reproduce the issue.


Now to figure out on how to fix the issue with the font sizes, I backtracked from using the button directly and tried to connect it to the code. I found possible 4 places where either the font size gets set or where a function is being called in order to connect to a  listener to handle the method. After much investigation and looking up I stumbled across this piece of code.


So as you can tell someone already has the minimum and the maximum set for the font size, as such the solution was simply to change them to appropriate values. In this case 8 for minimum and 32 for maximum.

After fixing the bug I committed the changes locally and submitted the pull request at :

As of today the request has been merged to main branch and the issue is now fixed!

If you would like to work check out the thimble project here are the two links :

Thimble :

Brackets :

by Andrey Bykin at February 10, 2017 04:44 PM

Jerry Goguette

Fixing a bug in Thimble(Mozilla)

To participate in the Thimble Open Source Project, I needed to set up my environment.

Click here or here for instructions on getting started.

Setting up Thimble locally on my computer was easy. However, I did run into a few hiccups.
Firstly, After installing node.js on my windows 10 machine, I could not access the npm command in the terminal at will. To solve this I had to add npm to the systems environmental path variable.

Here is an example of how it looks when Brackets(Bramble) is up and running:



Here is an example of how it looks when Thimble is up and running:


After everything is setup and running, I chose the issue,
This issue addressing the ability to insert code snippets into files.

For example, when editing HTML, it might be nice to have a dropdown that lets users add…

  • A bulleted list with a few blank items
  • A small form
  • An empty HTML comment
  • A definition list
  • An empty table…

We could have different snippets depending on the type of file being edited.

For this issue  I decided to split it into 2 parts:

  • Bramble Side of things (Functionality)
  • Thimble Side of things(UI)

Stay tuned for the progress on this bug!

by jgoguette at February 10, 2017 04:19 PM

Timothy Moy

OSD600 : Fixing My First Bug in Thimble

Before diving into the serious stuff, status report on  my previous pull request: it’s been merged! It feels good to have been able to contribute to the community, even with such a small thing.

Anyways, here is a follow up to the blog post about setting up thimble. Basically, this post will bring you up to speed on what I did with the bug.

Understanding the Problem

Before attempting to solve anything, you need to first understand it. I launched up thimble, right-clicked the “auto-refresh” box and that enabled me to find the related html file. From that file, I found that the check mark being displayed or not was controlled by a CSS class that was removed or added to the class attribute via javascript.

From that point on, figuring out the cause was easy! The html had the check box div as:

<div class="refresh-wrapper enabled">

Which meant that the .enabled class was loaded every time the window was loaded (or refreshed!). But how can we have the class not load if the user had last made the check box unchecked? We can’t.

Solving the Problem

However, we can find similar code and follow their pattern. In that sense, I noticed the username being displayed was similar in function to our setting so I searched the files in the repo for the html file and found this:

<div id="navbar-login" class="{% if username %}signed-in{% endif %} nav-chunk">

Conditional class using an if statement based on a variable? Sounds like a potential fix could adapt the code into:

<div class="refresh-wrapper {% if auto-refresh %}enabled{% endif %}">

Alas, things are never as easy as they seem. Since the files were slightly formatted differently, I had to change my approach a bit so that my script didn’t get ignored due to the quotation marks. Here’s what actually works:

<div class={% if autoUpdate %}"refresh-wrapper enabled"{% else %}" refresh-wrapper"{% endif %}>

Not a huge change, but worlds apart in terms of it working or not. So, it seems like we’re all done, right? Not quite.

The variable autoUpdate doesn’t exist outside a temporary scope. We need a way to store it like a preference or username. To that end, Gideon suggested using a pattern similar to humphd’s in this issue. I tried to do that, but my attempts made no progress in resolving the issue. I also tried the pattern from this fix also with nothing to show for it.

Next Steps

As of now, I know what needs to be done:

  • Figure out how to implement the pattern for localstorage properly for my case
  • Set the new variable everytime the user toggles the option
  • Make the correct call to properly load the value after a refresh

Once those are figured out, the only thing left would be formatting, styling and documentation. Stay tuned for the follow up!

by Timothy Moy at February 10, 2017 09:35 AM

Zenan Zha

Lab3 first issue(#1608)

This bug become the most challenge bug I have ever fixed.
I spend the first week on hosting thimble on my own laptop.
The I started working on AFrame VR on the second week.
In the beginning, I am working on two issues with AFrame VR.
I have no idea which one I can fix.

On this Tuesday, my prof suggested me to switch to another topic because I might not be able to finish this bug before Friday.
However, I am sooooo interested in VR topics so I kept working on my issues.

I finally fixed one of my issues tonight, so I am writing my blog here.
Issue 1608:
Here is the detail of my issue: #1608.

The problem I have and how I fix it:
The first problem I have to solve is how to reproduce the bug on my device.
I published a sample VR website on thimble, and I successfully reproduced the bug on my phone and Lenovo pad.
However, I cannot debug on my phone or pad.
When I comes to my laptop, the remix button just jump to the top of the webpage, so there is no bug anymore.
I use the Chrome web debugger to find out which div I want to find.
I find the right div and the right css class.
There is a certain class called touch-mode that determine where the remix button is.
I spend 6 hours on try to reinstall thimble on my pad but I failed.
I finally find out that Chrome debugger could change the css directly.
I tested my change on the chrome and push the new branch on to github.

Here is my pull request:#1724

by zenan zha ( at February 10, 2017 07:06 AM