lunedì 13 dicembre 2010

A Case against the GO TO Statement.

by Edsger W.Dijkstra
Technological University
Eindhoven, The Netherlands

Since a number of years I am familiar with the observation that the quality of programmers is a decreasing function of the density of go to statements in the programs they produce. Later I discovered why the use of the go to statement has such disastrous effects and did I become convinced that the go to statement should be abolished from all "higher level" programming languages (i.e. everything except –perhaps- plain machine code). At that time I did not attach too much importance to this discovery; I now submit my considerations for publication because in very recent discussions in which the subject turned up, I have been urged to do so.

My first remark is that, although the programmer's activity ends when he has constructed a correct program, the process taking place under control of his program is the true subject matter of his activity, for it is this process that has to effectuate the desired effect, it is this process that in its dynamic behaviour has to satisfy the desired specifications. Yet, once the program has been made, the "making" of the corresponding process is delegated to the machine.

My second remark is that our intellectual powers are rather geared to master static relations and that our powers to visualize processes evolving in time are relatively poorly developed. For that reason we should do (as wise programmers aware of our limitations) our utmost best to shorten the conceptual gap between the static program and the dynamic process, to make the correspondence between the program (spread out in text space) and the process (spread out in time) as trivial as possible.

Let us now consider how we can characterize the progress of a process. (You may think about this question in a very concrete manner: suppose that a process, considered as a time succession of actions, is stopped after an arbitrary action, what data do we have to fix in order that we can redo the process until that very same point?) If the program text is a pure concatenation of, say, assignment statements (for the purpose of this discussion regarded

EWD215 - 1

as the descriptions of single actions) it is sufficient to point in the program text to a point between two successive action descriptions. (In the absence of go to statements I can permit myself the syntactic ambiguity in the last three words of the previous sentence: if we parse them as "successive (action descriptions)" we mean successive in text space, if we parse as "(successive action) descriptions" we mean successive in time.) Let us call such a pointer to a suitable place in the text a "textual index".

When we include conditional clauses ("if B then A"), alternative clauses ("if S then A1 else A2"), choice clauses as introduced by A.R.Hoare ("case[i] of(A1, A2,.....,An)") or conditional expressions as introduced by J.McCarthy ("B1 → E1, B2 → E2,....., Bn → En"), the fact remains that the progress of the process remains characterized by a single textual index.

As soon as we include in our language procedures we must admit that a single textual index is no longer sufficient: in the case that a textual index points to the interior of a procedure body the dynamic progress is only characterized when we also give to which call of the procedure we refer. With the inclusion of procedures we can characterize the progress of the process via a sequence of textual indices, the length of this sequence being equal to the dynamic depth of procedure calling.

Let us now consider repetition clauses (like "while B repeat A" or "repeat A until B"). Logically speaking, such clauses are now superfluous, because we can express repetition with the aid of recursive procedures. For reasons of realism I don't wish to exclude them: on the one hand repetition clauses can be implemented quite comfortable with present day finite equipment, on the other hand the reasoning pattern known as "induction" makes us well equipped to retain our intellectual grasp on the processes generated by repetition clauses. With the inclusion of the repetition clauses textual indices are no longer sufficient to describe the dynamic progress of the process. With each entry into a repetition clauses, however, we can associate a so-called "dynamic index", inexorably counting the ordinal number of the corresponding current repetition. As repetition clauses (just as procedure calls) may be applied nestedly, we find that now the progress of the process can always be uniquely characterized by a (mixed) sequence of textual and/or dynamic indices.

EWD215 - 2

The main point is that the values of these indices are outside programmer's control: they are generated (either by the write up of his program or by the dynamic evolution of the process) whether he wishes or not. They provide independent coordinates in which to describe the progress of the process.

Why do we need such independent coordinates? The reason is –and this seems to be inherent to sequential processes- that we can interpret the value of a variable only with respect to the progress of the process. If we wish to count the number, "n" say, of people in an initially empty room, we can achieve this by increasing "n" by 1 whenever we see someone entering the room; in the in-between moment that we have observed someone entering the room but have not yet performed the subsequent increase of "n", its value equals the number of people in the room minus one!

The unbridled use of the go to statement has as an immediate consequence that it becomes terribly hard to find a meaningful set of coordinates in which to describe the process progress. Usually, people take into account as well the values of some well chosen variables, but this is out of the question because it is relative to the progress that the meaning of these values is to be understood! With the go to statement one can, of course, still describe the progress uniquely by a counter counting the number of actions performed since program start (viz. a kind of normalized clock). The difficulty is that such a coordinate, although unique, is utterly unhelpful: in such a coordinate system it becomes an extremely complicated affair to define all those points of progress where, say, "n" equals the number of persons in the room minus one!

The go to statement as it stands is just too primitive, it is too much an invitation to make a mess of one's program. One can regard and appreciate the clauses considered as bridling its use. I do not claim that the clauses mentioned are exhaustive in the sense that they will satisfy all needs; but whatever clauses are suggested (e.g. abortion clauses) they should satisfy the requirement that a programmer independent coordinate system can be maintained to describe the process in a helpful and manageable way.

EWD215 - 3

It is hard to end this article with a fair acknowledgement: am I to judge by whom my thinking has been influenced? It is fairly obvious that I am not uninfluenced by Peter Landin and Christopher Strachey, and that I do not regret their influence upon me. Finally I should like to record (as I remember it quite distinctly) how Heinz Zemanek at the pre-ALGOL meeting in early 1959 in Copenhagen quite explicitly expressed his doubts whether the go to statement should be treated on equal syntactic footing with the assignment statement. To a modest extent I blame myself for not having then drawn the consequences of his remark.

