Pages

Wednesday, May 15, 2013

Software Design: Lazy Initialization - I4SWD Obligatorisk opgave

Gruppenavn: HalfEasyMode
Gruppedeltagere: Khaled Saied 11638, Niclas Skødt Gleesborg 11651
Emne: Lazy Initialization

Beskrivelse: 

Lazy Initialization går ud på kun at initialisere objekter når man får brug for dem. Dvs. hvis objektet ikke skal bruges bliver det ikke initialiseret og man har på denne måde sparet både på memory og performance.

Et eksempel kunne være, at man har et kunde objekt, som har en ordrer property, som indeholder et stort array af ordrer objekter, som ville kræve forbindelse til en database for at blive initialiseret. Hvis brugeren aldrig spørger om, at få vist ordrer eller anvende disse data er der ingen grund til at bruge memory eller tid på at forbinde til databasen og behandle dataen. Ved at bruge Lazy Initalization kan man undgå at spilde dyrebar ressourcer på objekter, som aldrig bliver brugt.

Lazy Initialization kan også medvirke til hurtigere opstart af programmet, da de forskellige ressourcer initialiseres efter behov,istedet for under opstart af programmet. Svagheden her er så, at programmet kan være langsommere under kørsel da objekterne skal initialiseres.

Sammenligning med andre emner:

Singleton kan med fordel benytte Lazy Initialization da det ligger i Singleton's natur, at kun et objekt skal eksistere og med Lazy Initialization kan man undgå at objektet bliver initialiseret før der er brug for det, hvis der overhovedet bliver brug for det.

Det omvendte at Lazy Initialization er Eager Initialization, hvor man initialisere objektet med det samme. Fordelen med dette er, at computere ikke skal bruge ressourcer på at initialisere objekter imens programmet kører, men har sørget for dette under opstart. Generelt kan man sige at Lazy Initialization er godt for memory, dårligt for performance og Eager Initialization er godt for performance, dårligt for memory.

Eksempler:













Det kan ses ud fra consol outputtet at Lazy Initialization gør, at der ikke bliver brugt memory før objektet skal bruges. Hvorimod Eager Initialization bruger alt memory med det samme uden at vi skal bruge objektet.


Konklusion:

Det giver ingen mening at bruge Lazy Initialization på primitive datatyper eller generelt små objekter. Det giver mening i et miljø med få ressourcer mht. memory. Lazy initialization anbefales til kommunikation med databaser eller internettet generelt. Hvis miljøet er begrænset af performance og ikke af memory kan Eager Initialization vær et bedre valg.

Thursday, December 13, 2012

ISU - Exercise 11 - IPC

Goal:

The goal of this exercise is to get familiar with fork(),  _exit() and wait() and get an understanding of inter-process communication. Know what a child inherent from its parent and what shared memory is used for.

Exercise 1.1: Simple process creation

Our program:


Output:


Explain the value of the PIDs and the return values from fork() - how can one function return
two different values?
The child will return 0 on fork() and the parent will return the real pid of the child. When fork() is being executed a new process is being created which means the int pid will exist both in the parent and in the child and contain two different values will have been assigned.


Explain what happens when a process is forked:
What happens to the memory from the parent passed to the child?
The child gets a complete virtual copy but only if the child writes to the memory will it phsycally get its own. This is to ensure if you clone a progress that takes up ex 1GB of memory there is no need to physically require 2GB's unless the child needs to manipulate it.
What is passed to the child process and what is not?
The child does not get mutexes or semaphore locks. It also doesn't inherent any timers.
See this source for more.
Why must it be _exit() that is called from within the child and not exit()?
You risk flushing stdio buffers twice and remove temporary files. In additional destructors might be called incorrectly.

Exercise 1.2: Single program - multiple processes

Our program:

Output:



Explain what happens when a process is spawned via the exec() function familily:
What is passed to the "child" process and what is not?

exec() will replace the current process image with a completely new program. Essentially killing the old and creating a new but keeping the same PID. Open file descripters will still stay open


What should one be vary about when spawning processes in a security context (in relation
to the previous question)?
Files are kept open and are therefor exposed. What if we left the password file open?

Exercise 2: Shared memory

Questions to answer:
Describe the concept behind shared memory this includes which steps to go through and
what to remember from a purely functional point of view.
The reason to use shared memory is to allow for an abitrary amount of processes which have access to a certain section of memory, known as shared memory. From  the previous exercise we know each process has its own memory space but using shared memory we can easily and quickly communicate between processes.

