Pages

Custom keyboard shortcuts in ubuntu

Creating a custom keyboard shortcut

Let us look at how can we create a custom keyboard shortcut to launch an application in ubuntu. As an example let us try to create a shortcut to launch the firefox browser using a keyboard shortcut.

1. Open a terminal and run the command "goconf-editor"

2. Go to apps->metaciy->keybinding_command
    on the right side you will see a list command_1, command_2 ..etc.


3. Double click on command_1 option which should launch a small window where you need to enter the command to launch the application you want the shortcut for.


4. The command to launch firefox from command line is "firefox", hence enter "firefox" in the space provided and click "ok".

5. Now go to "global_keybindings" under "metacity"

6. On the left window search for the option "run_command1" ( If  in the 3rd step you choose any other number of command go to the run option of that command number).

7. Double click on the option and enter the shortcut you would like to use to launch firefox. Let us say you want to launch firefox every time "Alt+m" is pressed then enter "m" .

8. Close the configuration editor and its done.

9. Press Alt+m any where in your system and it should launch firefox automatically.

Using getopts to read commandline arguments

getopts is used in scripting to parse command line arguments. The arguments passed on the command line are parsed in the script using a string which is a string made by separating the argument names by colons.
 For example if the arguments passed were named a,b,c,d, the string would be made up as follows a:b:c:d where the colon after the name specifies that the variable is expected to be associated with a value on the command line.
Internally getopts uses OPTIND to index the arguments and OPTARG to read the value of arguments.

Here is an example :

#!/bin/bash

while getopts a:b:c:d: opts   # using getopts to parse the command line options
do
echo "index $OPTIND"          # printing the index of the argument being parsed
    case "$opts" in
    a) one="$OPTARG"      # Using OPTARG to get the value of the argument
     echo $OPTARG ;;
    b) two="$OPTARG"
     echo $OPTARG ;;
    c) three="$OPTARG"
     echo $OPTARG ;;
    d) four="$OPTARG"
     echo $OPTARG ;;
    esac
done


echo " one = $one two = $two three = $three four = $four"

Save the above script as gopts_example.sh and execute it as follows

sh getopts a 1 b 2 c 3 d 4
output :

index 3
1
index 5
2
index 7
3
index 9
4
one = 1 two = 2 three = 3 four = 4



From the output we see that the OPTIND stores the index of argument it is reading and OPTARG stores the value.

The index can be reintialized to "1" to restart the parsing of the arguments, as shown in the script below.

#!/bin/bash

while getopts a:b:c:d: opts   # using getopts to parse the command line options
do
echo "index $OPTIND"          # printing the index of the argument being parsed
    case "$opts" in
    a) one="$OPTARG"      # Using OPTARG to get the value of the argument
     echo $OPTARG ;;
    b) two="$OPTARG"
     echo $OPTARG ;;
    c) three="$OPTARG"
     echo $OPTARG ;;
    d) four="$OPTARG"
     echo $OPTARG ;;
    esac
done

echo " one = $one two = $two three = $three four = $four"
OPTIND=1          # Reinitialize the OPTIND to 1

while getopts a:b:c:d: opts   # Repeat the same loop as above.
do
echo "index $OPTIND"         
    case "$opts" in
    a) one="$OPTARG"     
     echo $OPTARG ;;
    b) two="$OPTARG"
     echo $OPTARG ;;
    c) three="$OPTARG"
     echo $OPTARG ;;
    d) four="$OPTARG"
     echo $OPTARG ;;
    esac
done


As opposed to the standard way of parsing the command line arguments using the $ symbol, it is simpler to parse it using the getopts as we need not keep track of the index numbers of the arguments being passed and the number of arguments being passed.
Even if the order of the arguments passed is not the same as mentioned in the string, i.e. a:b:c:d in our case,  getopts would still be able to parse it successfully.

If any of the expected arguments is not passed on the command line then it is assumed to be blank and no error is thrown.



Cache Coherence

cache Coherence:

Cache coherence is a issue that is faced in multicore systems, when each core has its own private cache. For example consider the following system, which has two cores. each core has its own private cache and a common share memory. The sharing of the main memory could be on a bus or on an interconnection network.





Because the main memory is shared the cache of both the systems store in them the memory locations from the same memory. There are three possible cases in such a situation.


Case 1:

Both the caches store different memory locations. As shown in the figure below, the caches might have data from different memory locations and hence do not have any common memory location between them. In this case there is no problem as the data in both the cache can be modified with out any issues.






Case2:

The caches might store a common location in them. Let us the memory address 100 is being stored in both the caches. Assume the data in the memory location 100 is 10 initially as shown below.








Let us assume the following set of operations are done on the memory location 100

1. P1 Increments the value at memory location 100 by 1 making it 11.

If the cache is write back, this change will not be reflected in main memory instantly and even if the cache is write through the change in the data will only be visible to the main memory but not to the cache of the processor p2.

2. P2 Reads the data from memory location 100.

 As the change in the value has not been informed to the cache of processor P2, it contiues to read the older value of 10, which is the wrong value.
Thus we see that there is need for the change in the value of a memory location that is being cached by different processors to be informed to all the caches that are sharing the memory location so that they can be updated.
This process of keeping all the cache up to date is termed as cache coherence. This is done in two ways.

Invalidation:
If one processor modifies the data in a share memory location, all the other caches are informed about this and they in turn invalidate the corresponding memory locations. Thus the next time the processor issues a read it will lead to miss and thus fetch the updated data from the main memory .



Update:
The second method is to send the updated data of the memory location to all the cache. Thus all the caches can update themselves with the new data so that any for further reads will have the update data in them.






Coherence Misses:




Because of the coherence issues explained above, multicore systems have a new kind of miss other than the usual , capacity,conflict and compulsory,  that is coherence misses. These are misses that occur when a cache block gets invalidated because of a write in some other cache. Thus any future reads to that block will lead to a miss and the read will have to fetch the data from main memory or the cache that has the update data.


To handle the coherence issue there are a number of protocols that are used the most often used ones are

Invalidation based  :  Protocols which invalidate other copies of the data on a write


MSI Protocol  (Modified Shared Invalid)
MESI protocol  (Modified Exclusive Shared Invalid)
MOESI protocol  (Modified Owned  Exclusive Shared Invalid)


Update Based :  Protocols which send the updated data to all the  caches on a write


Dragon protocol.