lunedì 22 novembre 2010

Debian installazione di phpmyadmin

Come non puo' funzionare phpmyadmin se l'installazione e cosi' diretta? il nostro sistema operativo unix-like ha il vantaggio della filosofia "everything is a file" ... e le installazioni funzionano se si fanno manualmente..
phpmyadmin e' un gestore di database, o meglio e' un software scritto in php che gestisce MySql. per installarlo abbiamo bisogno dei pacchetti seguenti:
php5, mysql-server, mysql-client, apache2.
Scarichiamo una versione di phpmyadmin da qui e posizioniamo il file nel localhost (/var/www) .
Ssspakkettiamolo e rinominiamolo in "phpmyadmin".
Ora abbiamo la directory con il software dentro. Se abbiamo fatto tutto cio' con i privilegi di root e' ok, altrimenti dobbiamo assegnare i permessi adeguati per non essere scoperti.
A proposito di permessi andiamo a configurare il programma entrando nella directory /var/www/phpmyadmin e creiamo il file di configurazione "config.inc.php" con qualsiasi editor e spariamoci lo scriptino di accesso:
$cfg['blowfish_secret'] = 'la_vostra_fottuta_password';
$i=0;
$i++;
$cfg['Servers'][$i]['auth_type'] = 'cookie';
?>
..aprite il browser per accede a phpmyadmin. Inserite l'url http://localhost/phpmyadmin connettetevi con root e password e dovreste esserci.
Se qualcosa non funge bisogna controllare l'installazione di apache2 o mysql, si puo' fare tramite
/etc/init.d/mysql status
/etc/init.d/apache2 status
e se sono fermi
/etc/init.d/mysql start
/etc/init.d/apache2 start.
Se ancora non funge si crea lo scriptino di prova in /var/www "info.php"
phpinfo();
?>
per controllare l'installazione di php5...

mercoledì 3 novembre 2010

Program Development Terminology

1. A NUMBER OF DIFFERENT APPROACHES ARE BEING TRIED - We are still pissing in the wind.

2. EXTENSIVE REPORT IS BEING PREPARED ON A FRESH APPROACH TO THE PROBLEM - We just hired three kids fresh out of college.

3. CLOSE PROJECT COORDINATION - We know who to blame.

4. MAJOR TECHNOLOGICAL BREAKTHROUGH - It works OK, but looks very hi-tech.

5. CUSTOMER SATISFACTION IS DELIVERED ASSURED - We are so far behind schedule the customer is happy to get it delivered.

6. PRELIMINARY OPERATIONAL TESTS WERE INCONCLUSIVE - The darn thing blew up when we threw the switch.

7. TEST RESULTS WERE EXTREMELY GRATIFYING - We are so surprised that the stupid thing works.

8. THE ENTIRE CONCEPT WILL HAVE TO BE ABANDONED - The only person who understood the thing quit.

9. IT IS IN THE PROCESS - It is so wrapped up in red tape that the situation is about hopeless.

10. WE WILL LOOK INTO IT - Forget it! We have enough problems for now.

11. PLEASE NOTE AND INITIAL - Let`s spread the responsibility for the screw up.

12. GIVE US THE BENEFIT OF YOUR THINKING - We`ll listen to what you have to say as long as it doesn`t interfere with what we`ve already done.