You have to open the memory object and set its size, then you map that to the process' virtual memory. The functions are respectively shm_open(), ftruncate() and mmap().

When you have used the memory you must free it by using the above mentioned functions counterparts munmap(), close() and shm_unlink().

Under which circumstances would you consider shared memory a viable solution?
In highspees applications with multiple processes. If you only have one process this would be stupid.

Consider a scenario where two programs communicate via shared memory and program
B has taken a mutex that program A also waits for. In this unfortunate moment program
B crash whilst having acquired said mutex.
What is the problem?
The mutex will obvsiouly never be released and therefor the entire program will hault. Also known as Starvation.

How would you resolve it? (See pthread ROBUST - Google it)
Using pthread_mutex_robust you can tell the process which is waiting on the mutex that the process holding the mutex has crashed.  This makes the program able to continue but causes some problems descriped in the next question

But using said approach what does this mean for what I may do in the critical section
part, namely the part where I have acquired the mutex?
When a process crash while holding the mutex the mutex will become inconsistent. When a mutex is inconsistent is it not protected which means it can't be locked. The next process to acquire the mutex from the crashed process will have to call pthread_mutex_consisten().

Where is your code?
Unfortunately we couldn't get our code working but we try to prove we understand the theory by answering the questions anyway.


Thursday, December 6, 2012

MPS - Exercise 11 – Linux Device Model


Formål

Måden hvorpå vi hidtil har skrevet driver skalerer ikke godt til større systemer. Linux har en device model som på en ensartet måde repræsenterer selv sammensatte enheder ved: Bus, device og driver. Formålet med denne øvelse er at omskrive en GPIO device driver således at den lader sig registrere i SysFS som er en fil-system abstraktion på Linux' device model.


Øvelsen

a) Verificere at sysLed4 driveren virker

Den gamle driver for sysLed4 blev testet vha. insmod --> mknod /dev/led --> echo 1-0 > /dev/led.
Når der skrives 1 slukker LED'en og når der skrives 0 tænder LED'en. 
Terminal Output



b) Tilføj en sysfs klasse "ledKlasse"

Vores driver får sin egen klasse under /sys/class/.
Metoderne beskrevet i device.h(~/sources/linux-3.2.6/include/linux/device.h), anvendes i init/exit:

INIT
Nedenstående metoder tilføjes i init:

EXIT
Nedenstående metoder tilføjes i exit:
NB: Tilføjes lige efter printk

c) Kompiler og kopier modulet til target.

To ssh forbindelser laves til target(terminal1+terminal2). På den ene(terminal1) startes "udevadm monitor" og via den anden forbindelse(terminal2) indsættes modulet. 

Kommando på terminal1
Herunder er terminal output for den ene forbindelse, som skal vis de events der sker når man indsætter/fjerne drivermodulet igennem den anden terminal(terminal2).






Terminal output (gammel sysLed4)
Herunder er outputtet for den gamle sysLed4 driver:








Terminal output (sysLed4_devModel)
Herunder er outputtet for sysLed4_devModel driver:









d) Dynamisk allokering af major numre

Ændre linien med funktionskaldet fra register_chrdev_region() til alloc_chrdev_region():
For dynamisk allokering ændres definitioner for minor, ch derudover fjernes major:


I init tilføjes alloc_chrdev_region() og register_chrdev_region() slettes.

Terminal output Target
Programmet testes og vi aflæser følgende major og minor numre:





e) Opret en device_attribute struct

Show metoden implementeres. Den skal kun lave en printk("SHOW !!!"), den anden venter vi lidt med (dvs. at den implementeres tom). Herunder er kodeløsningen for show metoden:



f) Attribute output

Processen fra opgave c gentages













NB: Bemærk at der er kommet en folder med forskellige attributter, inklusiv den netop oprettede. 
Herunder laves der cat  på attributen ledAttrs:






Dernæst tjekke i dmesg om der bliver udskrevet "SHOW !!!". Herunder ses et vellykket terminal output fra Target:




g) Opret en global int gpio_sysled4_no = 164 i init

Et hvert device kan gemme private data i driveren. Til dette benyttes drvdata som er en void pointer i device_create() metoden. Show/store metoderne har hver især en device pointer, således at man ved med hvilket device de er kaldt. Vha device pointeren kan de private data udtrækkes vha dev_get_data()metoden.

i) Ændrer navn på gpio device’t

