Pour Kelios, faire un OS, n´oublie pas de multiples problemes qu´un prog a moi a pu soulever en cours de temps réel :
Il faut gérer le scheduler, il peut changer a peu pres n´importe quand mais il est hard.
Il faut de ce fait gérer les Mutex, pour cela, il est inévitable d´utiliser l´instruction assembleur ( donc atomique) dite de " test and set", car il ne faut pas scheduler entre le test et le set.
Si tu veux gérer la priorité des taches, soitbien rigoureux : si une tache de faible priorité bloque par mutex une tache de haute priorité, il faut penser a monter temporairement la priorité du faible, pour qu´il libere vite le mutex pour le fort.
Enfin bref, plein d´astuces qui me rappellent le cours de temps réel, moi qui croyait que CT pas si difficile que ça.... ouch !
Merci pour l´info/idée.
Mais la synchonization des threads, c´est loin d´être simple. M´enfin, j´vais y passer un jour, mais pour l´instant, c´est surtout un mal de tête
En particlier les atomic instructions
: c´est un truc que j´ai du mal à comprendre, ne représentant pour moi que quelques lock dont l´utilité m´échappe, et de quelques instructions du genre CMPXCHG dont je ne suis même pas sur de la véracité....
M´enfin bon, si tu as une quelconque simplification à me fournir, je suis preneur
" Enfin bref, plein d´astuces qui me rappellent le cours de temps réel, moi qui croyait que CT pas si difficile que ça.... ouch ! "
Moui, ouch, c´est le cas de le dire, pour moi aussi
Bon. En tout cas, merci
-------------------------------------------------
Dans un autre ordre d´idées:
" A part créer la structure de contrôle, la détruire, ajouter un élément, enlever un élément, rechercher un élément, et appliquer une fonction à tous les éléments, qu´est-ce qu´on peut rajouter comme fonctions communes à toutes les structures de contrôle ? "
Classer les éléments selon leurs caractéristiques?
-------------------------------------------------
" Kelios ca faisait longtemps ^^"
Meuh je suis toujours vivant
J´ai toujours la même signature!
Et en plus, je joue à la Bataille Navale sur MSN Messenger qund je suis content ( genre, j,ai rempli un objectif, le dernier en liste important étant.... mouarf, le BootLoader )
Kelios
---------
lol Kelios.
Sinon la j´ai implémenté 2-3 trucs de base ( genre les operations, les aires, les volumes, le PGCD, les valeurs absolue, Pythagore ( a part la reciproque parce que faut que je recode une fonction racine carree mais je sais pas comment on obtient une racine sans calculette), les identites remarquables, verifier si un nombre est premier, les degres en radians et inversement, etc...
Il me manque les puissances, les racines, sinus, cosinus, tangente, et tout ca -1, et le reste je verrai au fur et a mesure.
" En particlier les atomic instructions
: c´est un truc que j´ai du mal à comprendre, ne représentant pour moi que quelques lock dont l´utilité m´échappe, et de quelques instructions du genre CMPXCHG dont je ne suis même pas sur de la véracité.... "
J´ai pas bien compris...
Peut etre aussi parce que je n´ai vu que la théorie la dessus et que je ne connais pas directement CMPXCHG.
Je V développer le " test and set" atomique ![]()
un systeme d´exploitation peut changer de processus n´importe quand si le tempo est fini ou alors qu´un evenement survient.
Le test and set évite ce probleme:
Imagine que tu aies une variable X utilisé par 2 programmes, en gros, les processsus vont faire
( écrit en pseudo code)
while ( blocked(X))
{
reschedule();
}
block(X);
manipule(X);
tu as 2 programmes qui contiennent ça. Imagine que X est libre, le 1er test le while, donc il sort du while. Puis le systeme reschedule. Le 2e teste, et le X est toujours libre ! ! puisque le 1er n´a pas eu le temps de le blocker.
le 2e le blocke, le maniupule, puis on reschedule, c´est au tour du 1er qui a eu la permission de la manipuler. il le blocke ( il était déja bloqué), puis le manipule aussi...
: violation de partage...
"
Expr a("2*x^2+3*x+2+sin(x)");
Expr b(a.Derive());
cout < < b < < endl;
et que le programme nous sorte :
4*x+6+cos(x)
"
hihi ! la dérivée, c´est 4*x+3+cos(x) ! !!
"
Le pire est la primitive, car autant la dérivée, c´est un algo bourrin a appliquer ( cependant, faut déja faire les fonctions d´analyse de la chaine et tout...)
mais l´intégrale, faut bidouiller pour retrouver une forme connue, et c´est le " bidouiller" qui peut etre vraiment tres chiant.
"
En fait, la primitive d´une fonction linéaire est très simple à trouver, et toute fonction non linéaire peut être approximée par une fonction linéaire d´ordre suffisant. Donc on linéarise la fonction ( développement limité d´ordre n avec un o(x^n) connu), on intègre, puis on tente de retrouver une formule connue d´approximation en o(x^(n-1)) en faisant des changements de variables. Le plus compliqué est alors de trouver le bon changement de variable. Qu´en dites-vous ?
"
" A part créer la structure de contrôle, la détruire, ajouter un élément, enlever un élément, rechercher un élément, et appliquer une fonction à tous les éléments, qu´est-ce qu´on peut rajouter comme fonctions communes à toutes les structures de contrôle ? "
Classer les éléments selon leurs caractéristiques?
"
Ben, si l´élément est totalement générique, il n´y a pas de raison de supposer qu´on peut ordonner ( totalement ou partiellement) les éléments d´une structure de contrôle.
"
Il me manque les puissances, les racines, sinus, cosinus, tangente, et tout ca -1, et le reste je verrai au fur et a mesure.
"
Les racines sont des puissances inverses : sqrt(x) = x^(1/2) = e^((1/2)*ln(x)) donc si tu sais faire l´exponentielle et le logarithme népérien, tu peux faire les puissances fractionnaires et donc les " racines" comme tu dis ( qui s´appellent des radicaux en réalité, car des racines sont des solutions d´équation...)
Toutes les implémentations rapides de calculs mathématiques sont disponibles sur le net, il suffit de chercher un peu.
pour ce qui est du test&, çà n´est utile que si tu fais un OS qui gère la multiprogrammation... Tu devrais peut-être d´abord te concentrer sur un OS monoprogrammé, mais qui sait gérer la pagination, les interruptions, etc.
lol
exponentielle, logarythme ca se voit en quelle classe tout ca ? ??
euh... Je sais plus... En terminale ptet bien...
ln(x) c´est la primitive de 1/x
exp(x) c´est la fonction inverse de ln(x)
En terminale, oui, je me souviens.
excuse moi pour la dérivée, lol
tete en l´air
tu ne m´as pas répondu sur le fait que tu connaisses ou non les STL ?
en ce qui concerne l´ordonancement, il existe l´élément est surchargé en <
je te fais copier coller de 2 ou 3 trucs :
Generic algorithms overview
Name Purpose
algorithms used to initialize a sequence
fill fill a sequence with an initial value
fill_n fill n positions with an initial value
copy copy sequence into another sequence
copy_backward copy sequence into another sequence
generate initialize a sequence using a generator
generate_n initialize n positions using generator
swap_ranges swap values from two parallel sequences
searching algorithms
find find an element matching the argument
find_if find an element satisfying a condition
adjacent_find find consecutive duplicate elements
search match a subsequence within a sequence
max_element find the maximum value in a sequence
min_element find the minimum value in a sequence
mismatch find first mismatch in parallel sequences
in-place transformations
reverse reverse the elements in a sequence
replace replace specific values with new value
replace_if replace elements matching predicate
rotate rotate elements in a sequence around a point
partition partition elements into two groups
stable_partition partition preserving original ordering
next_permutation generate permutations in sequence
prev_permutation generate permutations in reverse sequence
inplace_merge merge two adjacent streams into one
random_shuffle randomly rearrange elements in a sequence
removal algorithms
remove remove elements that match condition
unique remove all but first of duplicate values in sequences
scalar generating algorithms
count count number of elements matching value
count_if count elements matching predicate
accumulate reduce sequence to a scalar value
inner_product inner product of two parallel sequences
equal check two sequences for equality
lexicographical_compare compare two sequences
sequence generating algorithms
transform transform each element
partial_sum generate sequence of partial sums
adjacent_difference generate sequence of adjacent differences
miscellaneous operations
for_each apply a function to each element of collection
Ordered collection algorithms overview
Name Purpose
Sorting algorithms
sort rearrange sequence, place in order
stable_sort sort, retaining original order of equal
elements
partial_sort sort only part of sequence
partial_sort_copy partial sort into copy
Find nth largest element
nth_element locate nth largest element
Binary search
binary_search search, returning boolean
lower_bound search, returning first position
upper_bound search, returning last position
equal_range search, returning both positions
Merge ordered sequences
merge combine two ordered sequences
Set operations
set_union form union of two sets
set_intersection form intersection of two sets
set_difference form difference of two sets
set_symmetric_difference form symmetric difference of two sets
includes see if one set is a subset of another
Heap operations
make_heap turn a sequence into a heap
push_heap add a new value to the heap
pop_heap remove largest value from the heap
sort_heap turn heap into sorted collection
mais comme je te dis : c´est déja implémenté tout ça, c´est meme en standard, ton compilateur y a surement d´intégré ![]()
correction :
il existe SI l´élément est surchargé en <
il existe ensuite tout un vocabulaire :
iterateur : sorte de pointeur générique, dont ++ est surchargé, et marche peut importe le conteneur
conteneur : structure meme de la liste :
liste chainée ( list), liste chainée a double entrée ( deque), tableau réallouable ( vector), arbre de recherche ( set), map, . ..
tous les conteneures permettent de stcoker des trucs, ont des caractéristiques, sont plus rapides selon un cas ou un autre ( d´ou l´utilité de choisir son conteneur en fonction de ce qu´on veut faire, etc !
tout une belle histoire les STL ! !
vivi, je connaissais... Mais bon, l´objectif était de développer notre propre boîte à outil
et en plus en C
pareil, il existe des librairies mathématiques complètes en C++ avec dérivation et intégration...
http://perso.wanadoo.fr/jvprog/LibrairiesJV/elements/element.h
http://perso.wanadoo.fr/jvprog/LibrairiesJV/elements/groupe.h
http://perso.wanadoo.fr/jvprog/LibrairiesJV/elements/groupe.c
ok, je vois, des void* ![]()
j´avais qq trucs si tu veux, j´ai ça dans de vieux TP a moi, mais C pas online, si tu les veux, mail moi ![]()
Et voilà, un zouli analyseur d´expressions mathématiques, que je viens de retrouver...
http://perso.wanadoo.fr/jvprog/TPSE/tp7/ELT.c
http://perso.wanadoo.fr/jvprog/TPSE/tp7/ELT.h
http://perso.wanadoo.fr/jvprog/TPSE/tp7/EXPR.c
http://perso.wanadoo.fr/jvprog/TPSE/tp7/EXPR.h
http://perso.wanadoo.fr/jvprog/TPSE/tp7/HTAB.c
http://perso.wanadoo.fr/jvprog/TPSE/tp7/HTAB.h
http://perso.wanadoo.fr/jvprog/TPSE/tp7/LIST.c
http://perso.wanadoo.fr/jvprog/TPSE/tp7/LIST.h
http://perso.wanadoo.fr/jvprog/TPSE/tp7/main.c
Et maintenant, il faut l´adapter aux nouvelles structures de contrôle que je viens d´écrire, et l´enrichir avec des nouvelles capacités...
exemple d´utilisation
"
Pour évaluer les expressions entrées, tapez ok
a=10
b=2
c=a+12*2
d=c-b
d+1
ok
((a=10);((b=2);((c=(a+(12*2)));((d=(c-b));(d+1))))
) = 33.000000
"
J´ai mis à jour notre librairie.
Je vous rappelle que vous pouvez participer vous aussi...
http://perso.wanadoo.fr/j/jvprog/LibrairiesJV/element.c
http://perso.wanadoo.fr/j/jvprog/LibrairiesJV/element.h
http://perso.wanadoo.fr/jr/jvprog/LibrairiesJV/groupe.c
http://perso.wanadoo.fr/jr/jvprog/LibrairiesJV/groupe.h
http://perso.wanadoo.fr/jvprog/LibrairiesJV/expression.c
http://perso.wanadoo.fr/jvprog/LibrairiesJV/expression.h
et pour les tester :
http://perso.wanadoo.fr/jvprog/LibrairiesJV/elements/main.c avec element.c et groupe.c
http://perso.wanadoo.fr/jvprog/LibrairiesJV/expressions/main.c avec groupe.c et expression.c
à vous
Attention, le programme ne fonctionne pas comme un langage de programmation itératif : les expressions a=a+1 ne fonctionnent pas, une variable peut être définie à partir d´une autre variable, même si celle-ci n´est pas encore définie, etc.
Exemple:
"
Pour évaluer les expressions entrées, tapez ok
a=1
b=a
b
ok
( (a=1);((b=a);b)) = 1.000000
Recommencer ( o=oui) ? o
b=a
a=1
b
ok
( (b=a);((a=1);b)) = 1.000000
Recommencer ( o=oui) ? n
"
Mais j´ai encore un problème. Le programme plante si je fais
"
a=a
a=1
"
Quelqu´un a une idée ?
Encore un autre problème !
L´évaluateur d´expression ne libère pas la mémoire des variables qu´il crée : detruit_groupe() ne détruit pas ses éléments, et certains éléments sont communs à gp_var_ndef et gp_var
Je corrige pas dans la soirée.
bien, j´ai mis à jour les fichiers, la libération de mémoire s´effectue complètement maintenant...
Si quelqu´un trouve une meilleure solution pour libérer la mémoire des éléments de deux groupes dont certains sont en commun, sans perdre du temps à fusionner les deux groupes, qu´il le dise ou se taise à jamais !
J´attends toujours des propositions pour gérer les cas " a=a;a=1" qui plantent toujours. Il s´agit d´un problème d´affectation de variables. Que pensez-vous de renvoyer après l´évaluation, plutôt qu´un simple double, une structure contenant le double en question et un test ( dans un char par exemple) qui indiquerait si ce résultat est valable ou pas. Ainsi " a=a" n´est pas valable, mais " a=1" est valable, donc " a=a;a=1" est valable. Si on a " a" alors que " a" n´est pas encore une variable définie correctement ( soit non définie, soit définie récursivement), le résultat de son analyse ( comme dans " a=a") est non valide. Le résultat de l´affectation de " a" est non valide, donc " a" n´est toujours pas défini correctement. Au contraire, dans " a=1", " 1" est évalué de manière valide, donc " a=1" est valide, donc " a" est définie correctement. Le groupe gp_var contient alors les variables qui sont définies ( correctement ou pas), le groupe gp_var_ndef contient les variables qui sont mal définies ( récursives par exemple) et qui ne peuvent donc pas être évaluées de manière valide.
Une autre solution pourrait être de réserver certaines valeurs du double pour les erreurs ( type +infini, -infini, NotANumber, etc.) : une des erreurs serait alors " variable non définie correctement". Mais cela signifie que l´on doit vérifier que le résultat d´un calcul ne soit jamais un de ces codes erreur.
D´autres idées ?
non, la deuxième solution n´est pas correcte : elle implique que depuis l´extérieur de la librairie, un double ne soit plus considéré comme un double générique, mais un double " dont certaines valeurs sont des codes d´erreur". Je ne vois donc que la solution
typedef struct{double valeur;char valide;}RESULTAT;
De plus, pour la même raison, la structure interne du résultat doit être connue depuis l´extérieur de la librairie, afin que l´utilisateur de la librairie sache comment récupérer la valeur du résultat : la structure doit être définie dans le fichier d´en-tête expression.h.
la structure ne contient qu´un double et un char, on peut donc se permettre de la passer par valeur, ce qui est plus pratique que de l´allouer dans le tas ( en plus, ça signifierait que l´utilisateur doit s´occuper de la libération de mémoire, ce qui n´est pas acceptable si on veut que la librairie soit tranparente).
Au fait, si certains veulent m´aider, il faudrait déjà que je vous donne les conventions d´écriture que j´ai utilisé.
1.Tous les fichiers d´en-tête contiennent un triplet de macrocommandes
contenu
avec " nom", le nom du fichier d´en-tête.
Exemple : __LIBJV_GROUPE_H__
2.Toutes les structures ont un alias ( typedef), et une description succinte sur la même ligne que l´alias, commençant par " type". Si une structure est nommée, son nom suit le format : __STRUCT_alias__
Exemple :
typedef struct __STRUCT_EXPRESSION__ EXPRESSION; //type arbre d´expression
typedef struct{
double valeur;
char valide;
} RESULTAT; //type résultat d´évaluation
3.Les déclarations de fonctions dans les fichiers d´en-tête sont suivies d´une courte description sur la même ligne, commençant par un verbe sans majuscule au début. Si des explications supplémentaires sont nécessaires, des commentaires multilignes précèdent la déclaration de la fonction, avec des phrases complètes, sauf la première qui reprend la description courte, mais avec une majuscule et un point. Dans une déclaration de fonction, les paramètres ne sont pas nommés.
Exemple :
/*
* Donne une clé d´un élément.
* Plusieurs éléments peuvent avoir la même clé.
*/
extern CLE_ELEMENT cle_element(ELEMENT *); //donne une clé de l´élément
4.La définition d´une fonction prend les mêmes commentaires que sa déclaration.
Exemple :
/*
* Donne une clé d´un élément.
* Plusieurs éléments peuvent avoir la même clé.
*/
CLE_ELEMENT cle_element(ELEMENT *elt){ //donne une clé de l´élément
return ( unsigned int)identifie_element(elt)%MAX_CLE;
}
5. Les commentaires au milieu d´un algorithme sont libres.
eh beh t´as pas chômé...