13. GIVE US YOUR INTERPRETATION - I can`t wait to hear this bull!

14. SEE ME or LET`S DISCUSS - Come into my office, I`m lonely.

15. ALL NEW - Code not interchangeable with the previous design.

16. YEARS OF DEVELOPMENT - It finally worked!

17. LOW MAINTENANCE - Impossible to fix if broken.

venerdì 29 ottobre 2010

Cocaine

Un "viaggio" da cocaina e' il risultato di un'eccessiva stimolazione del centro di piacere del cervello da parte di un neurotrasmettitore, la dopamina.
Un neurotrasmettitore e' una sostanza che VEICOLA (veicola cazzo ! ) le informazioni tra cellule del sistema nervoso, ossia i neuroni, attraverso la trasmissione sinaptica.
Quando la cocaina raggiunge il cervello, la dopamina rilasciata viene totalmente bruciata. (WTF!)
La cocaina innalza i livelli di: adrenalina (aumento della pressione sanguigna e del battito cardiaco) acetilcolina (tremori muscolari) serotonina (sensazione di piacere e serenita').
Assunta con l'alcol produce un prodotto: il cocaetilene, che da dipendenza ed e' molto piu' pericoloso per il cervello. La dipendenza prolungata da cocaina ha gravissimi effetti collaterali, che sono perdere la ragione, avere manie e idee fisse che portano a vivere una dimensione irreale, con sintomi paranoici.
Alla fine il cervello termina tutta la sua limitata scorta di dopamina e i cocainomani possono soffrire di: depressione, cambi d'umore e morbo di Parkinson, ma anche: schizofrenia psicosi reattiva disordine da illusione disturbo bipolare depressione psicotica disordine schizoaffettivo psicosi paranoide iperattivita' convulsioni allucinazioni problemi cardiaci aggressivita'.
Con l'abbassarsi del livello di cocaina nell'organismo, i dipendenti possono provare ansia, apatia, insonnia e un forte aumento dell'aggressivita'.
Molti di questi sono sintomi da depressione clinica.

Una volta ho sentito una giustificazione del genere: "bisogna provare tutto", io infatti faccio skate sempre in posti diversi, e se voglio stripparmi in modo mezzo malsano mi faccio un bicchiere (o anche 10) con gli amici a cena davanti ad una superbistecca. Ma quando si e' curiosi basta cercare la verita' anche sul web... e rendersi conto che non e' poi cosi' fregno fare le pecore.
(bella)
~

martedì 26 ottobre 2010

compilers definizione delle fasi

Visto come box unico un compilatore traduce il programma sorgente in programma target, ma al suo interno si possono distinguere due famiglie di passaggi diversi: analisi e sintesi.
L'analisi spezza il programma sorgente (sequenza finita di caratteri) in sottosequenze, o stringhe, e costruisce una grammatica adeguata. Questa struttura e' la rappresentazione che passa alla parte di sintesi insieme alle informazioni sui token che memorizza nella struttura dati symbol table.
Se il programma sorgente non e' sintatticamente corretto la parte di analisi informa l'utente.
La sintesi costruisce il programma target dalla rappresentazione intermedia e dalla symbol table.
La parte di analisi viene spesso chiamata "front end" del compilatore, la parte di sintesi "back end".
A differenza dei compilatori gli interpreti non producono rappresentazioni intermedie, ma eseguono direttamente le istruzioni del programma sorgente, quindi eseguendo statement per statement tutto il codice sorgente sono piu' scrupolosi nella gestione degli errori, ma il codice eseguibile, o programma target, che produce un compilatore e' piu' veloce.

giovedì 7 ottobre 2010

Relazione di ricorrenza, definizione

La misurazione del tempo (complessita' di un algoritmo) avviene tramite il conteggio delle istruzioni macchina eseguite, nelle funzioni ricorsive si contano anche le linee di codice (istruzioni) mandate in esecuzione dalle chiamate ricorsive della stessa funzione.
La relazione di ricorrenza esprime questo calcolo in formula.

Es, la relazione di ricorrenza di Fibonacci: T(n) = 2 + T(n-1) + T(n-2)

E' possibile risolvere le relazioni di ricorrenza attraverso 3 metodi: Il metodo iterativo, della sostituzione, e tramite il teorema fondamentale delle ricorrenze.
Il metodo iterativo consite nello srotolare la relazione di ricorrenza considerando la variabile c menzionata nelle definizioni delle limitazioni superiori e inferiori (O grande e Omega grande) in modo tale da contare quante volte si svolge il procedimento, quindi nel caso della relazione di ricorrenza della ricerca binaria, che e' T(n)=c+T(n/2) per n>1 e T(n)=1 per n=1 si considera c multiplo di due e si srotola la ricorsione cosi':

T(n)=c+T(n/2)=2c+T(n/4)=...=ic+T(n/2^i)

per essere n/2^i bisogna svolgere il procedimento i=logn volte, quindi T(n)=O(logn)


Il metodo della sostituzione tratta di indovinare la soluzione e dimostrarla tramite induzione, quindi dopo aver determinato i caso base bisogna applicare il passo induttivo per calcolare i valori della variabile c per i quali e' valida la ricorrenza, per determinare le limitazioni inferiori o superiori.

Il teorema fondamentale delle ricorrenze si applica agli algoritmi che seguono la tecnica "divide et impera", con relazioni di ricorrenza del tipo T(n)=aT(n/b) + f(n), a seconda della forma di f(n) presenta tre soluzioni diverse. (vedi definizione teorema master).

domenica 3 ottobre 2010

svoltastampa-cups

Cups: Debian printing system

solo con cups cups-client controllandolo da /etc/init.d
/etc/init.d/cups start
/etc/init.d/cups status


-->ora dal browser controlla stampanti e lavori
http://localhost:631 username e pwd utente o root

mercoledì 9 giugno 2010

Quanto moto ??

...nell'analizzare degli eventi fisici particolari, si fa riferimento alla quantita' di moto.
E' una grandezza che mette in relazione velocita' e massa di un oggetto in moviemento.
"Aspettando con una mazza da baseball una palla che viaggia a 120 Km/h
e' ben diverso che aspettare un camion che viaggia alla stessa velocita'".

Una certa percezione intuitiva mi dice che preferirei colpire la palla anziche' il tir. E questo perche' una grandezza detta quantita' di moto definisce la differenza tra i due oggetti.
p=mv

mercoledì 19 maggio 2010

smoklebubble

void swap(int *x, int *y){
int aus=*x;
*x=*y;
*y=aus;
}

void bubbleSort(int a[], int size){
int i,j;
for(i=size-1;i>=0;i--){
for(j=1;j<=i;j++)
if(a[j-1] > a[j])
swap(&a[j],&a[j-1]);
}
}

void stampa_Arr(int a[], int size){
int i;
for(i=0;i printf("%d ", a[i]);
}
printf("\n");
}

main(){
int a[DIM];
int i;
srand(time(NULL));
for(i=0;i a[i]=rand()%100;
}
stampa_Arr(a,DIM);
bubbleSort(a,DIM);
stampa_Arr(a,DIM);
}
There was a plan heald high up for the young ones
It says, we alone must bring the fruit out of the garden
For this is not just a sign this is our holy water
Well now wa da da da
In a vision of fire, I'll fight til the end

So you think you are the only one, well well well well
who gave my Father the strength to cross the ocean
Lord Mother come carry your flock in for the day
Rally round, gather round, oh people in some way

Each one shall teach one yes
well until we reach Jah heights, oh children bless
Each one shall teach one yes
Until we reach Jah heights inna future
Each one shall teach one yes
Yes until we reach Jah heights oh children bless
Each one shall teach one yes
Lord, until we reach Jah heights inna future

In this plan is the knowledge
Of what dwelled before man
So know your history or you will become it
Dear Mother come save your pickney
From the Philstine, marching in this time
Oh Father, guide them from the Babylonians

Well I man go, down by the river
Yes and I man see, our children deliver me
Well I man go, down by hte river
Yes and I man see, our children deliver me

Some may say "oh why am I hear today?"
Well if you do not know today, you will know tomorrow
Finding a river flowing deep, deep from from within
Rally round, gather round, everyone run come pass it on!!!

Each one shall teach one yes
well until we reach Jah heights, oh children bless
Each one shall teach one yes
Until we reach Jah heights inna future
Each one shall teach one yes
Yes until we reach Jah heights oh children bless
Each one shall teach one yes
Lord, until we reach Jah heights inna future

martedì 27 aprile 2010

Configurare Alpine con Gmail

1. (S)etup -> Collection(L)ist -> Add
...ed riempire i campi:
NickName:Gmail
Server :imap.gmail.com:993/ssl/novalidate-cert/user=username@gmail.com
(sostituire "username" con il nome utente)

2. (S)etup -> (C)onfig
...ed inserire in SMTP:smtp.gmail.com/tls/user=username@gmail.com

venerdì 12 marzo 2010

LAMP install

...Un piccolo script per l'installazione di LAMP, LINUX APACHE MYSQL PHP, la piattaforma di sviluppo di applicazioni web.

il codice e' questo ma si puo' scaricare da
http://hotfile.com/dl/34333712/39edf98/lampinstall.bash.html


#~/bin/bash


salute() {
echo
echo " hi , wellcome to the Lamp installation Script " ;
echo
}

controlling_root() {
echo ...
if [ $UID == 0 ]
then
echo "ok" ;
else
echo "...NOP ! Bye, see ya when the root user comes back" ;
echo "\(you have to be root\)";
exit;
fi
}


sleep 1
clear
salute #function
sleep 1
echo "first thing...updating" ;
echo " wait wait...are you root? ( controlling )" ;
controlling_root #function

apt-get update && upgrade
apt-get install mysql-server mysql-client

echo "mysql installed, now, we (me and you) provide to install apache2" ;
sleep 2
apt-get install apache2 apache2-doc
sleep 2
echo "apache installed, now php stuff must be installed: ";
#or apt-get install php5 php5-mysql libapache2-mod-php5
# or apt-get install perl libapache2-mod-perl2
apt-get install python libapache2-mod-python



##### ok, 2nd step, configuring apache

echo
echo
echo "ok, now apache2 must be configured," ;
sleep 1
echo "the configuration file is: /etc/apache2/apache2.conf" ;
sleep 1
echo " now I open the file, and I will add a line: " ;
echo "file: /var/www/apache2-default/test.php" ;
echo "line: " ;
sleep 1
echo "" > /var/www/test.php ;

echo "ok...done!" ;
sleep 3
echo "now for easy configuration, phpmyadmin must be installed" ;
sleep 3
apt-get install phpmyadmin
echo "done!" ;

sleep 2
echo " now adding the line"
echo " Include /etc/phpmyadmin/apache.conf"
echo "in /etc/apache2/apache2.conf";
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2.apache2.conf
sleep4
echo "..and restarting apache "
sleep 1
/etc/init.d/apache2 restart


sleep 2; clear ;

sleep 3
clear

sleep1
echo "now..apache2 configuration , libraries and restarting"
sleep 1
clear
echo "installing libapache2-mod-php5 php5-cli php5-common php5-cgi"
apt-get install libapache2-mod-php5 php5-cli php5-common php5-cgi
sleep 1
clear
echo "...and restarting apache2"
/etc/init.d/apache2 restart

venerdì 5 marzo 2010

Memoria Virtuale

Memoria Virtuale.
Le tecniche di gestione della memoria prevedono la suddivisione degli spazi fisici e logici dei processi per conservarli in memoria centrale in modo da migliorare efficientemente la multiprogrammazione lavorando pero' sugli spazi logici, e' possibile evitare di dover tenere un processo completamente in memoria e trarne diversi vantaggi.
Infatti e' possibile eseguire un processo che non e' caricato completamente poiche' il codice potrebbe contenere riferimenti a routines di gestione di errori che verrebbero richiamate di rado, oppure verrebbero utilizzate variabili che occupano spazi inutilizzati, come array di dimensione esagerate rispetto all'utilizzo necessario.
I vantaggi che riguardano un caricamento parziale di un processo sono stimabili in termini di spazio, poiche' meno frame fisici sono utilizzati, quindi occupati. Un secondo vantaggio e' il grado di multiprogrammazione, possono essere tenuti piu' programmi in memoria visto che occuerebbero meno, ed infine il sistema sarebbe piu' veloce, poiche' ci sarebbero meno operazioni di i/o per caricare un programma utente (meno pagine logiche!).
Nella tecnica di memoria virtuale lo swapping, la tecnica che prevede di caricare processi in memoria centrale dalla memoria secondaria e viceversa, viene sostituito con il lazy swapping, che carica solo alcune pagine logiche del processo.
Il pager e' il modulo che affronta questo tipo di lavoro.
Un processo, per come e' strutturato, puo' infatti sugerire al pager quali pagine caricare e di quali routine, librerie e funzioni ha bisogno per essere eseguito.
Questo puo' essere ben compreso attraverso lo spazio degli indirizzi, un'espressione che fa riferimento al modo di memorizzazione logica, quindi apparentemente contigua, di un processo.
Parte da un determinato indirizzo, e presenta un segmento dedicato al codice, uno dedicato ai dati, poi heap e stack, ma tra questi ultimi c'e' uno spazio che permette all'heap e allo stack di crescere.
Questo spazio libero necessita di pagine fisiche, quindi frames, solo se l'heap o lo stack crescono.
La funzione del buco e' sia di lasciare spazio ai segmenti adiacenti (come gia' detto heap e stack) ma anche di permettere collegamenti dinamici a librerie che il processo potrebbe richiedere all'istante.
Quindi e' un punto di forza per la condivisione della memoria, sia per le librerie che per l'ipc.

Il pager carica solo le pagine necessarie.
Per identificarle, nella page table di ogni processo queste sono segnate come "valide", ossia che appartengono allo spazio di indirizzi logici e sono presenti in memoria.
Un processo nell'esecuzione richiede accesso alle pagine, se il riferimento in memoria non e' valido il processo termina, altrimenti la pagina deve essere caricata.
Un accesso a pagina mancante si chiama PAGE FAULT.
Quindi si individua un frame libero, si aggiornano le tabelle e continua l'esecuzione.
Cosa accade se non c'e' un frame libero? In questo caso si parla di sostituzione, ossia si scegli un frame vittima, si scrive la pagina richiesta nel frame, si modificano le tabelle delle pagine e si prosegue con l'esecuzione.
Quindi si hanno due cambiamenti di pagine, nel frame e nella memoria.
Si puo' evitare associando un bit (dirty bit) ad un apagina, che segnala che quella pagina e' stata modificata, quindi deve essere scritta sul disco.
Gli algoritmi di sostituzione delle pagine si basano sulla frequenza di page fault. Si studiano in base a successioni di riferimenti che si ottengono attraverso successioni di numeri casuali.
Un primo algoritmo e' affrontare la successione calcolando il numero di page fault tramite la sostituzione di pagine in modo FIFO, un secondo algoritmo e' la sostituzione ottimale, per il quale si sostituisce la pagina mancante con quella che non si iusera' per il periodo piu' lungo.
Ma non e' realizzabile, poiche' dovrebbe essere noto l'utilizzo futuro delle pagine.
L'LRU invece, usa sostituire la pagina con quella che non e' stata usata per il tempo piu' lungo.

Sono poche le architetture che sfruttano un algoritmo di sostituzione LRU, ma puo' essere approssimato, ad esempio un algoritmo FIFO puo' essere aiutato da un bit di riferimento nel seguente modo:
inizialmente tutte le pagine hanno un bit impostato a zero, quando il sistema fa riferimenteo ad una pagina imposta il bit a 1, in modo tale che in ogni istante si conoscono le pagine utilizzate. Tuttavia non si puo' conoscere l'ordine in cui sono state utilizzate.

Gestione della memoria


 Memoria Centrale.
Visto che l'obiettivo di avere un sistema efficiente ha portato alla multiprogrammazione, ossia l'alternarsi di piu' processi in cpu, la memoria centrale dovra' ospitare diversi processi, e siccome non e' grande abbastanza da contenerli tutti, dovra' essere gestita dal sistema operativo nel modo piu' efficiente possibile.

Il ciclo di cpu prevede 3 istruzioni principali: fetch decode execute, prevede la lettura e scrittura oltre all'esecuzione vera e propria, da e su dispositivi di memorizzazione.
Questi possono essere accessibili direttamente dal processore.
Alla memoria centrale si accede tramite bus.
La questione di velocita' d'accesso e' coperta dalla memoria cache, un dispositivo di memorizzazione che sfrutta principi di localita' e temportali per cui si controlla se un'istruzione e' presente in cache o bisogna andare a prelevarla in memoria, ma un fattore altrettanto importante oltre alla cache e' la velocita' di protezione.
La memoria e' protetta grazie al meccanismo di protezione hardware offerto da due registri base e limite.
Quando un processo richiede accesso ad un'area di memoria si controllano gli indirizzi attraverso questi due registri: il registro base contiene il piu' piccolo indirizzo a cui puo' accerdere, il registro limite contiene l'inervallo di indirizzi a cui il processo puo' accedere.
Un tentativo di accesso a intervalli di memoria sbagliata comporta una trap.
Quando un programma utente viene scelto per l'esecuzione puo' venire caricato in memoria passando per vari stadi in cui gli indirizzi sono rappresentati in modo diverso.
Infatti gli indirizzi del codice sorgente sono simbolici, un compilatore li rende rilocabili ed un loader li fa corrispondere ad indirizzi assoluti.
I metodi di associazione degli indirizzi nella fasi di compilazione e caricamento producono indirizzi logici e fisici identici, mentre nella fase d'esecuzione l'associazione degli indirizzi e' compito dell'MMU.

L'MMU e' un dispositivo che contiene un registro di rilocazione che ha un valore a cui deve essere sommato l'indirizzo logico per ottenere l'indirizzo fisico.
La separazioned degi indirizzi logici e fisici e' un primo passo verso tecniche di memorizzazione molto efficienti.
In primo luogo e' possibile avere un caricamento dinamico di procedure, che occupano la memoria solo quando vengono chiamate, o di librerie, che ancor meglio vengono linkate, in modo che durante l'esecuzione di un programma il riferimento fa si che venga ricercata la libreria linkata e se non e' presente viene caricata in memoria. Questo meccanismo e' molto utile per l'aggiornamento delle librerie.

Il caricamento in memoria delle immagini dei processi e' detto swapping, o avvicendamento, e' l'atto di caricare dalla memoria ausiliaria in memoria centrale i processi che richiede la cpu.
La coda dei processi pronti conserva puntatori alle immagini dei processi (in memoria secondaria).

La gestione della memoria segue un percorso siffatto: inizialmente la cosa piu' importante e' la rilocazione, ossia voler caricare processi in memoria, e scaricarli, ma dividendo lo spazio degli indirizzi logici da quello degli indirizzi fisici, in modo tale che siamo capaci uno, di swappare i processi per rendere efficiente l'utilizzo del processore, e due di rilocare i processi caricati di nuovo in memoria in altre porzioni.
Dopo il primo aspetto della rilocazione vi e' quello della protezione, quindi la stessa separazione degli indirizzi pone dei limiti di permessi che i processi sono costretti a seguire attraverso registri di rilocazione.
Si parla di associazione dinamica degli indirizzi in runtime (MMU).

Ma la principale funzione della gestione della memoria e' quella di organizzarla per accogliere piu' processi.
Un primo approccio e' quello di suddividere la memoria ( spazio contiguo di indirizzi) in partizioni di dimensione fissa.

Il partizionamento fisso e' una tecnica per la quale vengono scelti i processi da una coda d'ingresso per essere inseriti in memoria.
Sono 3 le strategie di posizionamento : best fit, il processo viene messo nel buco di memoria piu' adatto, first fit, il processo occupera' la posizione di memoria che lo contiene che incontra per prima, worst fit: il processo sara' accolto dalla partizione piu' comoda.
Vi e' uno spreco enorme di memoria, che genera due problematiche gravi: la frammentazione interna si ha all'interno della partizione fissa che accogli un processo quindi l'algoritmo di partizionamento worst fit e' quello che causa maggior danno in termini di framentazinoe interna.
La frammentazione esterna e' data dal fatto che non tutte le partizioni vengono occupate.
La soluzione e' in primo luogo il partizionamento dinamico, in cui le partizioni occupate possono essere in un certo modo accorpate per cui creano uno spazio partizionabile ricorsivamente.
Comunque non risolverebbe la frammentazione esterna.
Per evitare questi due problemi bisogna permettere che lo spazio di memoria non sia contiguo.
Questo vuol dire allocare un processo in segmenti di memoria sparsi, non adiacenti.
Per farlo oltre a dividere la memoria si dovra' dividere lo spazio logico, per poi avere dei riferimenti.
La memoria centrale si divide in frames, il processo, o meglio la memoria logica che lo rappresenta, in pagine.
Le pagine e i frame hanno uguale dimensione, che e' data dall'architettura della macchina, ed e' compresa tra 512 byte e 16 Mb. Ed e' una potenza di 2, perche' se lo spazio di indirizzi logici e' grande 2 alla m e una pagina e' 2 alla n, m-n sono il numero delle pagine ed n e' l'offset.
L'architettura di paginazione funziona cosi:
la cpu genera un indirizzo logico, che e' diviso in due, un numero di pagina, rappresentato da m-n bit, il numero di pagina punta alla page table, un riferimento ai frame corrispondenti, presente in ogni processo, o meglio ogni pcb ha un puntatore ad una struttura dati che rappresenta la tabella delle pagine.
Una volta individuato il numero di frame si somma l'offset per ottere l'indirizzo del frame fisico in memoria centrale.

Ma com'e' realizzata una page table?
Si puo' implementare attraverso una serie di registri che la cpu carica ogni volta dopo che il pcb espone il puntatore che indica i valori che deve avere, ma la tabella delle pagine e' molto grande, quindi non sarebbe contenuta in registri. Un metodo alternativo e' utilizzare un solo registro, in cui viene caricata la tabella delle pagine del processo in esecuzione, Page Table Base Register, quindi occorre accedere al PTBR, e poi al frame per ottenere un numero di frame...e due accessi alla memoria non rendono la gestione molto efficiente.
Quindi si utilizza il TLB: Translation Look Aside Buffer, che funziona come una cache, ossia mantiene alcuni numeri di frame per cui la parte dell'indirizzo logico relativa al numero di pagina indica un campo del TLB, e se vi e' presente il numero di pagina si evita l'accesso in memoria, altrimenti si accede alla page table.

Logicamente ci vuole una protezione interna alla paginazione, ma e' facile aggiungere nella struttura dati della page table un campo che indica se il riferimento e' valido o meno, ossia se il bit di una pagina e' impostato a valido vuol dire che quella pagina risiede nello spazio logico del processo.

La paginazione consente di condividere spazi di memoria: se un codice e' rientrante o puro, questo non viene modificato durante l'esecuzione, quindi puo' risiedere in memoria senza copie ed essere utilizzato da piu' preocessi.

sabato 27 febbraio 2010

fedora 12 compiz conf

...qualcosa non va con l'impatto...effetti desktop, ho trovato i driver della mia scheda video, ho aggiunto i repository con:

rpm -Uvh http://download1.rpmfusion.org/free/fedora/rpmfusion-free-release-stable.noarch.rpm http://download1.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-stable.noarch.rpm

e ho installato i driver:

yum install kmod-nvidia xorg-x11-drv-nvidia

Poi ho installato tutti i package che mi servono:

emerald-themes
compiz-fusion-extras
emerald
compiz-fusion
compiz-manager
compiz-fusion-extras-gnome
gnome-compiz-manager
libcompizconfig
compiz-fusion-gnome
ccsm


...done XD !

mercoledì 17 febbraio 2010

Deadlock (relazione)

Un deadlock e' causato da un insieme di processi in blocco permanente che competono per le risorse del sistema.
Ogni processo e' bloccato in attesa che un altro processo rilasci una risorsa, ma questo non avviene perche' anch'esso e' fermo nell'attesa dello stesso evento.
Il blocco e' permanente poiche' il rilascio da parte di un processo di una risorsa non avviene, visto che aspetta altre risorse per concludere il lavoro.
Esempi nella vita comune sono gli incroci, in cui se arrivano 4 macchine e si fermano in attesa che passi prima la vettura alla loro destra, non procedono, e se non rispettano la regola e avanzano insieme all'istante si bloccano contemporaneamente allo stesso modo.
Un altro esempio e' la legge del Kansas del XX secolo: "Quando due treni convergono ad un incrocio, entrambi devono arrestarsi, e non possono procedere fin quando uno dei due non si allontana."
Cosa succede nel sistema?
La vita di un processo prevede l'utilizzo di diverse risorse, ed il metodo per sfruttarle richiede che sia rispettata la seguente sequenza: richiesta, uso, rilascio.
Le situazioni di stallo sono caratterizzate da 4 condizioni che avvengono contemporaneamente:
1. Mutua esclusione,
2. Possesso e attesa,
3. Impossibilita' di prelazione
4. Attesa circolare.
Mentre un metodo di visualizzazione dello stato del sistema e' il grafo di assegnamento risorse, che contiene due tipi di nodi, rappresentati da un processo o da una risorsa, e due tipi di archi, quello che va dalla risorsa al processo (arco di assegnazione) e quello che va dal processo alla risorsa (arco di richiesta).
Se il grafo contiene cicli allora il sistema e' in deadlock.
...Comunque come gestire il problema del deadlock?
Ci sono tre possibilita', anche se non sono tutte implementabili.
E' possibile evitarlo, risolverlo, o ignorarlo.
Prevenire il deadlock:
Se non avviene una delle 4 condizioni il sistema non entra in stallo. Un sistema che possiede risorse condivisibili non ha bisogno di mutua esclusione (es: file aperti), per quanto riguarda il possessso e attesa vi sono diversi algoritmi, in pratica un processo che richiede non deve possedere risorse, quindi o puo' richiederle solo se non ha risorse, o deve rilasciarle tutte prima di effettuare richieste.Oppure deve richiedere tutte le risorse prima dell'esecuzione e gli devono essere assegnate.
Questo non solo porta ad un utilizzo poco efficiente delle risorse, ma porta al verificarsi del problema dell'attesa indefinita.
Per quanto riguarda l'impossibilita' di prelazione, e' possibile che non accada in diverse maniere, ad esempio si puo' far si' che un processo rilasci tutte le risorse se una non gli puo' essere assegnata.E quindi essere sottratto dall'utilizzo in cpu.
Attesa circolare: per non permettere il verificarsi di attesa circolare, c'e' bisogno di un algoritmo che assegni risorse in modo tale che le richieste siano ordinate rispetto alle risorse, quindi da evitare che un processo richiede risorse in possesso da una altro processo in attesa.E possibile ad esempio richiedendo risorse in sequenza crescente in numeri di istanza.
Evitare il deadlock:
Evitare il deadlock e' sicuramente piu' probabile anche se meno semplice, poiche' prevenire il deadlock vuol dire privare il sistema di funzioni necessarie per il corretto funzionamento. Come ad esempio la mutua esclusione: non si puo' lasciare in vita un sistema senza mutua esclusione, si annienterebbe il concetto di multiprogrammazione che e' alla base dell'efficienza di un sistema operativo.
Evitare vuol dire prevedere, ed in tal caso simulare l'assegnamento. Per far cio' bisogna definire uno stato in cui il sistema puo' assegnare risorse a ciascun processo.
Lo stato sicuro e' la condizione in cui il sistema operativo assegna le risorse in un certo ordine e impedisce una situazione di stallo. Questo avviene se c'e' una sequenza sicura.
Una sequenza si dice sicura se per ogni Pi si puo' assegnare il numero di risorse che richiede impiegando le risorse disponibili piu' quelle possedute da tutti i Pj con j
R(Pi) = Disponibili+Allocate(Pj)

Algoritmo del banchiere: viene utilizzato per prevedere l'assegnamento e verificare se e' possibile dimostrando che la sequenza delle richieste lascia il sistema in uno stato sicuro. Questo e' possibile attraverso due algoritmi: di verifica della sicurezza e di richiesta.
L'algoritmo del banchiere si avvale di 4 vettori: Disponibili, Massimo, Allocated, Need.
Si applica prima l'algoritmo della verifica di sicurezza, per verificare appunto se il sistema e' in uno stato sicuro.

if(Need <= Disponibili)
Disponibili += Allocate

Ora che e' verificato che il sistema vive in uno stato sicuro, e' possibile applicare l'algoritmo di richiesta delle risorse. Quest'ultimo necessita di una variabile in piu' che e' il vettore Richieste.

if(Richieste <= Need)
if(Richieste <= Disponibili)
Disponibili -= Richieste
Allocate += Richieste
Need -= Richieste


Se non c'e' modo di prevenire o evitare lo stallo c'e' bisogno di un metodo per verificare, o meglio rilevare le situazioni di stallo, ed in tal caso ripristinare.
Vuol dire permettere he un sistema entri in stallo per poi risolvere la situazione.
Per questa necessita' e' possibile modificare il grafo di assegnamento risorse che prevede l'utilizzo di due archi, di richiesta e di assegnamento, e due tipologie di vertici: risorsa (con il numero di istanze disponibili) e processo; trasformandolo in un grafo di attesa, introducendo un nuovo tipo di arco che va da processo a processo, eliminando il vertice risorsa, in modo tale che l'arco appena introdotto indichi che un processo "e' in attesa di una risorsa posseduta da".
Anche in questo caso i cicli indicano l'avvenimento del deadlock, un algoritmo che individua un ciclo e' capace di verificare una situazione di deadlock, quindi pericolosa per il sistema.

..tubi..

//unnamed pipe

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

char *s="I am a message";
main(){
int fd[2];
int bytesread;
char buf[100];
pipe(fd);
if(fork()==0){
close(fd[0]);
write(fd[1],s,strlen(s));
close(fd[1]);
}
else{
close(fd[1]);
bytesread=read(fd[0],buf,100);
printf("%s,%d \n",buf,bytesread);
close(fd[0]);
}
}



//named pipe , writer program

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>

char *s="I am a message XD !";

int main(int argc,char *argv[]){
int r,w;
if(argc!=2){printf("errore: inserire il nome della pipe\n");exit(1);}
if((mknod(argv[1],S_IFIFO|0666,0)==-1)&&(errno != EEXIST)){
perror("errore mknod");exit(1);
}
if((w=open(argv[1],O_WRONLY)==-1)){perror("errore open");exit(-1);}
if((write(w,s,strlen(s)+1))==-1){perror("errore write");exit(-1);}
close(w);
}


//unnamed pipe, reader program

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<errno.h>

char *s="I am a message XD !!";

int main(int argc, char *argv[]){
char buf[100];
int bytesread;
int r,w;
if(argc!=2){printf("manca l'argomento\n");exit(1);}

if(mknod(argv[1],S_IFIFO|0666,0)==-1){perror("errore nella creazione");exit(1);}
if(r=open(argv[1],O_RDONLY)==-1){perror("errore nell'apertura");exit(1);}
if((bytesread=read(r,buf,100))==-1){perror("errore nella lettura");exit(1);}
printf("%s,%d\n",buf,bytesread);
close(r);
}

venerdì 29 gennaio 2010

i capofamiglia exec

#include<stdio.h>
#include<stdio.h>
#include<sys/signal.h>
#include<unistd.h>


main()
{
int i, status, pid;

pid=fork();
if(pid==0){
printf("child\n");
execl("/bin/ls","ls",".", "-l", 0);

}
else{
printf("parent\n");
wait(&status);
}
}


/*______________________________________________________________________________*/


#include<stdio.h>
#include<stdio.h>
#include<sys/signal.h>
#include<unistd.h>

main()
{
int i, status, pid;
char *myargs[]={"ls","-l","/",NULL};
pid=fork();
if(pid==0){
printf("child\n");
execv("/bin/ls",myargs);

}
else
printf("parent\n");
wait(&status);
}

domenica 24 gennaio 2010

Configurazione Alpine

S
C
nickname:
smtp: smtp.gmail.com:587/tls
Inbox: imap.gmail.com/ssl/user=user@gmail.com
E

(..Done..) XD

sabato 23 gennaio 2010

I cover the waterfront



I cover the waterfront, watchin' the ship go by
I could see, everybody's baby, but I couldn't see mine
I could see, the ships pullin' in, to the harbor
I could see the people, meetin' their loved one
Shakin' hand, I sat there,
So all alone, coverin' the waterfront

And after a while, all the people,
Left the harbor, and headed for their destination
All the ships, left the harbor,
And headed for their next destination
I sat there, coverin' the waterfront

And after a while, I looked down the ocean,
As far as I could see, in the fog, I saw a ship
It headed, this way, comin' out the foam
It must be my baby, comin' down
And after a while, the ship pulled into the harbor,
Rollin' slow, so cripple
And my baby, stepped off board
I was still, coverin' the waterfront

Said 'Johnny, our ship had trouble, with the fog
And that's why we're so late, so late
Comin' home, comin' down' .

(John Lee Hooker)

martedì 5 gennaio 2010

aggiornare gli ebuild

gli ebuild sono file che contengono le info necessarie al Portage di Gentoo per la gestione dei pacchetti.
si trovano in /usr/portage.
per aggiornare gli ebuild : emerge --sync
("e' il comando che non trovavo...visto che questo 2010 si e' aperto con Sabayon...sara' un anno parecchio dolce...ed e' il comando che mi ha aperto il mondo della gestione pacchetti : Il Portage, lo confrontero' con il mitico apt").
i comandi:
emerge --search
emerge //installa
emerge --fetchonly //scarica il codice sorgente
emerge --unmerge //disinstalla
emerge --update


...configurando il kernel ho poi letto riguardo i file di configurazione: (direttamente tradotto dal man):
Portage ha una funzione speciale chiamata "protezione dei file di configurazione". Il compito di questa caratteristica e' evitare che i file di configurazione vengano sostituiti.
[...]
Quando Portage installa un file in una dir protetta ogni file esistente NON viene sostituito, e un file dello stesso nome esiste gia', Portage lo cambia facendolo iniziare per ._cfg0000_foo.
Sara' l'amministratore a fondere manualmente i nuovi file di configurazione ed evitare cambiamenti inaspettati.

Per fare un update di un file che ha bisogno :
find /etc -iname `._cfg????_*`

Run minikube with podman on Fedora

After install minikube as described in the documentation , set rootless property to true to use Podman without sudo: minikube config set roo...