Evt. prøv at oprette en regel under /etc/udev/rules.d som giver gpio device't et andet navn.



FILERNE


På nedenstående link kan du se hele koden for alle programmer:


Monday, December 3, 2012

ISU - Exercise 9 - Resource Handling

Goals:

To understand the problems with memory leaks and how to prevent them, first by implementing it ourselfs and then by using smart pointer boost.

Exercise 1: Ensuring garbage collection on dynamically allocated std::string

Implement the following UML diagram:

Our code solution:


The output when using the test program provided in the exercise:


Questions to answer:
Why must the copy constructor and assignment operator be private with no implementa-
tion? and what is the consequence when these are private?

We make them private so it's impossible to create copies of the same object. If we allowed copies we would get multiple objects which points to the same stringPtr. When the destructor is called stringPtr is deleted and the program will crash because it no exists to the other objects.


What exactly does the operator->() do?
It fetches the object so you can write: *ss="Davs";

Exercise 2: The counted pointer

Extending the smartstring such the multiple parties can have a reference to it. We now implement the assignment and copy operator.

What happens in the destructor and how should it be implemented?
We check if count is zero. Only if count is zero will we delete that data.

New interface:










main.cpp:

smartstring.h:

Output:



Exercise 4: Discarding our solution in favor of boost::shared_ ptr<>

Instead of using our newly created solution and reinventing the wheel. We use boost::shared_ptr to give us the same functionality.

To use boost::shared_ptr we need to install a library:
sudo apt-get install libboost_dev

Exercise 4.1: Using boost::shared_ptr<>

Test program using boost::shared_ptr<> (forcing segmentation fault)
Output:





boost::shared_ptr<> works.We didn't simulate a cycle in this test but to prevent cycles we would use the weak ptr which doesn't add to the counter.

Exercise 5: Resource Handling

Perspective of this particular exercises:
What do you consider a resource?
CPU time
Memory
Files
Inputs and outputs

In which situations do you foresee challenges with resources and how could they be han-
dled?
In all non-trival C++ programs which requires resources in any way. When needing shared memory it is good to use these pratices because you allways know who is responsible of the resource

In particular regarding memory, when would you be able eliminate the need for allocations.
Or when is it a must that something is allocated(on heap)?
Embedded systems and systems with limited resources. It allows you to use the same memory several places.. Instead of copying data and do math on them you can point to them directly which reduces memory usage. 

Saturday, December 1, 2012

MPS - Exercise 10 - Userspace Driver


Formål

User Space drivers kan i nogle tilfælde være ganske nyttige. Kan arbejdet laves i User Space frem for Kernel Space, så bør det gøres der. User Space giver adgang til C++, Floating point, beskyttelse af hukommelse og meget mere. Tilgengæld er vi ikke garanteret nær den samme responstid som i kernen og vi kan heller ikke umiddelbart anvende interrupts. Til debugging af hardware kan det være nyttigt at skrive direkte fra user space til hardwaren og anvendes en fornuftig arkitektur, kan "mechanism" let flyttes til kernel space efterfølgende og "policy" beholdes i hardware.


Øvelsen

a) Userspace GPIO Driver på Target

mmap benyttes. For at anvende mmap på vores bootkey, skal størrelsen for en enkelt ”page” defineres. En page er 4k(4096UL).

For at tilgå GPIO, anvendes adresserne fundet vha. databladet spruf98c.pdf.
For at tilgå Bootkey og sysLed4, defineres en mask vha. bit/hex-konvertering, fx sættes BOOTKEY_OE bit 8 til 1 og resterende bits sættes til 0 og kenverteres til hex: 0b10000000 => 0x00000080


Userspace Driver kode


Programmeret kompileres:
arm-angstrom-linux-gnueabi-gcc -o user userspaceDriver.c

Dermed fås en executeable fil, user, som overføres til Target.
Executeable filen køreres på Target:
/.user

Terminal output på Target:








Dermed kan vi se at det lykkedes at mappe adresserne.

b) Test ELDD program på Kubuntu


Userprogrammet er hentet vha. checkout svn og kompileret til linux vha. gcc -o
Testapplikation:
gcc -o test user_space_rtc_driver_test.c
Der oprettes tre forskellige testprogrammer med tre forskellige ”scheduling policy”:
SCHED_OTHER, SCHED_ FIFO, SCHED_ RR







































Ved ovenstående scheduleringstest fås følgende resultater(testet 6 gange for hver type):