From 9192ca5ea078d6412af8ddc133aeea8770ec2c0a Mon Sep 17 00:00:00 2001
From: rissadmin <floreal.risso@univ-tlse3.fr>
Date: Sun, 18 Dec 2022 08:44:31 +0000
Subject: [PATCH 001/229] Refactored project tree

---
 .gitignore                                    |   3 +
 makefile                                      |  53 ++++++++++++------
 mojitos                                       | Bin 37696 -> 0 bytes
 counters.h => src/counters.h                  |   0
 counters_group.c => src/counters_group.c      |   0
 .../counters_individual.c                     |   0
 counters_option.py => src/counters_option.py  |   0
 frapl.c => src/frapl.c                        |   0
 frapl.h => src/frapl.h                        |   0
 infiniband.c => src/infiniband.c              |   0
 infiniband.h => src/infiniband.h              |   0
 load.c => src/load.c                          |   0
 load.h => src/load.h                          |   0
 mojitos.c => src/mojitos.c                    |   0
 network.c => src/network.c                    |   0
 network.h => src/network.h                    |   0
 rapl.c => src/rapl.c                          |   0
 rapl.h => src/rapl.h                          |   0
 temperature.c => src/temperature.c            |   0
 temperature.h => src/temperature.h            |   0
 20 files changed, 40 insertions(+), 16 deletions(-)
 delete mode 100755 mojitos
 rename counters.h => src/counters.h (100%)
 rename counters_group.c => src/counters_group.c (100%)
 rename counters_individual.c => src/counters_individual.c (100%)
 rename counters_option.py => src/counters_option.py (100%)
 rename frapl.c => src/frapl.c (100%)
 rename frapl.h => src/frapl.h (100%)
 rename infiniband.c => src/infiniband.c (100%)
 rename infiniband.h => src/infiniband.h (100%)
 rename load.c => src/load.c (100%)
 rename load.h => src/load.h (100%)
 rename mojitos.c => src/mojitos.c (100%)
 rename network.c => src/network.c (100%)
 rename network.h => src/network.h (100%)
 rename rapl.c => src/rapl.c (100%)
 rename rapl.h => src/rapl.h (100%)
 rename temperature.c => src/temperature.c (100%)
 rename temperature.h => src/temperature.h (100%)

diff --git a/.gitignore b/.gitignore
index 5761abc..f5893ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,4 @@
 *.o
+src/counters_option.h
+bin
+obj
diff --git a/makefile b/makefile
index 433b76f..064dfca 100644
--- a/makefile
+++ b/makefile
@@ -1,30 +1,51 @@
+.PHONY: all clean mojitos mojitos_group debug format 
+
+SRC_DIR = src
+OBJ_DIR = obj
+BIN_DIR = bin
+
+OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters_individual.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
+OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
+
+CC = gcc
+CFLAGS = -std=gnu99 -O3 -Wall # -Wextra -Werror -Wpedantic
+
+ASTYLE = astyle --style=gnu -s2 -k3 -n -Z -Q
+
+
+# depending on the context it may need to be changed to all: mojitos mojitos_group
 all: mojitos
 
-OBJECTS = mojitos.o counters_individual.o rapl.o frapl.o network.o load.o infiniband.o temperature.o
+mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
+	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
 
-mojitos:$(OBJECTS)
-	gcc $(DEBUG) -O3 -Wall -o mojitos $(OBJECTS) -lpowercap
+mojitos_group: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS_GRP) $(SRC_DIR)/counters_option.h
+	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos_group $(OBJECTS_GRP) -lpowercap
 
-OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
-mojitos_group: $(OBJECTS_GRP) counters_option.h
-	gcc $(DEBUG) -O3 -Wall -o mojitos_group $(OBJECTS_GRP) -lpowercap
+$(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
+	$(CC) $(CFLAGS) -c $< -o $@
 
-counters_%.o: counters_%.c counters.h counters_option.h
-	gcc $(DEBUG) -c -O3 -Wall $< -o $@
+$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.py
+	python3 ./$(SRC_DIR)/counters_option.py > $(SRC_DIR)/counters_option.h
 
-counters_option.h: counters_option.py
-	./counters_option.py > counters_option.h
+$(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
+	$(CC) $(CFLAGS) -c $< -o $@
 
+$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c $(SRC_DIR)/%.h
+	$(CC) $(CFLAGS) -c $< -o $@
 
-mojitos.o: mojitos.c counters_option.h
-	gcc $(DEBUG) -c -O3 -Wall $< -o $@
+$(OBJ_DIR): 
+	mkdir -p $(OBJ_DIR)
 
-debug: DEBUG = -DDEBUG -g
+$(BIN_DIR):
+	mkdir -p $(BIN_DIR)
 
+debug: CFLAGS += -DDEBUG -g
 debug: all
 
-%.o : %.c %.h
-	gcc $(DEBUG) -c -O3 -Wall $< -o $@
+format: 
+	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
 
 clean:
-	\rm -f *~ *.o mojitos_group mojitos counters_option.h
+	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
+	\rm -f $(SRC_DIR)/counters_option.h
diff --git a/mojitos b/mojitos
deleted file mode 100755
index ab3f7b4824740935e193e4d9efee35d0f20849fa..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 37696
zcmb<-^>JfjWMqH=W(GS35HCR!BH{p{7#zBx3<d@U2L=lUUIqsS1qOKrHU<U;7O)sZ
z9<Cn3Ww^lvVZdk(2$z8ws!syMU|?WCr)8k(U^K{0AR!P9vJb?@hJQ#xL}4_80E7?H
z#|mO9fCvT#1~fVn>R%X*tPgBo08}3u9Uuk~htbITKw)zs4I+P`43*x%4dMTgg3vI1
zpx^@Q%Y}$vs70kefIPy$zyPCR;R$jh2wOnI6P-r$E(5y02&g`E+67`g1B?dQ0TK#+
zT9N`{quT@H<FYRRs?Q)AWC{ZVI^6>GAB+as0a6+Gv?K)-E+95B7#i&iK~Vc}#e)GS
z#55QUwVpvgCo{>+L_a4*HzzZ%v_iMS!c5o9M6Wns&j_pm<SvjMpfu&~7s|lYz;FO0
z2Gb8>i!d;N(>X|<LwDAcaM7TH>#eRm%;_wd(0cP_BS;O%43Hj>8j!)DXaJ=F5F3O+
zd}9U%aGnJFpRtjFfl-19BxcIMz+lF}z@Q=9BXcqJT(0G(ZW-ev--ST>aN!q>3=G&5
zfZPC!Gi1Fd7_h7VghRXshxxuZ#3gZv&&DBMgTvm{IK&ljn3IG<JOhWg9}aN`9O8#?
zh@ZnDUW!9p2#5G_9OAEWgu^Tx>NnyLmqjWfk<$Y=4)tz0#Eo%?hu{!Dh{OGVaEQC%
z5Z{Tz{2MsbU&kT-1cx{a4)Y)25ZA#W9*e{LJRIuZ;t)TGLtGt)_<0=me#N1_6^FPE
zj&#zG!~E|!#OrXFZ^_8OAjlxi(9i@)g|K>S5hDYG5=01vjE1UTfTsQ~1H_yTs5q$X
z1#67=4DpRmNi9lE&nzxUEei2<&dJY94M|MONo9zSPtVQIi!UxoEGmhQX8<e3s<0rx
zJhdn}u^_%Eu^=ZtJ+&l0FEKZj0gG^HZhS#va&}^RYB8F0W?p6qnh?mK)V$Q9^vd|s
zEHt^4)Z&t&{7Qzjw4Bo742I&8qU3@~hT?*v%)F8`hP3>G)I5g#f|AU<6o!J-qN4mF
zhT_chyu=)ag3^*=hP3>mY=)xL#GIV`WRTvH{A>u7!;lOY%t_5-$W6^HPAy?b&&f|>
zNKY-vFDPLsNGvT*WhgF5$uBKoNGm8UNd~C`*`Ai1lV6<5kP9;*CAFxCAu~U@B!?k0
zFD12tA+;hkxvT(UQ)x~PLuqkNYH9&PT6s}sNh(8fPJVJWDD+A)b5j}8pk9fOPp(Le
zPs_|p%*m`uWhkyJ2Dy--IJKlKsWgqDpeQvl1!Q7!ZUIAld`@OkGBm<+6EpL`%JcKm
z7}APTLGcMPDzPNBBC~`cCo>5aKcH&e03?tMVwo|x`*=Dz#~bMxnZuceCI}`%)JP9h
z2Qx7+GB7bPF))Kk5D&r!iD6=p91Bz>NG+-gkSs`q6{>;}YBop=gc%uF7`T}jV9iB_
z_KDNj7#LU?M4@6+z<d@41t@<yn9t0h4ds_gWpXkwFfo`x8yT>6DJ)+(Xn}JD!wqPA
z6(-IA6@P#x?i>P9{{u~25-KiG4v~kM^CcL<*FY0zg{pTz6BmMtN1%zTLB$Ku#7&^$
z9cbeAQ1Jz5;(k!^9cbb)Q1J_B;#pAf7ii)YP;rI|i2q>zZG(zSpovd`iW{JbFM^7D
zpoy=CiYK6n?}3U}poyP^icdfjzXlawfhPVKDt-V>`~y_{2AcSPsQ3poalTNf|0|(1
zgkq3|iYuUr>p;aV(8R5w;sI#lUQqE2H1SBNcmtYv22^|ons_->d;^+z8&v!Rn)p<x
z_yaWYB~bAnXyTio;sRBW0Dz^315j}dH1Ts#aR)T<J5ccmH1StZ@d7mQA5ifQG;#JY
zh&vXbiHkwScc6)@Ld7qjiJL&hU!aLQL&X`YA@;!h8w3@XKod`aiW{JbmqEon(8N2S
z;t6Qtv!LP?XyR+2;uFxs_d&&1pow3BiXT7|e+3o4fhNun4)Ny)G;uMgI0vYs!oUFU
zXX`-470|?;pyC#2;!#lX05tI;sCWjNco$T>0Zn`nRD1@S_%5jU1~l<YQ1KIJ;&-6p
z575M)L&blfiGPNQ3qZ#&VCjJ+0upW-XyU?9aR)SUWvF-rnz%7kyZ}wy1uEWwCLRhE
zUw|ea4He&kCY}ZrU(pD0FU<Wg{sA=c+9-&+6KLX1Q1J_B;_XoJ8))J^P;mxmI~8W{
z&q#>*9BAU&Q1t?6;{TxPCD6oKq3RXT#JQm28ffC8P;mn^aY3lK1)8`dRNMhgTplX!
zfhMjB6;D7DuYrnZpoup^#S75H+o0kVXyV;a@dNdc@B@vZK$|{bffGpLf?yE{aREtO
z0wM$^Zy<^5gGC_310-=1h!B{B^;<yWM4&Mnupk2i1FRnc5(kapz{Fww7LYioZ3z>X
zXn?TTp<_W19s`2{k~nCr2qvz9Bo6QEFfcF}Ac=$QfT_1Y5(kA5OxyuU9Ar04+yhA*
zmPSEx0Z8J|p*4^&Lj;mI7gz*BBp``HheW{=8A#$hU=avWfF#Zf5dxDHNaB285eU(M
zB+d^J0+Ss`;-E1&upk2i!vrL8<Z-eYNaDgU#S9D#3y{P?<9#rx6-eTuFhK?eh7CyK
z(4k|n><%Pxaj*!4IDjM$9ohy<oInzX4IzUhE+C0Zg9M=X29h{zOdTZk07)D)<^vJ~
z;TK5aav%XH{(vMd4;2GZKaj*x#u1_A8z}84f)qkA2a-5)KVASyTp6ksL`fittAGTc
zSOG~~6)FazG?2vAKmt%~fF!OC6$4QgNa7kG0VsAr5{FI^fMq<8#Gzdyuy_EHxHeb>
zLPQ{mgT_oCq6`cPNaDIMK?Vkf3?y+qB=G_yaRVgr3M6quB=H6$amdIulH@3JGz3ON
zU^E0qLtw;)fJgHi4v%iuqwx$39<2vTnEqezXg<Pm7#<$~O&`TGF#K1263@WEFYmzc
zUlqj90Lj06@c;k+|Ejm*85lsbW(+Scfccj|d{7hn<pD7N6o?OMn!els<{tv_K~2(^
z3&8wcAU>!m`f>u8zX`+#H9=oCfcdLHd{Fb@WdWGK2*d|9IbSA#`LjTLP*d||0GK}s
z#0NDoUpj#KT_8TFY5CFs%x?nmK~2h+3SfQ}h!1K?z7zoSi$Hu(6Y?bkn4bmWgPM*n
zKl}svHwnZCH5p$%0P~|jd{Ecn<pnT52*d|99bX;*^SwZPP?PcH1~A_V#0NDMUoHUi
ztw4NG6Y=E)Fy9Eo2Q>{}Hh}qBAU>!`__6@ZR|4@tU6PjxV7?TH4{92|3;^?mKzvY>
z@TCKo&jsRxnu0G4z<eeUAJhbVsQ~8xieq5N05$zy3V`{aKzvY>?<E76{|dwhHT7P8
z_zUv?BM=|d#C!Pw%)bTVgPL|PFM#=%KzvY>?&Se6{}hN1YRbLb0OlV8@j*?vmkYrB
zT_8TF>GpC0n7;|c2Q}GVHh}r7KzvYB?PUR&zX-$!HPK!sfcdjPd{EQuWdN8z3B(6A
z$zD2u`CTABs44c+0L*U!@j*?nmkMBh6^IXNdc70?^H0SvFr-ZYC2$aS40jB340Q|%
z_2~Q>?9u$jqxnB0e~TO&1A|95t9?8JgJb6(k6v3<b_NDl!~c%^KuN}@SNFU=1A|Ae
zESmuXgGVQ8eLMrhi%Y5?A=B4v3=I20$?3(#zyJRqcTwR1O}!s?Q2`|>hT|?O93Xxg
zzkCbGdIq1)S00`3Tsoh>SoH7z|K=b6`CEQ7GBEhI{^xJ~#K^$V{36-a@PG3UA^!GG
zRt5%-WR_+R#vA`1`1G=Vlm%JHn<dS_VEE0|@V`f|=sU2GZMhT!!wVyJ28P!QJd#-(
z;}{rrfijHYH;?X`qYN)H{{H{J3*?ICAB>VGLB=0sY(2p5dZE)tMW8c8h2v$~|NsAe
zdRh02fNhu|jIg0b6eMK(Re*uv#RWD7hL_g=|Nr+$W|fI!VDRZ>_2mYKlSeOaF+WJ5
zsEz<ABukDmc=Xyb@G&sFm<`gz2GR697No|sUJs%P?6~N^|Nnb*vg*V!Fuc6~@Be?p
z121;4GcXwbfAJ9{lgzp)7HpHV1VmFWuctW36wyU;2%Fku85mv|f^3@e5A3|!Sa=wK
zLJDkC;-CNjJ6%+GURFTVL_%C6#md02AC%vHdO?B3{pbJxmthbU<`An-h{LQtCkD3q
zJIDpy5KnrGGBCW@#>&9(Qt=-+5VMp(YIr{@A_8$cSjhH(0t3T~ZjjP%fB*k?HT?GS
z9mtE_w)(LkwL3v;m<->7W6GmfwoI3S;f3s<|NnP^3OkQ(Ud~tshJB!D^yszq1xY^m
z^Z$Rd?a3Gh28I%SetB?@&7+%jV+<%@Y;S?6&U+r+A}<UNcr+hneBto>|9?x}SuqR@
z<u_bgzwx(xW&)`+-4MgTupg9QUhMnz|9`iO3J3ps7ZsjP7Zs7#1N?oUB_JNhT~t72
z6ocVgpWYM|1CL(W_c{y=E}bPR9Q^Vw3=I204)f`J<_b!hZ(m&f`Tu{nt$z#yL+k$%
zbAEYH?y`&lX?W$;ZSujRo0S>lyk46N9^I@GF$@e&|3yA{HXmbjWIXC(X(|SC;~7w<
zXaP+CzYzQL|9|TN{+1Lb28I_qfBpaO(OaUT0Jif**3bX{J-U5VG(5UpR4hC!5Ayev
zGlKkOdm|b|g{UZaXdW~?;GrD?a<{3D4g<prQ;<hR`=db-`?mE`i6Jb1dUUg9g0<Ps
z0#Tj!yujh-2?{@kU;qERSn5VbGcc522L%(zNv|0|mYC*5!@{uY=l}n{t^Z3Sklc9e
z$N&F39Gv(Wzz&`Hy+(zn^SH;3^WTFXFP(iv!Q=Z&kApw$JvuLV9Q?uVp?Sh1`Mk$W
zkMBP<ufNd#{r^96j*5U~j*19>|5Q*8x!r901vCs+qMJ6sqnq_%6vzcOH$1vok3}&s
z{1>^=&3Y9i)_j=J@<#dH)&u;lpk+TE%||>84@Ad0#yG}0#yQ3x2G#%FB`O>sM_IIf
zD=GEp1_e>K?R=2#UQ;G*1_r|eFF1ex|Nrv*zyJS1>Oo2*Ji2XbAWGhAft5V_@&EtJ
zZ~y-Pp8%3q@Mt{9aB7w{EW~$dfgEV-3DTl@(4+Ykqv3%Un?YJCLHP_3mGi%YqS6Hv
zl|G=TJW<Q$!3s7>^MpsIi;Bd{C{RJtZTl>ef#HQCShejX5Ze^O-Uec8LfDHyY*`3<
zABZjZ{r~@$-$6EZ^X`pgVAus}WWX{Mj}`;Ni++$#U;p|4-?Q7^r}N(n`Jey)8~%Th
z0ZL(=?_U@&GB6mv_3XSD=h6Adqxs2)fDoTv)?M=8{2mOZZ0G#^|Np<JT^Iwy7jVAt
z=(T+r0aC#F2t--_C=vDOW(CdCfSPBV{~ti}?O`bG(QCUCq_Ed?6Nu9M=h6AW<KR1c
zkApv$Js6L9T>Mue;?d3eHWbpn<M{s|4Qvlg|7U)=Uk$c%L8INJ+MyoJwx>W7NFJR}
zOL#oGZQH^b7+$>m@&Esel>h(#A7d?zU|?X3J<Ko9fUN&z`F~JkgUge{X=!?}yaA5?
z<~JOM|6hdu0I6_cV1TqYZF3_S7+yF)0y`1p@a7{NFCTpU{~sc6Zg{|>*EU0yf#Jn#
zkYKOv7Z7_sge{=P!0=)+gdM2C!0@6S!qxzZS3}q?Aa*{4y#mBehOn=I*x?YihB^bo
z3vUR!2E?|9uvdWC#t`-q5L^8#I9?}w|Np<6byYY6gJYOy=Qqbt&(6Od-L?}!0wKKx
zjGmomLVY@q277c~?lf%<XJGI+_>B2Q*0=xvyG2XF85n#zzk77DCWSLFG{0i>=ry_E
z`2Q-XNC0KFZqp!;hHhJHkZGMq!CLh}T1_n>5>g<llT|vLfuT3-KS<uEQ{}=7Zjc&L
zQIKS}?XxgYk@?P}ll4s)0|T?^y)cMf2cI!}bn0Aqaqlb0Eib~rt&*K#3=F+q|2?`z
z&w~WIO-^--t_87rZ7%%3?9%zpquaI@Y|M0!D9A7KzW)Co?ZT+r7RJC3>lowF$(j?!
zzyK;9VCkWowF{)U+qN2Hdcprr(<%@jq&X3!Io6|-H36gtT&NtL5E|^!D;w?wO7W{d
zfLc|}Z#cl|rrX-1`LM)`HJ|_g_pp3j`X1CRiH<$&81C8m9~%6QA)cLALOqgS27C0{
ztOYffK&j`&%`c$x-sUYxz_XLxqx0~KV_*LN_v~bAeOqT_c*&#J_L(OG10)}KCi6`3
z=;iVB=;b-@(OoFe?aATMX>y^HXR=50Ax00&tEG1#Hp5FnlmyNIY9IRanr5moFo4p-
zRgjy$go0X%9LGVO7zUrtZyv`%-64h-2f(g44$8;{usq_?s~hRbz+ia$wIDcOHXmm6
zXg(^@{M)M}#iP5H0aUEa`27EW>w(fIj@>LOp53(!%?B7AJ6TjbW_a|Pw1Ry3f(>MH
zvWSY|f1l28o}I1?oiP*sya)h^c7p6Hoq_HNxc%L>Geba0^Or}jX*#5I_W1n&Kcudl
z_vQb8O#g!0!<~QkgO&gUdo;e;0jknEOH>3rIzv<>Uc3ZFS#OAn!%k2y>bQ%F38-Z7
z=)CUHc^K55GCc6vWA%Pe3;vjkN(AEz&Cmb;r}5_<PUFuz+j%>UKk1-n=aDr2YYZOA
zM?HFNj)Hs$D$NyM{Qm@sMi&(hkIq9Ly)1JfGAt^sZ~6NcfgKT}qTy=z&8Ig<#lW-k
zI=CI-q9WkYZKLAVtMe74-l>~qL#K<10jTzu@aksy05aO*#gb3||9f|`eD8Kq;b}ck
z;^EU>qoQGWdxGHs$DN?grsED!%f9pGE)eC@`EI`!BLl+=y-%PL>&O2R8_(_#P{qij
z)yXo`qxmqSkLB;u!=9bjJ)4g)`dF8!DDbxyg6g8iBcRao>3o1xuX^;_YO63XyqEwo
zt=pC}7*zd*s91msK~qJL%(joP7~ug07NUrq;27#^_!itf`3p{T-Qg^)m+AuH{fBN>
z2ESeva9%LH-Fl!-0akBxyK;DSvnX`i%m6v}#gh;J|69f~)Iay=cI5!IUc9<(6khOs
z0JUIpS?YIqbk}mc`2QYM-_{De_y%D}ym$*?D7<(AVl*G&@aTLG@!88u@BjZ#o6zmf
z(t4mS6T_M8tq1Bn_~nrt2g#2h>kTjMV^CpWfI1J<7(LARLixl0|J|+(mN)9}IQE7z
zT86UJf!*19pnf+ZaUVvnf5^0-8N>d?@5!<sR6c<73n+Fpy2DvKKuzG*OZ<JH3FmHh
zP-zBkQ-IQ}MA`&+!`ZJ_<?E0Cpp0LaYIxi5Ei~RdyWKf<ffA%o=R0Tsz3>2sJ*aC4
z+N9yw%?^rD59S;d3CkPx=Nv(ncKfJscy;D{{NZBxsg4blC|^(YXg;C=i7RmH4wNA{
zypFqk_yNi$Aa(aTFSuxaXnw)yXnD;y`I}EK%TbWcJ3xdFzwZIC4v;B^-=br^dTl;9
z#`ts|0@VhN@h_9#fzk@EO#lPKF3@NQ*pnW;wmFIn3@^eyz|ynL2b2<K0;qid4()P-
zgACLv7V+o}QIUWL&5L$Wi#|C=MZ}{!MnwWv`1|zgfYZ5W=erkI-~IpZ)A`=B^T>-+
zAcyptes*SH@a#Nbc%b!dogN|sc_fQ8d-RF~dGv~0^XT>x=nmrW?BqG%*eTND(R_f>
z!}3Mx9iPr;KAneLI=}mLx~Oox`1uQD_H&QUqc7gQ0eP}Uh2zB&5UVp*!Kd^6iwKD2
z9-XcNAP0DY9MI`1(d`P#3gO+Z46cT6TMyKEg6cU$<|LH<-=d^H>rj?jc>4G0P8IO!
zeCE;l{zcDUP!XvQiWQg64@l7qO+S!vjLzR4o$o=FrAK#}#EXc(|NnP~vUqftN_ceF
z3bbCTOY-P-=kTyR?9uDS!9Vq&hvi}ZsRvpPmL&E%{crxkSQgoN(eS{<mmUWnvOvxK
z%%9J~_L)DQhdqt|_d$L^7G{s;0|FkFCrY1oUTA*s@7p0pP>Yi1n1?pcagR=(!yd_(
zJPtl$e!&g)7Yif{AD-aYdBN}ixZFlk+I)b~)AB&+>({3ycqIF=w4SWf^yzj}0GE%_
zPN0EF2G3-X25>xfi(K>Q6gduwyo06B4<q6l6yDu#pyJ&VR89W@hlSy7aJ}o%?JD8Z
z`N*^R2uHWc43BPCg>Dvb$>`C`(%{i+)8KLNIg1B#EyIgdZ$Tv`Px)C;;9`_Fj^X<)
z7(fj~Xr^y`0~*f(WqOGh4sSpe-TMQ_9YDj644$3G`2`&$Ufg{1|G#6WI|ryKsK>;>
z(0Rb{t>JBCdtb1<0mUl2N9VEEoRD<l*=_E@_|EWB=lvHqUx7*q{?<E;3=EFl?i`>d
zMB~v3j0_BxH_ESj9(M<iEE(Pgb;K1wmS{49f($ag)Oo|F*Hm2@)cykbQ>Ve>;8PZl
zP8}83Zaq-7xif_U)H-<N$!zb^`R>Kq*I>K)K$Wsb?-~`*I9caSpUy|%xHteBx9EKT
zA{^wSZg(Ef?s|dV0!GKqavo57^+o(^(Adp;&rWv%P^~NQ;@`{v{~f!_c|3Y67&}W;
zcwWf9{{O$bM1=>`EfnzVJmA?~FVX7;YV9)lbg~=*%Y!s{cGoL-cDhS=9DK&~f&*;q
zJI_vc1;=i8p5B1}p55-CO8>%(Sg-{!F$tGWoe2mf3Y{_&Je!ZPc=WOwDlss4S{~zX
zW&QvEfAe8RN6UB){&vv#l52N9&wfyeXL#GE^PO+!n-@P{g7W`6u%KtBy9THrc={3)
zLGA{wt#3=LK<Ui0+g-w=^OZ;QQBZpF>~_bNo;;cDUqrwD|KGJcoyXDgPWdTNi7MgK
zY2nd$1e9!C(3=T*pu#ir)&Kwd|NsC0|Hc1Tpq8%f4bV7I@T>p-o6rA$@%j}?feKEB
z(6LL7ZdV?U?lJ>V8u-EhDh~g6c76qA00#z0`hVpKaWCHV{|Z!E@L1j|KizrJqr23=
zqq|nar<dg{sM=_~RFViPG(0Vj^g8`_<ez%5`3EEa^aGA92TM{wg^H);k&<Xc=`jJd
z+;HR<WMP3798bUnNAn}b5<ZU^9^E3xJhVlQdv=N(@##GD;>rt9amWKHHb8Cj!;pMo
zcmP5ptA~{ZuU{XX0CKFW;epq?q2(5|>C_$0(R!)G1e8fs|I33r2ax>X(aSO$CHq%D
z2jzg$a!?&>8Ou?AuiF(=qR4`R5!Ao!b_J!p8zAWy=bu4}idUdw^~J$wpvt0_;l&OJ
zL*m7H2t(n;G6+NC#asx(;Kh_@|NlpObiR*ujCtAd4AgmsxW}jSIoRlw7a*fK_}ioZ
z|NsB8;y<Wl0gbD9bpGnD<7xe0lJC*&C*aZR$l+mmsKm3^{eSZhrZUIQe})GxzVkTv
zj0Ng{Q1~<Q3$idlLj6POyUriY5B@bjXDrbLg*wkck4~OLpumOLj|g9rgC3nGhah2l
zy!1Ut3CRDg-%64}J)ys#BKAvYu;Fcw#y1_{#`#mnZksuVCwGCCN_lj?dm-@R|9{xP
zbLaaP6Q6<dkjq^LkOw`Qf3uXH_h>u<(z*jQT?8s_9YJFcpxy+7;eo^8a@+8LN9%w7
zmQYaH7mm~~{1Xc5nap5eU}&(9@abKnvVehsfxqP{$RWL~d7!c2US4}S28R6s4502;
zng@U02@rA6qnCBQ94K=<Pvg%y=+VoYDaXJ7lDWXI$)W;c98BZSImEB&q9X7j7ZhKe
zM?Jeu;(a<F`E<TFJn$m&`Tzfh-ym#Ie0I9XI(Rf6X7OnLEl_&Zvr`Y0%2HGmx@%+|
zprPT@`RoPLb9iX@bUuI4{1jAHy2OG)1ELia8XylLg$B6c1`daYdPWBRR>l7yt37&c
zndKN5UMM{K|9{tWW>ES4uJd^3(HHVhK_%Dwec-X%M^FC$-v=7f^65=r1lf4;$^ZYI
z?~gGsytw}4|Noa)|AE@?=<R98FrVHs1!x3AD^QQ-BMqLNPtg2h1hO4u6DTa6zu5c)
z;vWTgP@MPZ4dw9ZeBq&a!K3+yLRrXX{(M)3&;0qZ3~Bto4?FS;x-x)-3_kPcrwXL;
z|2_f|68OxY@2da~1AakYhR=@t`C$V5f}sK)&2JhYX~Z!Olo%oD6;zUWXuC3iI>jE{
zt{NWNt{k47t{fiSt_B|3paz<&fJe8hg@?AQglDI##Onp9{augN|0UXvAwIq70ihn9
ze}g@G;~l_56D%(_KK}pT$MSLM2UtFR@aX@4^zicNWlaQS3(MmrGHLwztUfLb4E%!Z
zY5e)TfncV;0C-&0qnp(bq^^_I2tpY{C=&=}>cRjTa&usC3^P2r>pwGOwBc{Jt&9r;
z1E>t^)irWuU<d|ftDR5&|L5Pvs^kiq9Wt=t<ZlCIxE-JY_p}N8+e%m&IuC=gZEx6x
zhF_fJZ+&}H1K|BdpXATbEa}x-W6JR2&m&N#bY*bj-{xY<(EP%{hO=C**O}2{2Be(j
z-{u21FA!v2*;`N@(tMcF*YZv2MtFo6-hMqDR4+P)8GiHVwJiosN*#byPQAM2E({F8
zFA5+3{}1(?M<*!3vf4W{FuZv680?*37r1voV;*4d@XIq`@sCfhZkq=K1K3*=(EX!B
zp?`LOQZ#f({IKEe*OO3^ivxpWIMfTEK8#PV?i^=O{CIZ$@#%aA85Zic&2VC1cp(h&
zR*f^<Tl!243{Y=5FgRj*?2S*asjoW&gJ*9Za(w-U#+P?*jV;3qpNF9MVsqx-=3)zt
zE(LIOLCbqb%m{nq*?bJtX!NvvSGvKYm-V9?s4aAazvT|3uyh33X?cXd<qQL;V$5ef
z;Rd3AvnseVFo0@o6;Q%H3>B1y2)d{UfJFB~MMYtv3Lw$#P*HxEr~ycHBUF?VCh7pn
zCDCBfe9>e#1_p58r}5{@ra=T%^B}ZtnHvKGzb0=#m=c`<reqg_Db-bAN_VpxXz=+6
z2P{Q8#vk_RX8r5Rz~G_H8V2$*Xh^M_^)p1o2P^^_YU*Zv0TFV93JG|0v)+XWnL&jl
zJi1vgL4>rSLJA(;tj8fj3Q!>pk8ajI5Ft^hkO64^4I;z^6|(T?W?cpm`tJ&=hg?(~
zJi1wDLxjFSg*;w@8mET0Uq1hf(%$Q~<#J$Pcqw`x)MNma9lflI4h#$)md8t6K!MET
z055+8!AyTpJc){e+2Nqrk(C6q<3VwvDhp<(I~+!g7qXtT2M-^gf>5U+)ENkM7DAna
zQ0F1k1qgK!LS2GTm+cuC4yR23*WRE_p`d{hPtc$`s5Ao=w2f~xV6}IOibAPAsD>-m
zG`s{ZKdy>{YPE+i?%x0ZA2dKzqoTmT-!dDNV7tNdK^h*ttSO*rSIGP?wpu=092B~+
zTHZq(cP-z350t6EwY*2?E1%Bih6i30gKYi=VQ;?&>cJsb^H+R3^*nn^9YDhYFTef&
z53a8~8jpaygp>l)CKw(-t})Ukc=WPfw1dPKxW3q92am6VU?!rzSO`+r$+`$aErw7_
zAk<PjSbY&<cp$X%YOqJ=XTxtV_`nW5(){CpiLyuXRgcbloyT8r-UTl#D3SD-;nMls
z)$qwN7G{PQm+$=l5AA;(cIkZXxCh+h*n8*y|JN^&$~@$jKyMVINAhitgO8aZLkspE
zo%dd3-v!nC??Lr1XfTB54yemg!T7=$EdI{3(?#Y7s1@(gc^ncjFIV0MH)bLAw_~{B
z0Z>uuxEEA^fhuBEPEQ5~P|L%k*Yt-dsLtz^{RWyqXnv#7E&9fXfuXZTg~y}w{)-ED
z|Nr+%{@~TiV(ih$q5^Iwb%&_%xOBes=rz403Yv-pHGEcp)O9{L{APII#hW|-|92j5
z1`VdEgJ*?JRCa;7z@4Dh-u>JE|997@2!N%T!O}b`9y5G;ZA-mCGsEAGu`n{cn0fpE
z|JUNs^45l{l*REFI|FFQ&9nJ9BgkDGw?Peu4`srR{M*=V6iRP99%GMxeHY?BP;;b~
zp*MgLIzZylc?~kGt^^9X&ifvnt_+aQ^TAutpnP!~)UogZjdO#B$vW?ObRPHUbP@dV
zBJS4z|4<);Iu5<2tYA+&HXmhtvFQ$|2PFU+*zGM~^ho{&?o00hnUx$W0B*E-fEr4@
zA`=V`fSe%k;yg&QJ48jGld0KNfbr$}fB*l#Sas|F|7O-=Zw3ZN(5Mq65}^%KP<^-`
zv<|>A%yVCIeo<;kYHk6j*7xaEb#i532sL~Qn*T9(29?ckEI`8~9H4<vffpj+MDYHA
z;U%BWcl?43pt7q#1eEEYgW~eI19(uwV~2i5d2W85Y6>Vw6n3P7YN$>Z6&=F^$6Zu3
z^z#yPA?@^|pg0lbmuF}`%IMSi4xDW}U%gm&8`NF~^Im+q1<J&rs4sB^kFY{=$LpJr
z+@T4|9sj{uW5-QU{27;SZm?}}Vqjn>UFFejqSE>Ph5z6G|6k8_>HPm<>P=9Tu&98h
z$~inb8M_?>JerSKpac%MAJgq7(0ZUQ5}J*CdR4U@AgLSFaRRT+bLB8R2~L7OozJ>$
zX1us{3#FeBeG^nRx!h#{bv(f{`1Pkj`3Yhb#`qMZ5!?KRquU*1v6kU&NITA>+m*qi
z+vdg#=^G%IyK=xL22S4qbu<O)?}28cUi`fdlC9-<@dd<yjrYHNb{(8$LG=x&|0&S=
zzb?Jk{l7;yAE?*q4C{tkA$LC^`5RCFQ`Msz+WX{}XTa0%M44}P4EO1^{jLidf%ELV
z1`5`%jv<bne?mQabzkT*Fa-N({somzFPK3dIQW;jL>km{XYlF#<O5!3<@jIZKDYyF
zdAIZxA|Rm&n&B|=a3aXR-J*#Wpw&1pjc)$`4^GA$AYF(Rl%QdeQ9K#~qaiRF0;3@?
z8UlkW1VHDFfLs(>oS2@fV5Oj1tPrhRq5wL9B~~F?H%%d}D76s8DgqG&3I(Y}Y4JIk
z#U&ta4u~iP5y>DTMIkS>q&&YUJ3b|~EHgP3B$la=nU|KCmzk89ml9u)Sdsw}%vZ?C
zPfyFt0jo$=NY2mAP0UMCNGwV(%}vcKDb~}|iv^9dFfcG=rh(mJYipoTl98IHkdvQZ
zPz*J*B(p3v2YT*8W}1R-szPS5LP1e#acW+P4p^H4$XJjM6cUS474q^+6iSOzLCtvv
z-2#Qg<dV#?#FErvu&45iauf5CL5?ZSD@iRX1_cV}Y$FA*EZEB+<CF7q6BUY63lfVG
zOHxx5Kp~-!p9WTgZh}I2W=TeVX^BE{L1J>Mo`P$Il|p7-aY<2Wa!F=>Ua?McVsb`m
zd~RlOaVpF@2HhO6nZ+RADiq`w7iT8rq+&N7<hR1o%o4C(-4rDMK%+q+H$N}4B)=##
zFI_<+GYu_vK)#94Q79?OOf6O@$yZ28ElEu-QOGP&NGvVM&rK}JOis+nsRXU8XJBB^
z%|tRE5vAx>AY{OiO}rht#YpBCmn4>C7MElu7lXn!zbv&VBQ-HaAu~@QFEKB_I5jyx
zF9qyt1_s?yBz;Ax1^GoKAU(yE#U-h^3OV_S;Mith&`rjwuAnGCIkmVrzeoYpGf6E<
zEGaEYWza1`QXJ$M;KNX!#E_Yjk(^eNlA2#oR9woS49X$JC5gEO3Jj{n3Jh>ZGN|UH
z=&2f5=A<YvsOFS{h!h0|2JuV(|3A9;|NnuD|Nqaq`2YWhs}P)y#EwK_8(sYW|L+Be
znoAe{|986d|No2&|Nj?U`2SxAbfQyQd}>*0UP(OopeI+*0Z$4bCMd3RQWH~BixgCI
zaw@nOoD=gv>AnaQfJLdrr8y-GkaSm+nwDCWnwOkf3>APT#H6CcyyT2{<dn()6@#fL
zEsjsFOwLIyW++Nci%%{ng>fM!=NP8M7sV$+jfL=Xk$B}Oa^>;Jas?=I1qituWFtWw
zxUQUdBm+SlBpD>*a^exDrIh3(A(;o|!t{Z;2s5Ev6j_A1U|EF8nW!d1xiGz8F2ZCe
z7ey9fGFTR2a#BGll9M4km`)H6VJw7)EQc@@B!@6FFFz#}$xtX4rW4FX7z^d1$RZ2|
z%OXt9FNg;vIV8goA}|wRA_yxGBIs%m7Qxh@*i`^Z%_YehsP-X=BAEvlMX?u26q{NU
z`{8O4Zh&O1_{3yTaf0Luba9y3sNx8hpo?Qyk8lmDda!#y*%5S-8be89adtfTP&I~v
z#Prnow8YY!l46GB{JfIXijw%^^30Ot3{dtjD2>m}OfO0VS4+rh<8w3fQ2B{j42e0J
z>3N`f8fIW>ZfOo!FH9h%G&i@BA*moOKEJf2ptOV`IlU;qv;biv14C$Dc3ysY9=4hd
z)Chsr{tOIx`3kV}@)XkYOY>3`G;$LwlTyL;V|Hp$UTTg)ZhlH>4yf|aQ!fD*`Kc-P
z&}s|q&^*u?dpZiq8L7$H3XrH$&?w5!FHy)#O-)HnQLxu!P%Tz1Mbia4Y7g2Z0H4JQ
z+RzBX`o)#S`pG$o#l`x0sU`ZV#rlZKOTVZBeAr)VNihQ<bxD;a;6?ymbtOcaS5grV
zF;5><zkwZAlwVqs$^hYmT*y#boLU4r9j_!cmmxDHCzT;HzdSLsgrPV;tt7LkkfFFF
zH8F=Fy)?DB1VYB=WhSRGs21yk>e%?A<TAM5ki}9GOA_IVDsnSRFjRpB!OAj=Dhe1f
ziz<>BGD|?Ll8Pkca6+^t^tHg27VB&2C+9<&XZj2wsksI5swwdduyI9j^dN;Fcw`VZ
zKBy0>-&IrMa}twMa~K$q?ZK)pGY^z*G1W0jGh2hsCI+4T^5Mw;{}&h;7#<w||NjRg
z1H*^o|Nn1bVqh>h_y7L_Mg|6j^Z)+~fcWSC|5ssRU~oA9|Gxzj14F|3|NjF(OTsVw
z{}0-s6maqXf6zg}4Hy6a*I;H~5V-XJe*q|QUH<=n4>JS9ge(95^RO^57+n4T--U&N
zVZ+t`|64%(YybZrVPRlMxc>jY1}g)@fgAt-m#{K0G~E3Ee*uVp^Z)-HtPBhaxBmZs
z!OFm};m-g67HkX*pmFgMHU@?T_x}H1!p6X$aR2}R9c&B?6Yl^2{{ysW{o()r0qhJ6
zA0GbyKZTuv!Qj#V{|DF^7#be^|9^v>fx+SN|Njyk3=9fS{{N5QU|?AA?En8I91IK_
zp8fw1S{xei{Qv(891IKzFaG~m;ACLf@Z$e}3r+?GftUaPr*JYb6ukWZe-0-DgTd?n
z|6g!2Fa*5$|KEU%f#JZL|NnEi7#I}Z{{KIPi-BRm+yDPpfJ%aQ|NnpBVqg$>_y0c!
zXmc9_0|RISEhxentAZF9D+Cy&dDuB7FtQ7P#6g=|JI?(758CtzQUk&uaS)BFo&mJZ
zm;t0-;_(0fA3$-!C*Z~>;l<Bg&e6bNFJ-M|tODB03bqe)2KIxa|NnzlgMrKfVbCyi
z4CtJ%v;Y5tW+-4{1)%fI&;I`pcCHH_*j?Ze&$IvkD}WTa@Ck(Tae&WpoCDPlTB5?>
z!YAMXIwyvKfnmzo|Ns3#hI;S`^f9^eN%S)N@G11LxbtbWvAXaXG_x_?=i<}w;8Sqo
zlknsdaN^_e;7;JvaO6|)<dbj$3-~ZFFo4d^wK)3!zXK?4o%jU$nVk3}`k0;g6na^l
z_%wQ09r+B}*j)H5n%Q0W8W@@1v2gKOIP)1e@@Y7M&4w7|3i1nR<E{^A=HuM||KRgS
z9Qg#=m>l^enwf+66e9T~9Qgzs`8dGmg_kfgFa(_Y{~vrL6WCr?kiD*aFne9#_WJNS
zFop72IAT}|3X46A3=A{Q{r~?66mDR1!0z`1nd1s_KiC{ci2EIwCURjj$cvi+6c!vz
z3=B5s|NjT&VFrX*Xkp<2GRvLs10%B@BNv~A3x=~CL16(p=P81TfuZKY|Nrx#ZtDfb
zQxCHvpF$gp3!g?aD4v)a_%vMj6dYl3Vgov7h>3yW$%X&_3qkrk`2?`)3j)U_T%Y6N
zV`o6C>_GZ2FflNwTqI9_0s{ks05bza%EkZxRY2(rXE;E^GyzALI&xRTQ;Hj(f-B5}
zuG|cucq?IMU@*A!|9>Rh4siUVg*D6$W-CT)A<e+R0NN^YfSG~8<?{dk`$6FaPIE4x
zH0Q;qz|_kHOLb1%;C%XqnStTP<^TVY&$|I__+|kuBfIkde;~*VPd<SjCKo=5Hf9$-
zg=Us&uo+H#9H2l3EqP^NU@!rdu~+{8Zv~YL;4pFrrC)6Bcjr66#B9!lJFS2g1%t}$
zf@}Z(gU&n$rM+HIK15F|*SJt4-JP2O<aW^E@*&s%|33wCyA#Omj&Qd#P2=K|Z~<p`
z(Ee(0neu^!fdMo}13jjZ0hDG~SQ!`+Zv6kB4Kl+Wp5|OYY1I*wRz3MPFjn(vxFMxg
z4``YL?e%eCWnh?a<NyCeP<;Br%Mn*Tl>7{iPj|ixoJ<$F_$=HovW^=!Qv@Fe$k=n|
zL3c?oFw9|PU|4Yzk-z(x+(2cWE2yk<gqL-0d>a^<+PJ{xIU*HHUfiJc@qm?qA>`Ko
z|KPKa+(F^v3J;&q!+a7h$M^)C&hT-7>H!`$28N7V|Nn!^15i+aFerRfKy~7+|Nr-Z
z1e`!+t|!PH-f(w#fXm#8kQj1;rFL*x0MZY-pg`gF|Nj@^`h7wAozV0z;{pdUs(w&@
z0oBC^ZvX#Z3QupI@bu;hD(Bom<s~?LUHBZB>p?{mW{K&@4XTqsd+EO1h1NgN`jQ1y
zr{9H^RUkJ))42>g14G5V|Nogm@#>8wUJ><!JKqBirpwsMS7%6!g2Fe4oq@sPK5F=a
z;;4n4fuZ33|No#Jrl9oS!{iK#BWF<ltAu1?PzK}%m8%=r85ow_|NkF+jHDAhts=@*
zKR$ze)M6D}=Dc8MU^sLC|9?=O0kWeXl*gfUod+lkJwRdT4JzNg`4X6$8L|0=fdO29
znQ$;LI6Oq;*M25&{`Y~Wcd%K`5VH!H9%3^Jl<#Xe7#JiT{r{f`3UfqR?*Ynp;5x#M
z&!7@D*Mmx-v!J>b)SmKr^#4C-|26}n+;ibm06E45T-k!+`vC_7L(8N8|BFC&K;8d^
zgMs10qyPUwXUs#w0-T;)`4oCt5cMXsu5-x3=6rB@YQxFE!0{N-z5!VQvNHs<di3%C
z|DbJtAhE%KVdq!F&Z~x<PmS(2*!k2jaZu6+v0>*^gV-Pp%8DQwc0M(T4Z@)2Ifxbl
z6^tMT6oaZ55EFJjHHZzupaX6|H0*q85F3O+O)?M-JD(cF24PUpf@s+J)G+%%Vjv7V
zpBh~pc0M(_IP83CbaB}E)ac@{^QqCrVdqoB#9`qBJD(a|9Cki6x;X57YIJef`PAs*
zu=A<W#bM`D!^B}U?0jk%A4bE@r-t!iH0*q87#~K%&Zma)VKnS~Y8W3zdw~l#$h|M1
zc!H$|*!k2jbue+*`PAs*u=A<W#oKV04?CY4T|Ml4YM3}I9m3A1Mi+;jPmL}PJD(a|
z9Cki6x;X57YIJef`P49RSo(*ZPmL}PI{5$;j_BgB^QqCrVdqn$i^I;RMi+;jPYn|X
z*#*L|^QqCr%b@2$ql?4Nr$!f_g+u)s9OAI^sbS{8@)zuUYIJef`PAs*u=A<W#bM`D
zql?4Nr$!ftolgxD2Zap?!_KEh7l)lsjV=y5pBh~pc0M(_IP83CbaB}E)Ufgz<Q5Qy
zolgxDhtaU}sbPFrc*4%7hKa-Mft^nc6Nlwf*!k2jaacZrolgxDhoxuO`P49R&;e#3
zcf!u6hKa+*5@6?3!^C0bKkR&Jm^f%S1Y{2Ed}^3Ds6Pr4hw*<w8Bhv*X9P$dyz>ym
z01rYiFn|s|191a9K_ml%B!pss-3tLaI1D5Nb0_FvF%TbiKLlv(1jL8QfBpAAAH-h(
z4NzD(F+e>83!fWMd6<8kpb-P}2WZhC$Q)4+frO#j7#P5-=NK5E+86?$5d~_0f|SF;
z8+33Qh`$1A5KNo_8W1pduYkG_N-@Cf|NS50AJ7mD$ee#rKJ5Os|4=?GoIgPMPEe2h
zg!1D-ng=0<-7kmkG&5-WaD&oeP&y4tmqF<^C_N2IFN4zCp!6{)eGN)KgVNuiG#lvT
zI0gm=F(|DDrOlwU8<Y-%(rHk-3`(~_>1j}U8I;}zrH?`BYf$<bl>P>#*}$WF3=CpW
zS`A8@L1{NA9R{V-pmZ6OZiCX(p!6~*y$wnqgVNWa^fM^^4N9|tPR2tId@Ov}x%22!
zuyf~O=gh;-m4}@p4_dX2t_PV9J69fdjy&w#c-T4duyf&I=fK0xeTSX%4m;N!c8)u;
z*&sIP+$RtXJGUKnPCM*ec6VoID+LXg)TGSBJOx8TJ!3rsT|-SMiveBM2qbF+mNwD@
z4?lv;#)d)pk%i&oe{?xe{$^xgVW@!?B+z8Y06L%%n|jc}h}gtI{aGdkeufFKi6*E;
zpo0fN;s?;gZ5cpi6+Z*4UjkLm0J;u`kwKba1$dAYa?c+~4pd$+GKez3%2|*Y2)9Aa
zf%kJjf(#4{lfdV~i@?ims4&Au&^R=fa5xTDFUA17&j&PK0MY}x9}Sy-@8dA%B@Xcq
zVDqII9zf5Zh8E8Zf5GC?3<>QZ+ZY%EAQZz-s5k?fI42|Meo@SL6vH778qWlU=Yd|R
z!O#lAj1d&J(hLVc7n6acpyIAD@rfWokX;bk8zv4qQUfFeRUZTs?*s{gBLmEchKWPn
z5387PrJoeAdSM2iG_ZCQ0$cbOF+$Rh1GJuo^|>oS37tU%Bb{`C%@=1tFW)Ca)x+v{
zn8nM$;zIEIIAP+Td-NDVtpaF$3lsNe2Dyg^agQog;ym~sH-3f#RuBR3SRn%g1L$x9
zAqIX11E~AK)-f<Jyn(7O0A(D|dMk)FhHqeTC<lpRX9C?v$<L4gRS&IZ8F-m6oC4OR
z$ppFg4R#L$tiHEr0jZZ_SO86*V8sj!3^q{nFE~O(VCK7n#UWzIWE5DOpWy>&(29Y9
z0X(+Mz`y{S*8}<Y0n{Au`~U+3Lq1HsJH!<5xDEpYLnBl?0D9>Ic+8oBfuS2L4pECt
zma#(owF6pi!2C4_>fZ-Yaag`v4mO9M;Q_SN1kXD#FfeQbizAy1VV{SZ^8#uP%=~NM
zd&H#R_whkgGcYhg@7>#grv5Gt^FecMpnLsb_h7)>`3w~AOactB_9)DJW@b>l!*~c<
z3@pyiFu@rj1{>2=X9k6j6a(y@7FaoN4psjEsvg>%W+-IAZa!$N7!;2NpaEV61_tmP
z6axc;Bs)kwKSO{$#9r{2Edv9C6WDx+7%~|O7UySh0G%|8WKJqr99boVU5!J$59}{#
zh8t+%JQauf<v7H5g2nk644{*w;CV&{28Me$;wu^~&d>0`9O6Fk90mge!x5-^PN2Ex
z4A^{#T4eGbSe&0B05ssuz`y_-uYAu23QuH}5cUVKdI%et<iinP$}FIGmu6sShN^}p
zEG-=BZCOBf>0y=wUO3dp;t(&uAr6}J0Udt?bq$;XZRCfgNw^>b1H*E#Is6P8pydf{
z4r?1&99boVeG=qfCMgE=_Te=g>R*7x`588VCY2Z%VAl*Wd;^)oAPBFJp~1$$$_k1X
zeue~40|q)@0J2#aD((Q96lY+74L2~zL&X!o6EO@7p!yi3UKcD5VxeMtusA=%1!#Hz
zk5w};F!+PTQPqNYNjSty!R4V8+(WQ-1?b*V0S0M?6VUn{WCjR3L&E`f&p9+3Fw}z0
z=V!QJ2~x$t0GmI14$bcqpb-L|(*)h)1GZO?!5|W%9@?#Bm<%=tB8E&ZX9cA<#C@hP
zxy?A#p8|{XGblj&3E(+=1_p-nQ1J=SdJw#JfPsPGDp(w5DuR9q7UySZ0Bu+U-AfIv
zfPaGBFU@cOntx&O&cX)CM;D;tu=1aq4U!%Lp!GX=E|GzOK?f|3un)$P0GlJl0K4A_
zmgco_sJF!-9)LqU8Hac|Se&0B02)3}?=m!j#bK^P&{J`UZ^0oBI@}RkzJ35!&(EL$
z%`ebw!0-+%j<65Tf~Knjpan$?3=FV#0zW$_`~?|opy>)0FA`Ao8=&Tc=PDT(7?i-`
za8uz7&?(>8+<6{{d)&b0@G~$#(?58=8Pu);i^GkDGg3hAWWsC@6oA$9Gc-WkIpDc3
z1_p)(sCWWeJEWf-)E<Ky3uml^sxPpE2!ZET85kHgL&X<B%OCK39|Hr!DX=(1Ei(BG
zEY8nh0KH5Hy#9lMf#EAV_IrdCp!wwk^wKWyx&zR<2@X*DM>ZM4R>UC=nnMJ&9}++p
zRfF0M(1hp;R?pAS04;~1!NCyD0g88Nh6QN(jv+X?sKih&pCLXzF)1^?Br%;KH$N-0
zB)?cMnIXBTq`0IsEln?(0dbRYd`T{7@n>FYF++TON`5@(3g5(>_>_|TqT=|((h7#;
z{M>?^)RNQ`Jp=42K$q@j#wQjPC053#=9LsxGNctH=BCC&mUqU-Bk|%h^D;|Nl)@J3
z#b@TFWR_*7lqTlrB|{djgVrBrCdX&yrR6h#E=<--W`OQk&`V|jE!l@s@oAYU3?;b*
z@gTAIvc#Oy)M5t2szAMD2GF8D=%RhSWQL^Dw6xTsc+kcY(DloD#xN1^qCY(ohV0Zz
zJyQm-oDoz`&k)7{1%g|UqpxectDj4JJOlKa;CNK8r7*<1MEW`UdO9<p$bj#NW{8h>
z_X~}8^@xWU<lz#;5by5e@8swc@9*Xo>>3gu;^^e#8qWX@E~uwrw-zTCmx4o_0eqt~
z_>N-Gt;G)T+lci{AySZws1Y$8;)`@=HRN7q6ivxFsfl^uKm^~DTu_N38xOi=8War-
z;9!ENgJ?ktUWkjq%0L%LqnMDF6knWQS_Ilj0NQ+05)X@e2JqrzkOiRK5^z0+<_yqv
z!SSi!g`kjoqv7(PTb1*{S68D56_*s{q~@UrL0pVT5)6>_oyGC6pauD@xCFEV25n6*
zC;}j<5weW}w2=o*32fOf<O*yQdqF7}loml(Tcb#TuenAMNlZzBh7JQbP*aN-z;|Y&
zD1!I{Ik+)yvPMx~TvAk$Uz(GHA_z(T(EGblWa8sN!3?<;8=M4k3sB@CH-n=HL2uti
z5rba6jUtA2MLNVI@c0M26V;XR@hQdm@fnGEpf$(2skzBW$<fdR5+x;-1*!4bsg(@z
zp8oO0B`KMC@!)-15Yu6C3kunieDKaJ22dJ9Bs=g8<!H_XUknb)V&IsETv3jq1agr&
ziV!q4K{Ez8@q>u?s(etXS_HX19aTqsQgJafpkcR*qg@IQzLvZcwA~JNhdGJ~Am@RK
zM(Cb722kco%`46?DhA!ZUXoe_@hdD4piV^A0lxbk#Z1Tr@F+syn8`*Jsw_^<&r3rU
z%S?wvRT0Sc{DKk`Su8$8zTX~l+dGO5$Yt)3q7_8~oHyXv7JR8Y7I}EW%1eSq0yyG9
z^#k~ddW05phGNM5@dzP3Q%DX3#|QMzc@)|B_z+)bXz33sIFR!rxO_*Xuz1f9-}s``
z^vvRt)FPDf7aV_J2Z7UPYHk6vf{HH&M<ZGx1F|PIFSRJWGQKp60aDk%eF+Jzw9LH3
zoXo0J6t|}37oo;pX>m?!Dr&X{I|aoP8TsY$i8(n4e-xLbq!tySn9QJ8T$x*vn8ct5
zN+V!81IEe(ZH+8o(96p&N!3fwE7dC~$}dPQDyc*gN-E9FNzu(rfeJY~dFp~%D`4dr
ziNzTVdMTB8#g(}bx}=B!EK`<RRGgWghr)?3V$dr}%}E4lfU*j5N*MG&{$kK8$SKiF
z&o5!n18rtu&;xBUWzZ|i2bFXTdZ`)E)=5T65rPNN3TdW5bimjkT_C&kit@qkO3ckn
zW&jxvvW7tqB+a0gR9wuU2imNfnpXm8^-)fO=2t;YLg?@^g9LP50!G8;S7A1R)WX;x
z8q_TW&1u5)TR`>0Xjp#>q!xrZKm-y7-93w}KLV;BMuXO%At`5o^+RA{py6C({jhlz
z7>#Z}x_;35zHk5kgN8-HM#AQeVKj6YgaI~hjP8C=zXCKy3-dp0UKvJ%_C<gU2DuRw
zb};?0`Q1!VUl=ir&j6dJhS9KjX^<Hp3^D^m!!T$Z6*LD7vmZ9^3#0R(3SsVtse{pV
z3=E)aw&4DU%`3xb*f<8d`=Q1%fTlS>VG1)3Hm?n%Ve{HB`_cVB9Xx--zyKW<V1Uh&
z!)VyNI!HfgZ2-Fdh2VJ`26+5{?j!=c4I1&V`FF4w)GinsM1%G|fWj1HK8UXX)d!<N
z<HR6w7zV971hHZCay0t|Kp6tmPlM7h_k#3*FpLkQH=yZ<jkCaLJ<v^LAdOHAvlq%`
z*oLMbHf{~0IbjN+G$^j1OfUuNzk~b_k3U$1Lumt0;s&dP5a{+Ff!Yt#Zx9Vp2cu#A
zT!<)QehbFGgr<K7Xfq1~0|Shnf#v~NxWV*;&Ikm}ML~-V`26Dq=)4xXdKe!@zW^P}
z3eAHcGhy?cH;B{^I>#6kelYuC^O+Bz`eE~$AhSUjn!G?vFlJ<gq+OVP*nHWAT(C65
z2aw?m3=E+B2NHp~8x{|%q2UM954&glKt4z{WbXom1tDSjVKf(bo({2I5Vo#`0knY#
zG`<M6AEKLq0j3W|3!~|W&1WqD6-*2a3=d!$p)|VxLF4!!vtaIr&671i2j)FMSJgrF
zf+%$Ta!~tW;};+`APmzF9i{>aficWG$TTeNf)zlC15o>4fD#u21A`m`0|O{4g4_yH
x0xQ2k$rI*wkT?v(#>2B<8lVy|d!by=h&O2K9gGX7g}NY2&>?UT7KB9C4*-FpKac<b

diff --git a/counters.h b/src/counters.h
similarity index 100%
rename from counters.h
rename to src/counters.h
diff --git a/counters_group.c b/src/counters_group.c
similarity index 100%
rename from counters_group.c
rename to src/counters_group.c
diff --git a/counters_individual.c b/src/counters_individual.c
similarity index 100%
rename from counters_individual.c
rename to src/counters_individual.c
diff --git a/counters_option.py b/src/counters_option.py
similarity index 100%
rename from counters_option.py
rename to src/counters_option.py
diff --git a/frapl.c b/src/frapl.c
similarity index 100%
rename from frapl.c
rename to src/frapl.c
diff --git a/frapl.h b/src/frapl.h
similarity index 100%
rename from frapl.h
rename to src/frapl.h
diff --git a/infiniband.c b/src/infiniband.c
similarity index 100%
rename from infiniband.c
rename to src/infiniband.c
diff --git a/infiniband.h b/src/infiniband.h
similarity index 100%
rename from infiniband.h
rename to src/infiniband.h
diff --git a/load.c b/src/load.c
similarity index 100%
rename from load.c
rename to src/load.c
diff --git a/load.h b/src/load.h
similarity index 100%
rename from load.h
rename to src/load.h
diff --git a/mojitos.c b/src/mojitos.c
similarity index 100%
rename from mojitos.c
rename to src/mojitos.c
diff --git a/network.c b/src/network.c
similarity index 100%
rename from network.c
rename to src/network.c
diff --git a/network.h b/src/network.h
similarity index 100%
rename from network.h
rename to src/network.h
diff --git a/rapl.c b/src/rapl.c
similarity index 100%
rename from rapl.c
rename to src/rapl.c
diff --git a/rapl.h b/src/rapl.h
similarity index 100%
rename from rapl.h
rename to src/rapl.h
diff --git a/temperature.c b/src/temperature.c
similarity index 100%
rename from temperature.c
rename to src/temperature.c
diff --git a/temperature.h b/src/temperature.h
similarity index 100%
rename from temperature.h
rename to src/temperature.h
-- 
GitLab


From c9d740bd0d471c737b10f5ca1e4cc5655ef691f4 Mon Sep 17 00:00:00 2001
From: rissadmin <floreal.risso@univ-tlse3.fr>
Date: Sun, 18 Dec 2022 08:46:38 +0000
Subject: [PATCH 002/229] Standardized code formatting on GNU style

---
 src/counters.h            |   6 +-
 src/counters_group.c      |  85 +++++++-----
 src/counters_individual.c | 169 +++++++++++++----------
 src/frapl.c               | 119 ++++++++--------
 src/frapl.h               |   6 +-
 src/infiniband.c          |  50 ++++---
 src/infiniband.h          |   4 +-
 src/load.c                |  33 +++--
 src/load.h                |   6 +-
 src/mojitos.c             | 277 ++++++++++++++++++++------------------
 src/network.c             |  72 +++++-----
 src/network.h             |   6 +-
 src/rapl.c                | 124 +++++++++--------
 src/rapl.h                |   6 +-
 src/temperature.c         | 124 +++++++++--------
 src/temperature.h         |   6 +-
 16 files changed, 605 insertions(+), 488 deletions(-)

diff --git a/src/counters.h b/src/counters.h
index 751557a..af20717 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -18,9 +18,9 @@
 
  *******************************************************/
 
-unsigned int init_counters(char*, void **);
-unsigned int get_counters(uint64_t* results, void*);
+unsigned int init_counters(char *, void **);
+unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
-void label_counters(char **labels, void*);
+void label_counters(char **labels, void *);
 
 void show_all_counters();
diff --git a/src/counters_group.c b/src/counters_group.c
index bc9b448..f134823 100644
--- a/src/counters_group.c
+++ b/src/counters_group.c
@@ -29,28 +29,32 @@
 
 #include "counters.h"
 
-struct _counter_t {
+struct _counter_t
+{
   int nbcores;
   int nbperf;
   int *counters;
 };
- 
+
 static long
 perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-		int cpu, int group_fd, unsigned long flags) {
+                int cpu, int group_fd, unsigned long flags)
+{
   long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-  if (res == -1) {
-    perror("perf_event_open");
-    fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-    exit(EXIT_FAILURE);
-  }
+  if (res == -1)
+    {
+      perror("perf_event_open");
+      fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+      exit(EXIT_FAILURE);
+    }
   return res;
 }
 
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names) {
+counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+{
   struct perf_event_attr pe;
   struct _counter_t *counters = malloc(sizeof(struct _counter_t));
-  
+
   unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
   counters->nbcores=nbcores;
   counters->nbperf=nb_perf;
@@ -61,59 +65,70 @@ counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *name
   pe.read_format = PERF_FORMAT_GROUP;
   counters->counters = malloc((nbcores+1)*sizeof(int));
 
-  for (int core=0; core<nbcores; core++) {
-    counters->counters[core]=-1;
-    for(int idperf=0; idperf<nb_perf; idperf ++){
-      pe.type = types[idperf];
-      pe.config = names[idperf];
-      int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-      if(counters->counters[core]==-1)
-	counters->counters[core]=res;
+  for (int core=0; core<nbcores; core++)
+    {
+      counters->counters[core]=-1;
+      for(int idperf=0; idperf<nb_perf; idperf ++)
+        {
+          pe.type = types[idperf];
+          pe.config = names[idperf];
+          int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
+          if(counters->counters[core]==-1)
+            counters->counters[core]=res;
+        }
     }
-  }
   return counters;
 }
 
-void clean_counters(counter_t counters) {
+void clean_counters(counter_t counters)
+{
   for(int core=0; core<counters->nbcores; core++)
     close(counters->counters[core]);
   free(counters->counters);
   free(counters);
 }
 
-void start_counters(counter_t counters) {
+void start_counters(counter_t counters)
+{
   for(int core=0; core<counters->nbcores; core++)
     ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
 }
-void reset_counters(counter_t counters) {
+void reset_counters(counter_t counters)
+{
   for(int core=0; core<counters->nbcores; core++)
     ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
 }
 
-struct read_format {
+struct read_format
+{
   uint64_t nr;
-  struct {
+  struct
+  {
     uint64_t value;
   } values[];
 };
 
-void get_counters(counter_t counters, long long *values) {
+void get_counters(counter_t counters, long long *values)
+{
   int nb_perf = counters->nbperf;
   size_t buffer_size = sizeof(uint64_t)*(1+nb_perf);
-  struct read_format* buffer = NULL;
+  struct read_format *buffer = NULL;
   if(buffer==NULL)
     buffer = malloc(buffer_size);
-  
+
   memset(values, 0, nb_perf*sizeof(long long));
 
-  for (int core=0; core<counters->nbcores; core++) {
-    if (-1 == read(counters->counters[core], buffer, buffer_size)) {
-      perror("PB Lecture resultat");
-      exit(EXIT_FAILURE);
-    } 
-    for(int idperf=0; idperf<=nb_perf; idperf++) {
-      values[idperf] += buffer->values[idperf].value;
+  for (int core=0; core<counters->nbcores; core++)
+    {
+      if (-1 == read(counters->counters[core], buffer, buffer_size))
+        {
+          perror("PB Lecture resultat");
+          exit(EXIT_FAILURE);
+        }
+      for(int idperf=0; idperf<=nb_perf; idperf++)
+        {
+          values[idperf] += buffer->values[idperf].value;
+        }
     }
-  }
   reset_counters(counters);
 }
diff --git a/src/counters_individual.c b/src/counters_individual.c
index 1437aa3..222037a 100644
--- a/src/counters_individual.c
+++ b/src/counters_individual.c
@@ -28,67 +28,79 @@
 #include <asm/unistd.h>
 #include <stdint.h>
 
-struct _counter_t {
+struct _counter_t
+{
   int nbcores;
   int nbperf;
   int **counters;
   uint64_t *counters_values;
   uint64_t *tmp_counters_values;
 
-  int* perf_indexes;
-  
+  int *perf_indexes;
+
 };
-typedef struct _counter_t* counter_t;
+typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void show_all_counters() {
-  for(int i=0; i<nb_counter_option;i++)
+void show_all_counters()
+{
+  for(int i=0; i<nb_counter_option; i++)
     printf("%s\n", perf_static_info[i].name);
 }
 
-void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb){
+void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
+{
   *perf_type = malloc(nb*sizeof(__u32));
   *perf_key  = malloc(nb*sizeof(__u64));
-  for(int i=0; i<nb; i++) {
-    (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
-    (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
-  }
+  for(int i=0; i<nb; i++)
+    {
+      (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
+      (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
+    }
 }
-void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes) {
+void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
+{
   char *token;
   *nb_perf=0;
   *perf_indexes=NULL;
-  while((token=strtok(perf_string, ",")) != NULL) {
-    perf_string = NULL;
-    int i;
-    for(i=0; i<nb_counter_option; i++) {
-      if(strcmp(perf_static_info[i].name, token) == 0) {
-	(*nb_perf)++;
-	(*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-	(*perf_indexes)[*nb_perf-1]=i;
-	break;
-      }
+  while((token=strtok(perf_string, ",")) != NULL)
+    {
+      perf_string = NULL;
+      int i;
+      for(i=0; i<nb_counter_option; i++)
+        {
+          if(strcmp(perf_static_info[i].name, token) == 0)
+            {
+              (*nb_perf)++;
+              (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
+              (*perf_indexes)[*nb_perf-1]=i;
+              break;
+            }
+        }
+      if(i == nb_counter_option)
+        {
+          fprintf(stderr, "Unknown performance counter: %s\n", token);
+          exit(EXIT_FAILURE);
+        }
     }
-    if(i == nb_counter_option) {
-      fprintf(stderr, "Unknown performance counter: %s\n", token);
-      exit(EXIT_FAILURE);
-    }
-  }
 }
 
 static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-			    int cpu, int group_fd, unsigned long flags) {
+                            int cpu, int group_fd, unsigned long flags)
+{
   long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-  if (res == -1) {
-    perror("perf_event_open");
-    fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-    exit(EXIT_FAILURE);
-  }
+  if (res == -1)
+    {
+      perror("perf_event_open");
+      fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+      exit(EXIT_FAILURE);
+    }
   return res;
 }
 
-counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names) {
+counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+{
   struct perf_event_attr pe;
   unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
   memset(&pe, 0, sizeof(struct perf_event_attr));
@@ -98,26 +110,30 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
   counter_t counters = malloc(sizeof(struct _counter_t));
   counters->nbperf = nb_perf;
   counters->nbcores=nbcores;
-  counters->counters=malloc(nb_perf*sizeof(int*));
-  for (int i=0; i<nb_perf; i++) {
-    pe.type = types[i];
-    pe.config = names[i];
-    counters->counters[i] = malloc(nbcores*sizeof(int));
-
-    for (int core=0; core<nbcores; core++) {
-      counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
+  counters->counters=malloc(nb_perf*sizeof(int *));
+  for (int i=0; i<nb_perf; i++)
+    {
+      pe.type = types[i];
+      pe.config = names[i];
+      counters->counters[i] = malloc(nbcores*sizeof(int));
+
+      for (int core=0; core<nbcores; core++)
+        {
+          counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
+        }
     }
-  }
   return counters;
 }
 
-void clean_counters(void *ptr) {
+void clean_counters(void *ptr)
+{
   counter_t counters = (counter_t) ptr;
-  for(int counter=0; counter<counters->nbperf; counter++) {
-    for(int core=0; core<counters->nbcores; core++)
-      close(counters->counters[counter][core]);
-    free(counters->counters[counter]);
-  }
+  for(int counter=0; counter<counters->nbperf; counter++)
+    {
+      for(int core=0; core<counters->nbcores; core++)
+        close(counters->counters[counter][core]);
+      free(counters->counters[counter]);
+    }
   free(counters->counters);
   free(counters->counters_values);
   free(counters->tmp_counters_values);
@@ -126,31 +142,37 @@ void clean_counters(void *ptr) {
   free(counters);
 }
 
-void start_counters(counter_t counters) {
+void start_counters(counter_t counters)
+{
   for(int counter=0; counter<counters->nbperf; counter++)
     for(int core=0; core<counters->nbcores; core++)
       ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
 }
 
-void reset_counters(counter_t counters) {
+void reset_counters(counter_t counters)
+{
   for(int counter=0; counter<counters->nbperf; counter++)
     for(int core=0; core<counters->nbcores; core++)
       ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
 }
 
-void _get_counters(counter_t counters, uint64_t *values) {
-  for(int i=0; i<counters->nbperf; i++) {
-    uint64_t accu=0;
-    uint64_t count=0;
-    for (int core=0; core<counters->nbcores; core++) {
-      if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
-	fprintf(stderr, "Cannot read result");
-	exit(EXIT_FAILURE);
-      }
-      accu += count;
+void _get_counters(counter_t counters, uint64_t *values)
+{
+  for(int i=0; i<counters->nbperf; i++)
+    {
+      uint64_t accu=0;
+      uint64_t count=0;
+      for (int core=0; core<counters->nbcores; core++)
+        {
+          if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t)))
+            {
+              fprintf(stderr, "Cannot read result");
+              exit(EXIT_FAILURE);
+            }
+          accu += count;
+        }
+      values[i] = accu;
     }
-    values[i] = accu;
-  }
 }
 
 
@@ -158,14 +180,15 @@ void _get_counters(counter_t counters, uint64_t *values) {
 
 
 
-unsigned int init_counters(char* args, void **state) {
+unsigned int init_counters(char *args, void **state)
+{
   int nb_perf;
-  int* perf_indexes=NULL;
+  int *perf_indexes=NULL;
 
   perf_event_list(args, &nb_perf, &perf_indexes);
 
-  __u32* perf_type;
-  __u64* perf_key;
+  __u32 *perf_type;
+  __u64 *perf_key;
   perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
   counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
   free(perf_type);
@@ -176,15 +199,16 @@ unsigned int init_counters(char* args, void **state) {
   fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
   start_counters(fd);
   _get_counters(fd, fd->counters_values);
-  *state = (void*) fd;
+  *state = (void *) fd;
 
   return nb_perf;
 }
 
-unsigned int get_counters(uint64_t* results, void*ptr) {
+unsigned int get_counters(uint64_t *results, void *ptr)
+{
   counter_t state = (counter_t) ptr;
 
-_get_counters(state, state->tmp_counters_values);
+  _get_counters(state, state->tmp_counters_values);
   for(int i=0; i<state->nbperf; i++)
     results[i] = state->tmp_counters_values[i] - state->counters_values[i];
 
@@ -192,9 +216,10 @@ _get_counters(state, state->tmp_counters_values);
   return state->nbperf;
 }
 
-void label_counters(char **labels, void*ptr) {
+void label_counters(char **labels, void *ptr)
+{
   counter_t state = (counter_t) ptr;
-  for(int i=0; i<state->nbperf;i++)
+  for(int i=0; i<state->nbperf; i++)
     labels[i] = perf_static_info[state->perf_indexes[i]].name;
 
 }
diff --git a/src/frapl.c b/src/frapl.c
index 433a28c..d0d0abf 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -28,7 +28,8 @@
 
 #define MAX_HEADER 128
 
-char *get_frapl_string(const char *filename) {
+char *get_frapl_string(const char *filename)
+{
   int fd = open(filename, O_RDONLY);
   if( fd == -1)
     return NULL;
@@ -37,9 +38,10 @@ char *get_frapl_string(const char *filename) {
   close(fd);
   result[nb-1] = 0;
   return (result);
-}  
+}
 
-void test_append(char* name, int i) {
+void test_append(char *name, int i)
+{
   //char last = name[strlen(name)-1];
   //if (last>='0' && last <= '9')
   //  return;
@@ -47,22 +49,24 @@ void test_append(char* name, int i) {
 }
 
 
-struct _frapl_t {
+struct _frapl_t
+{
   unsigned int nb;
   char **names;
   int *fids;
-  uint64_t* values;
-  uint64_t* tmp_values;
+  uint64_t *values;
+  uint64_t *tmp_values;
 
 };
 typedef struct _frapl_t _frapl_t;
 
 
-void add_frapl_source(_frapl_t* rapl, char*name, char*energy_uj) {
+void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
+{
   rapl->nb += 1;
-  rapl->names = realloc(rapl->names, sizeof(char**)*rapl->nb);
-  rapl->fids = realloc(rapl->fids, sizeof(int*)*rapl->nb);
-  
+  rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
+  rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
+
   rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
   strcpy(rapl->names[rapl->nb-1], name);
   //printf("%s\n", energy_uj);
@@ -71,18 +75,21 @@ void add_frapl_source(_frapl_t* rapl, char*name, char*energy_uj) {
 }
 
 
-void _get_frapl(uint64_t *values, _frapl_t* rapl) {
+void _get_frapl(uint64_t *values, _frapl_t *rapl)
+{
   static char buffer[512];
 
-  for (int i = 0; i < rapl->nb; i++) {
+  for (int i = 0; i < rapl->nb; i++)
+    {
 
-    pread(rapl->fids[i], buffer, 100, 0);
-    values[i] = strtoull(buffer, NULL, 10);
-  }
+      pread(rapl->fids[i], buffer, 100, 0);
+      values[i] = strtoull(buffer, NULL, 10);
+    }
 }
 
 
-unsigned int init_frapl(char* none, void **ptr) {
+unsigned int init_frapl(char *none, void **ptr)
+{
   _frapl_t *rapl = malloc(sizeof(_frapl_t));
   rapl->nb = 0;
   rapl->names = NULL;
@@ -92,46 +99,49 @@ unsigned int init_frapl(char* none, void **ptr) {
   char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
   char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-  for (int i=0;; i++) {
-    sprintf(buffer, name_base, i, "name");
-    char *tmp = get_frapl_string(buffer);
-    if (tmp == NULL) break;
-    //printf("%s\n", tmp);
-    test_append(tmp, i);
-    //printf("%s -> %s\n", buffer, tmp);
-
-    sprintf(buffer, name_base, i, "energy_uj");
-    add_frapl_source(rapl, tmp, buffer);
-    free(tmp);
-
-    for (int j=0;; j++) {
-      sprintf(buffer, name_sub, i, i, j, "name");
-      char *tmp_sub = get_frapl_string(buffer);
-      if (tmp_sub == NULL) break;
-      //printf("%s\n", tmp_sub);
-      test_append(tmp_sub, i);
-      //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-      sprintf(buffer, name_sub, i, i, j, "energy_uj");
-      add_frapl_source(rapl, tmp_sub, buffer);
-      
-      free(tmp_sub);
+  for (int i=0;; i++)
+    {
+      sprintf(buffer, name_base, i, "name");
+      char *tmp = get_frapl_string(buffer);
+      if (tmp == NULL) break;
+      //printf("%s\n", tmp);
+      test_append(tmp, i);
+      //printf("%s -> %s\n", buffer, tmp);
+
+      sprintf(buffer, name_base, i, "energy_uj");
+      add_frapl_source(rapl, tmp, buffer);
+      free(tmp);
+
+      for (int j=0;; j++)
+        {
+          sprintf(buffer, name_sub, i, i, j, "name");
+          char *tmp_sub = get_frapl_string(buffer);
+          if (tmp_sub == NULL) break;
+          //printf("%s\n", tmp_sub);
+          test_append(tmp_sub, i);
+          //printf("%s -> %s\n", buffer, tmp_sub);
+
+
+          sprintf(buffer, name_sub, i, i, j, "energy_uj");
+          add_frapl_source(rapl, tmp_sub, buffer);
+
+          free(tmp_sub);
+        }
     }
-  }
 
   rapl->values = calloc(sizeof(uint64_t), rapl->nb);
   rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
 
   _get_frapl(rapl->values, rapl);
 
-  *ptr = (void*)rapl;
+  *ptr = (void *)rapl;
   return rapl->nb;
 }
 
 
-unsigned int get_frapl(uint64_t* results, void* ptr) {
-  _frapl_t* state = (_frapl_t*) ptr;
+unsigned int get_frapl(uint64_t *results, void *ptr)
+{
+  _frapl_t *state = (_frapl_t *) ptr;
   _get_frapl(state->tmp_values, state);
   for(int i=0; i<state->nb; i++)
     results[i] = state->tmp_values[i] - state->values[i];
@@ -140,12 +150,14 @@ unsigned int get_frapl(uint64_t* results, void* ptr) {
   return state->nb;
 }
 
-void clean_frapl(void *ptr) {
-  _frapl_t* rapl = (_frapl_t*) ptr;
-  for(int i=0; i<rapl->nb; i++) {
-    free(rapl->names[i]);
-    close(rapl->fids[i]);
-  }
+void clean_frapl(void *ptr)
+{
+  _frapl_t *rapl = (_frapl_t *) ptr;
+  for(int i=0; i<rapl->nb; i++)
+    {
+      free(rapl->names[i]);
+      close(rapl->fids[i]);
+    }
   free(rapl->names);
   free(rapl->fids);
   free(rapl->values);
@@ -154,8 +166,9 @@ void clean_frapl(void *ptr) {
 }
 
 
-void label_frapl(char **labels, void *ptr) {
-  _frapl_t* rapl = (_frapl_t*) ptr;
+void label_frapl(char **labels, void *ptr)
+{
+  _frapl_t *rapl = (_frapl_t *) ptr;
   for(int i=0; i<rapl->nb; i++)
     labels[i] = rapl->names[i];
 }
diff --git a/src/frapl.h b/src/frapl.h
index 6b2d154..937108e 100644
--- a/src/frapl.h
+++ b/src/frapl.h
@@ -18,8 +18,8 @@
 
  *******************************************************/
 
-unsigned int init_frapl(char*, void **);
-unsigned int get_frapl(uint64_t* results, void*);
+unsigned int init_frapl(char *, void **);
+unsigned int get_frapl(uint64_t *results, void *);
 void clean_frapl(void *);
-void label_frapl(char **labels, void*);
+void label_frapl(char **labels, void *);
 
diff --git a/src/infiniband.c b/src/infiniband.c
index 49dca07..e0daa2a 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -26,49 +26,55 @@
 
 #include <stdint.h>
 
-struct network_t {
+struct network_t
+{
   uint64_t values[4];
   uint64_t tmp_values[4];
   int sources[4];
 };
-unsigned int _get_network(uint64_t* results, int* sources);
+unsigned int _get_network(uint64_t *results, int *sources);
 
 
-unsigned int init_infiniband(char* infi_path, void**ptr) {
+unsigned int init_infiniband(char *infi_path, void **ptr)
+{
   if(infi_path==NULL)
     return 0;
 
-  if(strcmp(infi_path,"X")==0) {
+  if(strcmp(infi_path,"X")==0)
+    {
+
+      glob_t res;
+
+      glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
+      if(res.gl_pathc == 0)
+        return 0;
+      infi_path = res.gl_pathv[0];
+    }
 
-    glob_t res;
-  
-    glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
-    if(res.gl_pathc == 0)
-      return 0;
-    infi_path = res.gl_pathv[0];
-  }
-  
   char *filenames[] = {"%s/port_rcv_packets",
-		       "%s/port_rcv_data",
-		       "%s/port_xmit_packets",
-		       "%s/port_xmit_data"};
+                       "%s/port_rcv_data",
+                       "%s/port_xmit_packets",
+                       "%s/port_xmit_data"
+                      };
 
   struct network_t *state = malloc(sizeof(struct network_t));
 
   char buffer[1024];
-  for(int i=0; i<4; i++) {
-    sprintf(buffer, filenames[i], infi_path);
-    state->sources[i] = open(buffer, O_RDONLY);
-  }
-  
-  *ptr = (void*) state;
+  for(int i=0; i<4; i++)
+    {
+      sprintf(buffer, filenames[i], infi_path);
+      state->sources[i] = open(buffer, O_RDONLY);
+    }
+
+  *ptr = (void *) state;
   _get_network(state->values, state->sources);
 
   return 4;
 }
 
 char *_labels_infiniband[4] = {"irxp", "irxb", "itxp", "itxb"};
-void label_infiniband(char **labels, void*none) {
+void label_infiniband(char **labels, void *none)
+{
   for(int i=0; i<4; i++)
     labels[i] = _labels_infiniband[i];
 }
diff --git a/src/infiniband.h b/src/infiniband.h
index af8b2b6..1f6aaf9 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -18,5 +18,5 @@
 
  *******************************************************/
 
-unsigned int init_infiniband(char* infi_path, void**ptr);
-void label_infiniband(char **labels, void*);
+unsigned int init_infiniband(char *infi_path, void **ptr);
+void label_infiniband(char **labels, void *);
diff --git a/src/load.c b/src/load.c
index b3d154d..80daf4b 100644
--- a/src/load.c
+++ b/src/load.c
@@ -27,29 +27,33 @@
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid=-1;
-static uint64_t load_values[10]={0,0,0,0,0,0,0,0,0,0};
-static uint64_t tmp_load_values[10]={0,0,0,0,0,0,0,0,0,0};
+static uint64_t load_values[10]= {0,0,0,0,0,0,0,0,0,0};
+static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
 
-void _get_load(uint64_t* results) {
+void _get_load(uint64_t *results)
+{
   pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0);
   int pos=0;
   while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
-  for(int i=0; i<10; i++) {
-    results[i] = strtoull(buffer+pos, NULL, 10);
-    while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
-    pos++;
-  }
+  for(int i=0; i<10; i++)
+    {
+      results[i] = strtoull(buffer+pos, NULL, 10);
+      while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
+      pos++;
+    }
 }
 
 // Public interface
 
-unsigned int init_load(char* argument, void **state) {
+unsigned int init_load(char *argument, void **state)
+{
   load_fid = open("/proc/stat", O_RDONLY);
   _get_load(load_values);
   return 10;
 }
 
-unsigned int get_load(uint64_t* results, void* state) {
+unsigned int get_load(uint64_t *results, void *state)
+{
   _get_load(tmp_load_values);
   for(int i=0; i<10; i++)
     results[i] = tmp_load_values[i] - load_values[i];
@@ -58,13 +62,16 @@ unsigned int get_load(uint64_t* results, void* state) {
   return 10;
 }
 
-void clean_load(void *state) {
+void clean_load(void *state)
+{
   close(load_fid);
 }
 
 char *_labels[10] = {"user","nice","system","idle","iowait","irq",
-  "softirq","steal","guest","guest_nice"};
-void label_load(char **labels, void*none) {
+                     "softirq","steal","guest","guest_nice"
+                    };
+void label_load(char **labels, void *none)
+{
   for(int i=0; i<10; i++)
     labels[i] = _labels[i];
 }
diff --git a/src/load.h b/src/load.h
index 42ce968..299fa3e 100644
--- a/src/load.h
+++ b/src/load.h
@@ -18,7 +18,7 @@
 
  *******************************************************/
 
-unsigned int init_load(char*, void **);
-unsigned int get_load(uint64_t* results, void*);
+unsigned int init_load(char *, void **);
+unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
-void label_load(char **labels, void*);
+void label_load(char **labels, void *);
diff --git a/src/mojitos.c b/src/mojitos.c
index e80e692..94954cf 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -35,7 +35,8 @@
 
 
 
-void usage(char** argv) {
+void usage(char **argv)
+{
   printf("Usage : %s [-t time] [-f freq] [-r] [-p perf_list] [-l] [-u] [-c] [-d network_device] [-i infiniband_path] [-o logfile] [-e command arguments...]\n", argv[0]);
   printf("if time==0 then loops infinitively\n");
   printf("if -e is present, time and freq are not used\n");
@@ -52,23 +53,26 @@ void usage(char** argv) {
   exit(EXIT_SUCCESS);
 }
 
-void sighandler(int none) {
+void sighandler(int none)
+{
 }
 
-void flush(int none) {
+void flush(int none)
+{
   exit(0);
 }
 
 FILE *output;
-void flushexit() {
+void flushexit()
+{
   fflush(output);
   fclose(output);
 }
 
-typedef unsigned int (initializer_t)(char*, void **);
-typedef void (labeler_t)(char **, void*);
-typedef unsigned int (*getter_t)(uint64_t*, void*);
-typedef void (*cleaner_t)(void*);
+typedef unsigned int (initializer_t)(char *, void **);
+typedef void (labeler_t)(char **, void *);
+typedef unsigned int (*getter_t)(uint64_t *, void *);
+typedef void (*cleaner_t)(void *);
 
 unsigned int nb_sources=0;
 void **states=NULL;
@@ -79,30 +83,33 @@ unsigned int nb_sensors=0;
 char **labels=NULL;
 uint64_t *values=NULL;
 
-void add_source(initializer_t init, char* arg, labeler_t labeler,
-		getter_t get, cleaner_t clean) {
-    nb_sources++;
-    states = realloc(states, nb_sources*sizeof(void*));
-    int nb = init(arg, &states[nb_sources-1]);
-    if (nb == 0) {
+void add_source(initializer_t init, char *arg, labeler_t labeler,
+                getter_t get, cleaner_t clean)
+{
+  nb_sources++;
+  states = realloc(states, nb_sources*sizeof(void *));
+  int nb = init(arg, &states[nb_sources-1]);
+  if (nb == 0)
+    {
       nb_sources--;
-      states = realloc(states, nb_sources*sizeof(void*));
+      states = realloc(states, nb_sources*sizeof(void *));
       return;
     }
 
-    getter = realloc(getter, nb_sources*sizeof(void*));
-    getter[nb_sources-1] = get;
-    cleaner = realloc(cleaner, nb_sources*sizeof(void*));
-    cleaner[nb_sources-1] = clean;
+  getter = realloc(getter, nb_sources*sizeof(void *));
+  getter[nb_sources-1] = get;
+  cleaner = realloc(cleaner, nb_sources*sizeof(void *));
+  cleaner[nb_sources-1] = clean;
 
-    labels = realloc(labels, (nb_sensors+nb)*sizeof(char*));
-    labeler(labels+nb_sensors, states[nb_sources-1]);
-    
-    values = realloc(values, (nb_sensors+nb)*sizeof(uint64_t));
-    nb_sensors += nb;
+  labels = realloc(labels, (nb_sensors+nb)*sizeof(char *));
+  labeler(labels+nb_sensors, states[nb_sources-1]);
+
+  values = realloc(values, (nb_sensors+nb)*sizeof(uint64_t));
+  nb_sensors += nb;
 }
 
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
   int total_time=1;
   int delta=0;
   int frequency=1;
@@ -112,63 +119,65 @@ int main(int argc, char **argv) {
 
   if(argc==1)
     usage(argv);
-  
+
   output=stdout;
-  
+
   atexit(flushexit);
   signal(15, flush);
-  
+
   int c;
   while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application==NULL)
-    switch (c) {
-    case 'f':
-      frequency=atoi(argv[optind]);
-      break;
-    case 't':
-      total_time=atoi(argv[optind]);
-      delta=1;
-      if(total_time==0) {
-	total_time=1;
-	delta=0;
+    switch (c)
+      {
+      case 'f':
+        frequency=atoi(argv[optind]);
+        break;
+      case 't':
+        total_time=atoi(argv[optind]);
+        delta=1;
+        if(total_time==0)
+          {
+            total_time=1;
+            delta=0;
+          }
+        break;
+      case 'd':
+        add_source(init_network, argv[optind], label_network, get_network, clean_network);
+        break;
+      case 'i':
+        add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
+        break;
+      case 'o':
+        output = fopen(argv[optind],"wb");
+        break;
+      case 'e':
+        application=&argv[optind];
+        signal(17,sighandler);
+        break;
+      case 'p':
+        add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
+        break;
+      case 'r':
+        add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
+        break;
+      case 'R':
+        add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
+        break;
+      case 'u':
+        add_source(init_load, NULL, label_load, get_load, clean_load);
+        break;
+      case 'c':
+        add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
+        break;
+      case 's':
+        stat_mode=0;
+        break;
+      case 'l':
+        show_all_counters();
+        exit(EXIT_SUCCESS);
+      default:
+        usage(argv);
       }
-      break;
-    case 'd':
-      add_source(init_network, argv[optind], label_network, get_network, clean_network);
-      break;
-    case 'i':
-      add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
-      break;
-    case 'o':
-      output = fopen(argv[optind],"wb");
-      break;
-    case 'e':
-      application=&argv[optind];
-      signal(17,sighandler);
-      break;
-    case 'p':
-      add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
-      break;
-    case 'r':
-      add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
-      break;
-    case 'R':
-      add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
-      break;
-    case 'u':
-      add_source(init_load, NULL, label_load, get_load, clean_load);
-      break;
-    case 'c':
-      add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
-      break;
-    case 's':
-      stat_mode=0;
-      break;
-    case 'l':
-      show_all_counters();
-      exit(EXIT_SUCCESS);
-    default:
-      usage(argv);
-    }
 
 
   setvbuf(output, NULL, _IONBF, BUFSIZ);
@@ -187,71 +196,77 @@ int main(int argc, char **argv) {
 
   unsigned long int stat_data=0;
 
-  for (int temps = 0; temps <total_time*frequency; temps+=delta) {
-    clock_gettime(CLOCK_MONOTONIC, &ts_ref);
-
-    // Get Data
-    unsigned int current = 0;
-    for(int i=0; i<nb_sources; i++)
-      current += getter[i](&values[current], states[i]);
-    
-    if(application != NULL) {
-
-      if(fork()==0){
-	execvp(application[0], application);
-	exit(0);
-      }
-      pause();
-      clock_gettime(CLOCK_MONOTONIC, &ts);
-      if(ts.tv_nsec >= ts_ref.tv_nsec)
-	fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec), ts.tv_nsec-ts_ref.tv_nsec);
+  for (int temps = 0; temps <total_time*frequency; temps+=delta)
+    {
+      clock_gettime(CLOCK_MONOTONIC, &ts_ref);
+
+      // Get Data
+      unsigned int current = 0;
+      for(int i=0; i<nb_sources; i++)
+        current += getter[i](&values[current], states[i]);
+
+      if(application != NULL)
+        {
+
+          if(fork()==0)
+            {
+              execvp(application[0], application);
+              exit(0);
+            }
+          pause();
+          clock_gettime(CLOCK_MONOTONIC, &ts);
+          if(ts.tv_nsec >= ts_ref.tv_nsec)
+            fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec), ts.tv_nsec-ts_ref.tv_nsec);
+          else
+            fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec)-1,1000000000+ts.tv_nsec-ts_ref.tv_nsec);
+        }
       else
-	fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec)-1,1000000000+ts.tv_nsec-ts_ref.tv_nsec);
-    }
-    else {
+        {
 #ifdef DEBUG
-      clock_gettime(CLOCK_MONOTONIC, &ts);
-      fprintf(stderr, "%ld\n", (ts.tv_nsec-ts_ref.tv_nsec)/1000);
-      //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
-      //Group: mean: 309 std: 41 % med: 297 std: 39 %
+          clock_gettime(CLOCK_MONOTONIC, &ts);
+          fprintf(stderr, "%ld\n", (ts.tv_nsec-ts_ref.tv_nsec)/1000);
+          //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
+          //Group: mean: 309 std: 41 % med: 297 std: 39 %
 #endif
-      if(stat_mode==0) {
-	clock_gettime(CLOCK_MONOTONIC, &ts);
-      if(ts.tv_nsec >= ts_ref.tv_nsec)
-	stat_data = ts.tv_nsec-ts_ref.tv_nsec;
-      else
-	stat_data = 1000000000+ts.tv_nsec-ts_ref.tv_nsec;
-    }
-    
-      // Treat Data
-      fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
-    }
-    
-    for(int i=0; i<nb_sensors; i++)
-      fprintf(output, "%" PRIu64 " ", values[i]);
+          if(stat_mode==0)
+            {
+              clock_gettime(CLOCK_MONOTONIC, &ts);
+              if(ts.tv_nsec >= ts_ref.tv_nsec)
+                stat_data = ts.tv_nsec-ts_ref.tv_nsec;
+              else
+                stat_data = 1000000000+ts.tv_nsec-ts_ref.tv_nsec;
+            }
+
+          // Treat Data
+          fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
+        }
 
-    if(stat_mode==0)
-      fprintf(output, "%ld ", stat_data);
+      for(int i=0; i<nb_sensors; i++)
+        fprintf(output, "%" PRIu64 " ", values[i]);
 
-    fprintf(output, "\n");
+      if(stat_mode==0)
+        fprintf(output, "%ld ", stat_data);
 
-    if(application != NULL)
-      break;
+      fprintf(output, "\n");
 
-    clock_gettime(CLOCK_MONOTONIC, &ts);
-    usleep(1000*1000/frequency-(ts.tv_nsec/1000)%(1000*1000/frequency));
-  }
+      if(application != NULL)
+        break;
 
-  for(int i=0; i<nb_sources;i++)
+      clock_gettime(CLOCK_MONOTONIC, &ts);
+      usleep(1000*1000/frequency-(ts.tv_nsec/1000)%(1000*1000/frequency));
+    }
+
+  for(int i=0; i<nb_sources; i++)
     cleaner[i](states[i]);
 
-  if(nb_sources > 0) {
-    free(getter);
-    free(cleaner);
-    free(labels);
-    free(values);
-    free(states);
-  }
+  if(nb_sources > 0)
+    {
+      free(getter);
+      free(cleaner);
+      free(labels);
+      free(values);
+      free(states);
+    }
 }
 
 
diff --git a/src/network.c b/src/network.c
index 6e3f494..587319b 100644
--- a/src/network.c
+++ b/src/network.c
@@ -24,60 +24,68 @@
 #include <string.h>
 #include <stdint.h>
 
-struct network_t {
+struct network_t
+{
   uint64_t values[4];
   uint64_t tmp_values[4];
   int sources[4];
 };
 
-unsigned int _get_network(uint64_t* results, int* sources) {
+unsigned int _get_network(uint64_t *results, int *sources)
+{
   if(sources==NULL)
     return 0;
   char buffer[128];
-  for(int i=0; i<4; i++){
-    pread(sources[i], buffer, 127, 0);
+  for(int i=0; i<4; i++)
+    {
+      pread(sources[i], buffer, 127, 0);
 
-    results[i] = strtoull(buffer, NULL, 10);
-  }
+      results[i] = strtoull(buffer, NULL, 10);
+    }
   return 4;
 }
 
 
 
-unsigned int init_network(char* dev, void**ptr) {
+unsigned int init_network(char *dev, void **ptr)
+{
   if(dev==NULL)
     return 0;
 
-  if(strcmp(dev,"X")==0) {
-    int f = open("/proc/net/route", O_RDONLY);
-    char buffer[1000];
-    read(f, buffer, 999);
-    char *start_of_dev = index(buffer, '\n')+1;
-    char *end_of_dev = index(start_of_dev, '\t');
-    *end_of_dev='\0';
-    dev = start_of_dev;
-    close(f);
-  }
-  
+  if(strcmp(dev,"X")==0)
+    {
+      int f = open("/proc/net/route", O_RDONLY);
+      char buffer[1000];
+      read(f, buffer, 999);
+      char *start_of_dev = index(buffer, '\n')+1;
+      char *end_of_dev = index(start_of_dev, '\t');
+      *end_of_dev='\0';
+      dev = start_of_dev;
+      close(f);
+    }
+
   char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-		       "/sys/class/net/%s/statistics/rx_bytes",
-		       "/sys/class/net/%s/statistics/tx_packets",
-		       "/sys/class/net/%s/statistics/tx_bytes"};
+                       "/sys/class/net/%s/statistics/rx_bytes",
+                       "/sys/class/net/%s/statistics/tx_packets",
+                       "/sys/class/net/%s/statistics/tx_bytes"
+                      };
 
   struct network_t *state = malloc(sizeof(struct network_t));
 
   char buffer2[256];
-  for(int i=0; i<4; i++) {
-    sprintf(buffer2, filenames[i], dev);
-    state->sources[i] = open(buffer2, O_RDONLY);
-  }
-  *ptr = (void*) state;
+  for(int i=0; i<4; i++)
+    {
+      sprintf(buffer2, filenames[i], dev);
+      state->sources[i] = open(buffer2, O_RDONLY);
+    }
+  *ptr = (void *) state;
   _get_network(state->values, state->sources);
 
   return 4;
 }
 
-unsigned int get_network(uint64_t* results, void* ptr) {
+unsigned int get_network(uint64_t *results, void *ptr)
+{
   struct network_t *state = (struct network_t *) ptr;
   _get_network(state->tmp_values, state->sources);
   for(int i=0; i<4; i++)
@@ -87,17 +95,19 @@ unsigned int get_network(uint64_t* results, void* ptr) {
   return 4;
 }
 
-void clean_network(void *ptr) {
+void clean_network(void *ptr)
+{
   struct network_t *state = (struct network_t *) ptr;
   if(state==NULL)
     return;
-  for(int i=0;i<4;i++)
+  for(int i=0; i<4; i++)
     close(state->sources[i]);
   free(state);
-}    
+}
 
 char *_labels_network[4] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void*none) {
+void label_network(char **labels, void *none)
+{
   for(int i=0; i<4; i++)
     labels[i] = _labels_network[i];
 }
diff --git a/src/network.h b/src/network.h
index 44759dc..3ba9ae5 100644
--- a/src/network.h
+++ b/src/network.h
@@ -18,8 +18,8 @@
 
  *******************************************************/
 
-unsigned int init_network(char*, void **);
-unsigned int get_network(uint64_t* results, void*);
+unsigned int init_network(char *, void **);
+unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
-void label_network(char **labels, void*);
+void label_network(char **labels, void *);
 
diff --git a/src/rapl.c b/src/rapl.c
index 14b4a58..2536600 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -24,15 +24,16 @@
 
 #include <powercap/powercap-rapl.h>
 
-struct _rapl_t {
-  powercap_rapl_pkg* pkgs;
+struct _rapl_t
+{
+  powercap_rapl_pkg *pkgs;
   uint32_t nb_pkgs;
   uint32_t nb;
   char **names;
-  uint32_t* zones;
-  uint32_t* packages;
-  uint64_t* values;
-  uint64_t* tmp_values;
+  uint32_t *zones;
+  uint32_t *packages;
+  uint64_t *values;
+  uint64_t *tmp_values;
 };
 
 typedef struct _rapl_t _rapl_t;
@@ -49,69 +50,77 @@ const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_COR
 #define MAX_LEN_NAME 100
 
 // values [zone + package *nbzones] microjoules
-void _get_rapl(uint64_t *values, _rapl_t* rapl) {
-  for (int i = 0; i < rapl->nb; i++) {
+void _get_rapl(uint64_t *values, _rapl_t *rapl)
+{
+  for (int i = 0; i < rapl->nb; i++)
+    {
 #ifdef DEBUG
-    int ret =
+      int ret =
 #endif
-      powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
-				rapl->zones[i],
-				&values[i]);
+        powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
+                                    rapl->zones[i],
+                                    &values[i]);
 #ifdef DEBUG
-    printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
+      printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
 #endif
-  }
+    }
 }
 
-unsigned int init_rapl(char* none, void **ptr) {
+unsigned int init_rapl(char *none, void **ptr)
+{
   // get number of processor sockets
-  _rapl_t* rapl= malloc(sizeof(struct _rapl_t));
+  _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
   rapl->nb = 0;
   rapl->packages = NULL;
   rapl->zones = NULL;
 
   rapl->nb_pkgs = powercap_rapl_get_num_instances();
   //rapl->nb_pkgs = powercap_rapl_get_num_packages();
-  
-  if (rapl->nb_pkgs == 0) {
-    perror("no packages found (maybe the kernel module isn't loaded?)");
-    exit(-1);
-  }
-  rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));  
-  for (int package = 0; package < rapl->nb_pkgs; package++)
-    if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
-      perror("powercap_rapl_init, check access (root needed ?)");
+
+  if (rapl->nb_pkgs == 0)
+    {
+      perror("no packages found (maybe the kernel module isn't loaded?)");
       exit(-1);
     }
+  rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
+  for (int package = 0; package < rapl->nb_pkgs; package++)
+    if (powercap_rapl_init(package, &rapl->pkgs[package], 0))
+      {
+        perror("powercap_rapl_init, check access (root needed ?)");
+        exit(-1);
+      }
 
   rapl->names = NULL;
-    
+
   char _name[MAX_LEN_NAME+1];
   char _name2[MAX_LEN_NAME+11];
 
-  for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
-    for(unsigned int zone=0; zone < nb_zones; zone++) {
-      int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-			     _name, MAX_LEN_NAME);
-      if (length>0) {
-
-	sprintf(_name2, "%s%u", _name, package);
-
-	rapl->nb++;
-	rapl->names = realloc(rapl->names, sizeof(char*)*rapl->nb);
-	rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
-	rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
-	rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
-	
-	strcpy(rapl->names[rapl->nb-1], _name2);
-	rapl->zones[rapl->nb-1] = rapl_zones[zone];
-	rapl->packages[rapl->nb-1] = package;
-      }
+  for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
+    {
+      for(unsigned int zone=0; zone < nb_zones; zone++)
+        {
+          int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
+                                            _name, MAX_LEN_NAME);
+          if (length>0)
+            {
+
+              sprintf(_name2, "%s%u", _name, package);
+
+              rapl->nb++;
+              rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
+              rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
+              rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
+              rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+
+              strcpy(rapl->names[rapl->nb-1], _name2);
+              rapl->zones[rapl->nb-1] = rapl_zones[zone];
+              rapl->packages[rapl->nb-1] = package;
+            }
 #ifdef DEBUG
-      printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
+          printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
 #endif
+        }
     }
-  }
 #ifdef DEBUG
   printf("Result of init\n");
   for(int i=0; i<rapl->nb; i++)
@@ -123,14 +132,15 @@ unsigned int init_rapl(char* none, void **ptr) {
 
   _get_rapl(rapl->values, rapl);
 
-  *ptr = (void*)rapl;
+  *ptr = (void *)rapl;
   return rapl->nb;
 }
 
 
 
-unsigned int get_rapl(uint64_t* results, void* ptr) {
-  _rapl_t* state = (_rapl_t*) ptr;
+unsigned int get_rapl(uint64_t *results, void *ptr)
+{
+  _rapl_t *state = (_rapl_t *) ptr;
   _get_rapl(state->tmp_values, state);
   for(int i=0; i<state->nb; i++)
     results[i] = state->tmp_values[i] - state->values[i];
@@ -142,14 +152,15 @@ unsigned int get_rapl(uint64_t* results, void* ptr) {
 
 
 
-void clean_rapl(void* ptr) {
-  _rapl_t* rapl = (_rapl_t*) ptr;
+void clean_rapl(void *ptr)
+{
+  _rapl_t *rapl = (_rapl_t *) ptr;
   for (int package = 0; package < rapl->nb_pkgs; package++)
     if (powercap_rapl_destroy(&rapl->pkgs[package]))
       perror("powercap_rapl_destroy");
-  for (int elem=0; elem<rapl->nb; elem++) 
-      free(rapl->names[elem]);
-  
+  for (int elem=0; elem<rapl->nb; elem++)
+    free(rapl->names[elem]);
+
   free(rapl->names);
   free(rapl->pkgs);
   free(rapl->zones);
@@ -159,8 +170,9 @@ void clean_rapl(void* ptr) {
   free(rapl);
 }
 
-void label_rapl(char **labels, void *ptr) {
-  _rapl_t* rapl = (_rapl_t*) ptr;
+void label_rapl(char **labels, void *ptr)
+{
+  _rapl_t *rapl = (_rapl_t *) ptr;
   for(int i=0; i<rapl->nb; i++)
     labels[i] = rapl->names[i];
 }
diff --git a/src/rapl.h b/src/rapl.h
index 9ec5f3a..74cc515 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -18,8 +18,8 @@
 
  *******************************************************/
 
-unsigned int init_rapl(char*, void **);
-unsigned int get_rapl(uint64_t* results, void*);
+unsigned int init_rapl(char *, void **);
+unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
-void label_rapl(char **labels, void*);
+void label_rapl(char **labels, void *);
 
diff --git a/src/temperature.c b/src/temperature.c
index 142e86a..9dec997 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -25,113 +25,127 @@
 #include <stdio.h>
 #include <stdint.h>
 
-struct temperature_t {
+struct temperature_t
+{
   char **label_list;
   int *fid_list;
   int nb_elem;
 };
-  
-int get_string(char *filename, char *buffer, int max_size) {
+
+int get_string(char *filename, char *buffer, int max_size)
+{
   int fid = open(filename, O_RDONLY);
   //printf("Tries to open : %s : %d\n", filename, fid);
   if(fid == -1)
     return -1;
-      
+
   int nb = read(fid, buffer, max_size);
-  if(nb == -1) {
-    close(fid);
-    return -1;
-  }
+  if(nb == -1)
+    {
+      close(fid);
+      return -1;
+    }
 
   buffer[nb]=0;
   close(fid);
   return 0;
 }
 
-void add_to_list(char ***list_name, char *source, int nb_elem) {
+void add_to_list(char ***list_name, char *source, int nb_elem)
+{
   //printf("Adds: %s\n", source);
-  *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char*));
+  *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
   (*list_name)[nb_elem] = malloc(strlen(source)+1);
   strcpy((*list_name)[nb_elem], source);
 
 }
 
-void add_temperature_sensor(int id_rep, struct temperature_t *state) {
+void add_temperature_sensor(int id_rep, struct temperature_t *state)
+{
   static int key=0;
   static char buffer_filename[512];
   static char buffer_label[512];
-  
+
   int delta = sprintf(buffer_label, "Temp_%d_", key);
-  
-  for(int i=1;;i++) {
-    sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
-    if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
-      break;
-
-    for(int pos = 0; pos < strlen(buffer_label); pos++) {
-      if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
-      if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
-    }
-    add_to_list(&state->label_list, buffer_label, state->nb_elem);
 
-    sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
-    state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
-    state->fid_list[state->nb_elem] = open(buffer_filename, O_RDONLY);
+  for(int i=1;; i++)
+    {
+      sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+      if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
+        break;
+
+      for(int pos = 0; pos < strlen(buffer_label); pos++)
+        {
+          if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
+          if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+        }
+      add_to_list(&state->label_list, buffer_label, state->nb_elem);
+
+      sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+      state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
+      state->fid_list[state->nb_elem] = open(buffer_filename, O_RDONLY);
+
+      state->nb_elem++;
+      // printf("%s : %s\n", buffer_label, buffer_filename);
+    }
 
-    state->nb_elem++;
-    // printf("%s : %s\n", buffer_label, buffer_filename);
-  }
-  
   key++;
 }
 
-unsigned int init_temperature(char *args, void** ptr) {
+unsigned int init_temperature(char *args, void **ptr)
+{
   struct temperature_t *state = malloc(sizeof(struct temperature_t));
   state->nb_elem = 0;
   state->label_list = NULL;
   state->fid_list = NULL;
-  
+
   char base_name[] = "/sys/class/hwmon/hwmon%d/name";
   static char name[512];
   static char buffer[512];
 
   int i = 0;
   sprintf(name, base_name, i);
-  while(get_string(name, buffer, 8) != -1) {
-    if (strcmp(buffer, "coretemp")==0)
-      add_temperature_sensor(i, state);
-
-    i++;
-    sprintf(name, base_name, i);
-  }
-  *ptr = (void*) state;
+  while(get_string(name, buffer, 8) != -1)
+    {
+      if (strcmp(buffer, "coretemp")==0)
+        add_temperature_sensor(i, state);
+
+      i++;
+      sprintf(name, base_name, i);
+    }
+  *ptr = (void *) state;
   return state->nb_elem;
 }
 
-unsigned int get_temperature(uint64_t* results, void* ptr) {
-  struct temperature_t *state = (struct temperature_t*)ptr;
+unsigned int get_temperature(uint64_t *results, void *ptr)
+{
+  struct temperature_t *state = (struct temperature_t *)ptr;
   static char buffer[512];
-  for(int i=0; i<state->nb_elem; i++) {
-    pread(state->fid_list[i], buffer, 100, 0);
-    results[i] = strtoull(buffer, NULL, 10);
-  }
+  for(int i=0; i<state->nb_elem; i++)
+    {
+      pread(state->fid_list[i], buffer, 100, 0);
+      results[i] = strtoull(buffer, NULL, 10);
+    }
   return state->nb_elem;
 }
 
-void clean_temperature(void* ptr) {
-  struct temperature_t *state = (struct temperature_t*)ptr;
-  
-  for(int i=0; i<state->nb_elem; i++) {
-    free(state->label_list[i]);
-    close(state->fid_list[i]);
-  }
+void clean_temperature(void *ptr)
+{
+  struct temperature_t *state = (struct temperature_t *)ptr;
+
+  for(int i=0; i<state->nb_elem; i++)
+    {
+      free(state->label_list[i]);
+      close(state->fid_list[i]);
+    }
   free(state->label_list);
   free(state->fid_list);
   free(state);
 }
 
-void label_temperature(char**labels, void* ptr) {
-  struct temperature_t *state = (struct temperature_t*)ptr;
+void label_temperature(char **labels, void *ptr)
+{
+  struct temperature_t *state = (struct temperature_t *)ptr;
   for(int i=0; i<state->nb_elem; i++)
     labels[i] = state->label_list[i];
 }
diff --git a/src/temperature.h b/src/temperature.h
index c6c34df..e49e416 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -18,7 +18,7 @@
 
  *******************************************************/
 
-unsigned int init_temperature(char*, void **);
-unsigned int get_temperature(uint64_t* results, void*);
+unsigned int init_temperature(char *, void **);
+unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
-void label_temperature(char **labels, void*);
+void label_temperature(char **labels, void *);
-- 
GitLab


From 235419f61c07e12e6a6b00741f53da148b9900c4 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 20 Dec 2022 13:12:48 +0100
Subject: [PATCH 003/229] code style: 4 spaces instead of 2

---
 makefile                  |   8 +-
 src/counters_group.c      | 129 ++++++------
 src/counters_individual.c | 250 +++++++++++------------
 src/frapl.c               | 180 ++++++++---------
 src/infiniband.c          |  60 +++---
 src/load.c                |  40 ++--
 src/mojitos.c             | 404 ++++++++++++++++++++------------------
 src/network.c             | 120 +++++------
 src/rapl.c                | 184 ++++++++---------
 src/temperature.c         | 174 ++++++++--------
 10 files changed, 787 insertions(+), 762 deletions(-)

diff --git a/makefile b/makefile
index 064dfca..6aaf27c 100644
--- a/makefile
+++ b/makefile
@@ -1,4 +1,4 @@
-.PHONY: all clean mojitos mojitos_group debug format 
+.PHONY: all clean mojitos mojitos_group debug format
 
 SRC_DIR = src
 OBJ_DIR = obj
@@ -10,7 +10,7 @@ OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 CC = gcc
 CFLAGS = -std=gnu99 -O3 -Wall # -Wextra -Werror -Wpedantic
 
-ASTYLE = astyle --style=gnu -s2 -k3 -n -Z -Q
+ASTYLE = astyle --style=gnu -xf -s4 -k3 -n -Z -Q
 
 
 # depending on the context it may need to be changed to all: mojitos mojitos_group
@@ -34,7 +34,7 @@ $(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
 $(OBJ_DIR)/%.o : $(SRC_DIR)/%.c $(SRC_DIR)/%.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(OBJ_DIR): 
+$(OBJ_DIR):
 	mkdir -p $(OBJ_DIR)
 
 $(BIN_DIR):
@@ -43,7 +43,7 @@ $(BIN_DIR):
 debug: CFLAGS += -DDEBUG -g
 debug: all
 
-format: 
+format:
 	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
 
 clean:
diff --git a/src/counters_group.c b/src/counters_group.c
index f134823..0154a94 100644
--- a/src/counters_group.c
+++ b/src/counters_group.c
@@ -31,104 +31,103 @@
 
 struct _counter_t
 {
-  int nbcores;
-  int nbperf;
-  int *counters;
+    int nbcores;
+    int nbperf;
+    int *counters;
 };
 
-static long
-perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                int cpu, int group_fd, unsigned long flags)
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                            int cpu, int group_fd, unsigned long flags)
 {
-  long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-  if (res == -1)
-    {
-      perror("perf_event_open");
-      fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-      exit(EXIT_FAILURE);
-    }
-  return res;
+    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+    if (res == -1)
+        {
+            perror("perf_event_open");
+            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+            exit(EXIT_FAILURE);
+        }
+    return res;
 }
 
 counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
-  struct perf_event_attr pe;
-  struct _counter_t *counters = malloc(sizeof(struct _counter_t));
+    struct perf_event_attr pe;
+    struct _counter_t *counters = malloc(sizeof(struct _counter_t));
 
-  unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
-  counters->nbcores=nbcores;
-  counters->nbperf=nb_perf;
-  memset(&pe, 0, sizeof(struct perf_event_attr));
-  pe.size = sizeof(struct perf_event_attr);
-  pe.disabled = 1;
+    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
+    counters->nbcores=nbcores;
+    counters->nbperf=nb_perf;
+    memset(&pe, 0, sizeof(struct perf_event_attr));
+    pe.size = sizeof(struct perf_event_attr);
+    pe.disabled = 1;
 
-  pe.read_format = PERF_FORMAT_GROUP;
-  counters->counters = malloc((nbcores+1)*sizeof(int));
+    pe.read_format = PERF_FORMAT_GROUP;
+    counters->counters = malloc((nbcores+1)*sizeof(int));
 
-  for (int core=0; core<nbcores; core++)
-    {
-      counters->counters[core]=-1;
-      for(int idperf=0; idperf<nb_perf; idperf ++)
+    for (int core=0; core<nbcores; core++)
         {
-          pe.type = types[idperf];
-          pe.config = names[idperf];
-          int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-          if(counters->counters[core]==-1)
-            counters->counters[core]=res;
+            counters->counters[core]=-1;
+            for(int idperf=0; idperf<nb_perf; idperf ++)
+                {
+                    pe.type = types[idperf];
+                    pe.config = names[idperf];
+                    int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
+                    if(counters->counters[core]==-1)
+                        counters->counters[core]=res;
+                }
         }
-    }
-  return counters;
+    return counters;
 }
 
 void clean_counters(counter_t counters)
 {
-  for(int core=0; core<counters->nbcores; core++)
-    close(counters->counters[core]);
-  free(counters->counters);
-  free(counters);
+    for(int core=0; core<counters->nbcores; core++)
+        close(counters->counters[core]);
+    free(counters->counters);
+    free(counters);
 }
 
 void start_counters(counter_t counters)
 {
-  for(int core=0; core<counters->nbcores; core++)
-    ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
+    for(int core=0; core<counters->nbcores; core++)
+        ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
 }
 void reset_counters(counter_t counters)
 {
-  for(int core=0; core<counters->nbcores; core++)
-    ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
+    for(int core=0; core<counters->nbcores; core++)
+        ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
 }
 
 struct read_format
 {
-  uint64_t nr;
-  struct
-  {
-    uint64_t value;
-  } values[];
+    uint64_t nr;
+    struct
+    {
+        uint64_t value;
+    } values[];
 };
 
 void get_counters(counter_t counters, long long *values)
 {
-  int nb_perf = counters->nbperf;
-  size_t buffer_size = sizeof(uint64_t)*(1+nb_perf);
-  struct read_format *buffer = NULL;
-  if(buffer==NULL)
-    buffer = malloc(buffer_size);
+    int nb_perf = counters->nbperf;
+    size_t buffer_size = sizeof(uint64_t)*(1+nb_perf);
+    struct read_format *buffer = NULL;
+    if(buffer==NULL)
+        buffer = malloc(buffer_size);
 
-  memset(values, 0, nb_perf*sizeof(long long));
+    memset(values, 0, nb_perf*sizeof(long long));
 
-  for (int core=0; core<counters->nbcores; core++)
-    {
-      if (-1 == read(counters->counters[core], buffer, buffer_size))
-        {
-          perror("PB Lecture resultat");
-          exit(EXIT_FAILURE);
-        }
-      for(int idperf=0; idperf<=nb_perf; idperf++)
+    for (int core=0; core<counters->nbcores; core++)
         {
-          values[idperf] += buffer->values[idperf].value;
+            if (-1 == read(counters->counters[core], buffer, buffer_size))
+                {
+                    perror("PB Lecture resultat");
+                    exit(EXIT_FAILURE);
+                }
+            for(int idperf=0; idperf<=nb_perf; idperf++)
+                {
+                    values[idperf] += buffer->values[idperf].value;
+                }
         }
-    }
-  reset_counters(counters);
+    reset_counters(counters);
 }
diff --git a/src/counters_individual.c b/src/counters_individual.c
index 222037a..aff7fd0 100644
--- a/src/counters_individual.c
+++ b/src/counters_individual.c
@@ -30,13 +30,13 @@
 
 struct _counter_t
 {
-  int nbcores;
-  int nbperf;
-  int **counters;
-  uint64_t *counters_values;
-  uint64_t *tmp_counters_values;
+    int nbcores;
+    int nbperf;
+    int **counters;
+    uint64_t *counters_values;
+    uint64_t *tmp_counters_values;
 
-  int *perf_indexes;
+    int *perf_indexes;
 
 };
 typedef struct _counter_t *counter_t;
@@ -45,134 +45,134 @@ typedef struct _counter_t *counter_t;
 
 void show_all_counters()
 {
-  for(int i=0; i<nb_counter_option; i++)
-    printf("%s\n", perf_static_info[i].name);
+    for(int i=0; i<nb_counter_option; i++)
+        printf("%s\n", perf_static_info[i].name);
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
 {
-  *perf_type = malloc(nb*sizeof(__u32));
-  *perf_key  = malloc(nb*sizeof(__u64));
-  for(int i=0; i<nb; i++)
-    {
-      (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
-      (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
-    }
+    *perf_type = malloc(nb*sizeof(__u32));
+    *perf_key  = malloc(nb*sizeof(__u64));
+    for(int i=0; i<nb; i++)
+        {
+            (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
+            (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
+        }
 }
 void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
 {
-  char *token;
-  *nb_perf=0;
-  *perf_indexes=NULL;
-  while((token=strtok(perf_string, ",")) != NULL)
-    {
-      perf_string = NULL;
-      int i;
-      for(i=0; i<nb_counter_option; i++)
+    char *token;
+    *nb_perf=0;
+    *perf_indexes=NULL;
+    while((token=strtok(perf_string, ",")) != NULL)
         {
-          if(strcmp(perf_static_info[i].name, token) == 0)
-            {
-              (*nb_perf)++;
-              (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-              (*perf_indexes)[*nb_perf-1]=i;
-              break;
-            }
+            perf_string = NULL;
+            int i;
+            for(i=0; i<nb_counter_option; i++)
+                {
+                    if(strcmp(perf_static_info[i].name, token) == 0)
+                        {
+                            (*nb_perf)++;
+                            (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
+                            (*perf_indexes)[*nb_perf-1]=i;
+                            break;
+                        }
+                }
+            if(i == nb_counter_option)
+                {
+                    fprintf(stderr, "Unknown performance counter: %s\n", token);
+                    exit(EXIT_FAILURE);
+                }
         }
-      if(i == nb_counter_option)
-        {
-          fprintf(stderr, "Unknown performance counter: %s\n", token);
-          exit(EXIT_FAILURE);
-        }
-    }
 }
 
 static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                             int cpu, int group_fd, unsigned long flags)
 {
-  long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-  if (res == -1)
-    {
-      perror("perf_event_open");
-      fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-      exit(EXIT_FAILURE);
-    }
-  return res;
+    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+    if (res == -1)
+        {
+            perror("perf_event_open");
+            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+            exit(EXIT_FAILURE);
+        }
+    return res;
 }
 
 counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
-  struct perf_event_attr pe;
-  unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
-  memset(&pe, 0, sizeof(struct perf_event_attr));
-  pe.size = sizeof(struct perf_event_attr);
-  pe.disabled = 1;
-
-  counter_t counters = malloc(sizeof(struct _counter_t));
-  counters->nbperf = nb_perf;
-  counters->nbcores=nbcores;
-  counters->counters=malloc(nb_perf*sizeof(int *));
-  for (int i=0; i<nb_perf; i++)
-    {
-      pe.type = types[i];
-      pe.config = names[i];
-      counters->counters[i] = malloc(nbcores*sizeof(int));
-
-      for (int core=0; core<nbcores; core++)
+    struct perf_event_attr pe;
+    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
+    memset(&pe, 0, sizeof(struct perf_event_attr));
+    pe.size = sizeof(struct perf_event_attr);
+    pe.disabled = 1;
+
+    counter_t counters = malloc(sizeof(struct _counter_t));
+    counters->nbperf = nb_perf;
+    counters->nbcores=nbcores;
+    counters->counters=malloc(nb_perf*sizeof(int *));
+    for (int i=0; i<nb_perf; i++)
         {
-          counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
+            pe.type = types[i];
+            pe.config = names[i];
+            counters->counters[i] = malloc(nbcores*sizeof(int));
+
+            for (int core=0; core<nbcores; core++)
+                {
+                    counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
+                }
         }
-    }
-  return counters;
+    return counters;
 }
 
 void clean_counters(void *ptr)
 {
-  counter_t counters = (counter_t) ptr;
-  for(int counter=0; counter<counters->nbperf; counter++)
-    {
-      for(int core=0; core<counters->nbcores; core++)
-        close(counters->counters[counter][core]);
-      free(counters->counters[counter]);
-    }
-  free(counters->counters);
-  free(counters->counters_values);
-  free(counters->tmp_counters_values);
-  free(counters->perf_indexes);
-
-  free(counters);
+    counter_t counters = (counter_t) ptr;
+    for(int counter=0; counter<counters->nbperf; counter++)
+        {
+            for(int core=0; core<counters->nbcores; core++)
+                close(counters->counters[counter][core]);
+            free(counters->counters[counter]);
+        }
+    free(counters->counters);
+    free(counters->counters_values);
+    free(counters->tmp_counters_values);
+    free(counters->perf_indexes);
+
+    free(counters);
 }
 
 void start_counters(counter_t counters)
 {
-  for(int counter=0; counter<counters->nbperf; counter++)
-    for(int core=0; core<counters->nbcores; core++)
-      ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
+    for(int counter=0; counter<counters->nbperf; counter++)
+        for(int core=0; core<counters->nbcores; core++)
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
 }
 
 void reset_counters(counter_t counters)
 {
-  for(int counter=0; counter<counters->nbperf; counter++)
-    for(int core=0; core<counters->nbcores; core++)
-      ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
+    for(int counter=0; counter<counters->nbperf; counter++)
+        for(int core=0; core<counters->nbcores; core++)
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
 }
 
 void _get_counters(counter_t counters, uint64_t *values)
 {
-  for(int i=0; i<counters->nbperf; i++)
-    {
-      uint64_t accu=0;
-      uint64_t count=0;
-      for (int core=0; core<counters->nbcores; core++)
+    for(int i=0; i<counters->nbperf; i++)
         {
-          if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t)))
-            {
-              fprintf(stderr, "Cannot read result");
-              exit(EXIT_FAILURE);
-            }
-          accu += count;
+            uint64_t accu=0;
+            uint64_t count=0;
+            for (int core=0; core<counters->nbcores; core++)
+                {
+                    if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t)))
+                        {
+                            fprintf(stderr, "Cannot read result");
+                            exit(EXIT_FAILURE);
+                        }
+                    accu += count;
+                }
+            values[i] = accu;
         }
-      values[i] = accu;
-    }
 }
 
 
@@ -182,44 +182,44 @@ void _get_counters(counter_t counters, uint64_t *values)
 
 unsigned int init_counters(char *args, void **state)
 {
-  int nb_perf;
-  int *perf_indexes=NULL;
-
-  perf_event_list(args, &nb_perf, &perf_indexes);
-
-  __u32 *perf_type;
-  __u64 *perf_key;
-  perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
-  counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
-  free(perf_type);
-  free(perf_key);
-
-  fd->perf_indexes = perf_indexes;
-  fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
-  fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
-  start_counters(fd);
-  _get_counters(fd, fd->counters_values);
-  *state = (void *) fd;
-
-  return nb_perf;
+    int nb_perf;
+    int *perf_indexes=NULL;
+
+    perf_event_list(args, &nb_perf, &perf_indexes);
+
+    __u32 *perf_type;
+    __u64 *perf_key;
+    perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
+    counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
+    free(perf_type);
+    free(perf_key);
+
+    fd->perf_indexes = perf_indexes;
+    fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
+    fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
+    start_counters(fd);
+    _get_counters(fd, fd->counters_values);
+    *state = (void *) fd;
+
+    return nb_perf;
 }
 
 unsigned int get_counters(uint64_t *results, void *ptr)
 {
-  counter_t state = (counter_t) ptr;
+    counter_t state = (counter_t) ptr;
 
-  _get_counters(state, state->tmp_counters_values);
-  for(int i=0; i<state->nbperf; i++)
-    results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+    _get_counters(state, state->tmp_counters_values);
+    for(int i=0; i<state->nbperf; i++)
+        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
 
-  memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
-  return state->nbperf;
+    memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
+    return state->nbperf;
 }
 
 void label_counters(char **labels, void *ptr)
 {
-  counter_t state = (counter_t) ptr;
-  for(int i=0; i<state->nbperf; i++)
-    labels[i] = perf_static_info[state->perf_indexes[i]].name;
+    counter_t state = (counter_t) ptr;
+    for(int i=0; i<state->nbperf; i++)
+        labels[i] = perf_static_info[state->perf_indexes[i]].name;
 
 }
diff --git a/src/frapl.c b/src/frapl.c
index d0d0abf..f142c45 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -30,32 +30,32 @@
 
 char *get_frapl_string(const char *filename)
 {
-  int fd = open(filename, O_RDONLY);
-  if( fd == -1)
-    return NULL;
-  char *result = malloc(MAX_HEADER);
-  int nb = read(fd, result, MAX_HEADER);
-  close(fd);
-  result[nb-1] = 0;
-  return (result);
+    int fd = open(filename, O_RDONLY);
+    if( fd == -1)
+        return NULL;
+    char *result = malloc(MAX_HEADER);
+    int nb = read(fd, result, MAX_HEADER);
+    close(fd);
+    result[nb-1] = 0;
+    return (result);
 }
 
 void test_append(char *name, int i)
 {
-  //char last = name[strlen(name)-1];
-  //if (last>='0' && last <= '9')
-  //  return;
-  sprintf(name+strlen(name), "%d", i);
+    //char last = name[strlen(name)-1];
+    //if (last>='0' && last <= '9')
+    //  return;
+    sprintf(name+strlen(name), "%d", i);
 }
 
 
 struct _frapl_t
 {
-  unsigned int nb;
-  char **names;
-  int *fids;
-  uint64_t *values;
-  uint64_t *tmp_values;
+    unsigned int nb;
+    char **names;
+    int *fids;
+    uint64_t *values;
+    uint64_t *tmp_values;
 
 };
 typedef struct _frapl_t _frapl_t;
@@ -63,112 +63,112 @@ typedef struct _frapl_t _frapl_t;
 
 void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
 {
-  rapl->nb += 1;
-  rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
-  rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
+    rapl->nb += 1;
+    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
+    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
 
-  rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
-  strcpy(rapl->names[rapl->nb-1], name);
-  //printf("%s\n", energy_uj);
+    rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
+    strcpy(rapl->names[rapl->nb-1], name);
+    //printf("%s\n", energy_uj);
 
-  rapl->fids[rapl->nb-1] = open(energy_uj, O_RDONLY);
+    rapl->fids[rapl->nb-1] = open(energy_uj, O_RDONLY);
 }
 
 
 void _get_frapl(uint64_t *values, _frapl_t *rapl)
 {
-  static char buffer[512];
+    static char buffer[512];
 
-  for (int i = 0; i < rapl->nb; i++)
-    {
+    for (int i = 0; i < rapl->nb; i++)
+        {
 
-      pread(rapl->fids[i], buffer, 100, 0);
-      values[i] = strtoull(buffer, NULL, 10);
-    }
+            pread(rapl->fids[i], buffer, 100, 0);
+            values[i] = strtoull(buffer, NULL, 10);
+        }
 }
 
 
 unsigned int init_frapl(char *none, void **ptr)
 {
-  _frapl_t *rapl = malloc(sizeof(_frapl_t));
-  rapl->nb = 0;
-  rapl->names = NULL;
-  rapl->fids = NULL;
-
-  char buffer[1024];
-  char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
-  char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
-
-  for (int i=0;; i++)
-    {
-      sprintf(buffer, name_base, i, "name");
-      char *tmp = get_frapl_string(buffer);
-      if (tmp == NULL) break;
-      //printf("%s\n", tmp);
-      test_append(tmp, i);
-      //printf("%s -> %s\n", buffer, tmp);
-
-      sprintf(buffer, name_base, i, "energy_uj");
-      add_frapl_source(rapl, tmp, buffer);
-      free(tmp);
-
-      for (int j=0;; j++)
-        {
-          sprintf(buffer, name_sub, i, i, j, "name");
-          char *tmp_sub = get_frapl_string(buffer);
-          if (tmp_sub == NULL) break;
-          //printf("%s\n", tmp_sub);
-          test_append(tmp_sub, i);
-          //printf("%s -> %s\n", buffer, tmp_sub);
-
+    _frapl_t *rapl = malloc(sizeof(_frapl_t));
+    rapl->nb = 0;
+    rapl->names = NULL;
+    rapl->fids = NULL;
 
-          sprintf(buffer, name_sub, i, i, j, "energy_uj");
-          add_frapl_source(rapl, tmp_sub, buffer);
+    char buffer[1024];
+    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
+    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-          free(tmp_sub);
+    for (int i=0;; i++)
+        {
+            sprintf(buffer, name_base, i, "name");
+            char *tmp = get_frapl_string(buffer);
+            if (tmp == NULL) break;
+            //printf("%s\n", tmp);
+            test_append(tmp, i);
+            //printf("%s -> %s\n", buffer, tmp);
+
+            sprintf(buffer, name_base, i, "energy_uj");
+            add_frapl_source(rapl, tmp, buffer);
+            free(tmp);
+
+            for (int j=0;; j++)
+                {
+                    sprintf(buffer, name_sub, i, i, j, "name");
+                    char *tmp_sub = get_frapl_string(buffer);
+                    if (tmp_sub == NULL) break;
+                    //printf("%s\n", tmp_sub);
+                    test_append(tmp_sub, i);
+                    //printf("%s -> %s\n", buffer, tmp_sub);
+
+
+                    sprintf(buffer, name_sub, i, i, j, "energy_uj");
+                    add_frapl_source(rapl, tmp_sub, buffer);
+
+                    free(tmp_sub);
+                }
         }
-    }
 
-  rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-  rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
 
-  _get_frapl(rapl->values, rapl);
+    _get_frapl(rapl->values, rapl);
 
-  *ptr = (void *)rapl;
-  return rapl->nb;
+    *ptr = (void *)rapl;
+    return rapl->nb;
 }
 
 
 unsigned int get_frapl(uint64_t *results, void *ptr)
 {
-  _frapl_t *state = (_frapl_t *) ptr;
-  _get_frapl(state->tmp_values, state);
-  for(int i=0; i<state->nb; i++)
-    results[i] = state->tmp_values[i] - state->values[i];
+    _frapl_t *state = (_frapl_t *) ptr;
+    _get_frapl(state->tmp_values, state);
+    for(int i=0; i<state->nb; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
 
-  memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-  return state->nb;
+    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
+    return state->nb;
 }
 
 void clean_frapl(void *ptr)
 {
-  _frapl_t *rapl = (_frapl_t *) ptr;
-  for(int i=0; i<rapl->nb; i++)
-    {
-      free(rapl->names[i]);
-      close(rapl->fids[i]);
-    }
-  free(rapl->names);
-  free(rapl->fids);
-  free(rapl->values);
-  free(rapl->tmp_values);
-  free(rapl);
+    _frapl_t *rapl = (_frapl_t *) ptr;
+    for(int i=0; i<rapl->nb; i++)
+        {
+            free(rapl->names[i]);
+            close(rapl->fids[i]);
+        }
+    free(rapl->names);
+    free(rapl->fids);
+    free(rapl->values);
+    free(rapl->tmp_values);
+    free(rapl);
 }
 
 
 void label_frapl(char **labels, void *ptr)
 {
-  _frapl_t *rapl = (_frapl_t *) ptr;
-  for(int i=0; i<rapl->nb; i++)
-    labels[i] = rapl->names[i];
+    _frapl_t *rapl = (_frapl_t *) ptr;
+    for(int i=0; i<rapl->nb; i++)
+        labels[i] = rapl->names[i];
 }
diff --git a/src/infiniband.c b/src/infiniband.c
index e0daa2a..4c1da1d 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -28,53 +28,53 @@
 
 struct network_t
 {
-  uint64_t values[4];
-  uint64_t tmp_values[4];
-  int sources[4];
+    uint64_t values[4];
+    uint64_t tmp_values[4];
+    int sources[4];
 };
 unsigned int _get_network(uint64_t *results, int *sources);
 
 
 unsigned int init_infiniband(char *infi_path, void **ptr)
 {
-  if(infi_path==NULL)
-    return 0;
+    if(infi_path==NULL)
+        return 0;
 
-  if(strcmp(infi_path,"X")==0)
-    {
+    if(strcmp(infi_path,"X")==0)
+        {
 
-      glob_t res;
+            glob_t res;
 
-      glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
-      if(res.gl_pathc == 0)
-        return 0;
-      infi_path = res.gl_pathv[0];
-    }
+            glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
+            if(res.gl_pathc == 0)
+                return 0;
+            infi_path = res.gl_pathv[0];
+        }
 
-  char *filenames[] = {"%s/port_rcv_packets",
-                       "%s/port_rcv_data",
-                       "%s/port_xmit_packets",
-                       "%s/port_xmit_data"
-                      };
+    char *filenames[] = {"%s/port_rcv_packets",
+                         "%s/port_rcv_data",
+                         "%s/port_xmit_packets",
+                         "%s/port_xmit_data"
+                        };
 
-  struct network_t *state = malloc(sizeof(struct network_t));
+    struct network_t *state = malloc(sizeof(struct network_t));
 
-  char buffer[1024];
-  for(int i=0; i<4; i++)
-    {
-      sprintf(buffer, filenames[i], infi_path);
-      state->sources[i] = open(buffer, O_RDONLY);
-    }
+    char buffer[1024];
+    for(int i=0; i<4; i++)
+        {
+            sprintf(buffer, filenames[i], infi_path);
+            state->sources[i] = open(buffer, O_RDONLY);
+        }
 
-  *ptr = (void *) state;
-  _get_network(state->values, state->sources);
+    *ptr = (void *) state;
+    _get_network(state->values, state->sources);
 
-  return 4;
+    return 4;
 }
 
 char *_labels_infiniband[4] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
-  for(int i=0; i<4; i++)
-    labels[i] = _labels_infiniband[i];
+    for(int i=0; i<4; i++)
+        labels[i] = _labels_infiniband[i];
 }
diff --git a/src/load.c b/src/load.c
index 80daf4b..e345119 100644
--- a/src/load.c
+++ b/src/load.c
@@ -32,39 +32,39 @@ static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
 
 void _get_load(uint64_t *results)
 {
-  pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0);
-  int pos=0;
-  while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
-  for(int i=0; i<10; i++)
-    {
-      results[i] = strtoull(buffer+pos, NULL, 10);
-      while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
-      pos++;
-    }
+    pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0);
+    int pos=0;
+    while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
+    for(int i=0; i<10; i++)
+        {
+            results[i] = strtoull(buffer+pos, NULL, 10);
+            while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
+            pos++;
+        }
 }
 
 // Public interface
 
 unsigned int init_load(char *argument, void **state)
 {
-  load_fid = open("/proc/stat", O_RDONLY);
-  _get_load(load_values);
-  return 10;
+    load_fid = open("/proc/stat", O_RDONLY);
+    _get_load(load_values);
+    return 10;
 }
 
 unsigned int get_load(uint64_t *results, void *state)
 {
-  _get_load(tmp_load_values);
-  for(int i=0; i<10; i++)
-    results[i] = tmp_load_values[i] - load_values[i];
+    _get_load(tmp_load_values);
+    for(int i=0; i<10; i++)
+        results[i] = tmp_load_values[i] - load_values[i];
 
-  memcpy(load_values, tmp_load_values, sizeof(load_values));
-  return 10;
+    memcpy(load_values, tmp_load_values, sizeof(load_values));
+    return 10;
 }
 
 void clean_load(void *state)
 {
-  close(load_fid);
+    close(load_fid);
 }
 
 char *_labels[10] = {"user","nice","system","idle","iowait","irq",
@@ -72,6 +72,6 @@ char *_labels[10] = {"user","nice","system","idle","iowait","irq",
                     };
 void label_load(char **labels, void *none)
 {
-  for(int i=0; i<10; i++)
-    labels[i] = _labels[i];
+    for(int i=0; i<10; i++)
+        labels[i] = _labels[i];
 }
diff --git a/src/mojitos.c b/src/mojitos.c
index 94954cf..23e71c3 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -37,20 +37,22 @@
 
 void usage(char **argv)
 {
-  printf("Usage : %s [-t time] [-f freq] [-r] [-p perf_list] [-l] [-u] [-c] [-d network_device] [-i infiniband_path] [-o logfile] [-e command arguments...]\n", argv[0]);
-  printf("if time==0 then loops infinitively\n");
-  printf("if -e is present, time and freq are not used\n");
-  printf("-r activates RAPL\n");
-  printf("-R activates the file version of RAPL\n");
-  printf("-p activates performance counters\n");
-  printf("   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n");
-  printf("-l lists the possible performance counters and quits\n");
-  printf("-d activates network monitoring (if network_device is X, tries to detect it automatically)\n");
-  printf("-i activates infiniband monitoring (if infiniband_path is X, tries to detect it automatically)\n");
-  printf("-s activates statistics of overhead in nanoseconds\n");
-  printf("-u activates report of system load\n");
-  printf("-c activates report of processor temperature\n");
-  exit(EXIT_SUCCESS);
+    printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
+           "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
+           "if time==0 then loops infinitively\n"
+           "if -e is present, time and freq are not used\n"
+           "-r activates RAPL\n"
+           "-R activates the file version of RAPL\n"
+           "-p activates performance counters\n"
+           "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
+           "-l lists the possible performance counters and quits\n"
+           "-d activates network monitoring (if network_device is X, tries to detect it automatically)\n"
+           "-i activates infiniband monitoring (if infiniband_path is X, tries to detect it automatically)\n"
+           "-s activates statistics of overhead in nanoseconds\n"
+           "-u activates report of system load\n"
+           "-c activates report of processor temperature\n"
+           , argv[0]);
+    exit(EXIT_SUCCESS);
 }
 
 void sighandler(int none)
@@ -59,14 +61,14 @@ void sighandler(int none)
 
 void flush(int none)
 {
-  exit(0);
+    exit(0);
 }
 
 FILE *output;
 void flushexit()
 {
-  fflush(output);
-  fclose(output);
+    fflush(output);
+    fclose(output);
 }
 
 typedef unsigned int (initializer_t)(char *, void **);
@@ -74,199 +76,223 @@ typedef void (labeler_t)(char **, void *);
 typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
-unsigned int nb_sources=0;
-void **states=NULL;
-getter_t *getter=NULL;
-cleaner_t *cleaner=NULL;
+unsigned int nb_sources = 0;
+void **states = NULL;
+getter_t *getter = NULL;
+cleaner_t *cleaner = NULL;
 
-unsigned int nb_sensors=0;
-char **labels=NULL;
-uint64_t *values=NULL;
+unsigned int nb_sensors = 0;
+char **labels = NULL;
+uint64_t *values = NULL;
 
 void add_source(initializer_t init, char *arg, labeler_t labeler,
                 getter_t get, cleaner_t clean)
 {
-  nb_sources++;
-  states = realloc(states, nb_sources*sizeof(void *));
-  int nb = init(arg, &states[nb_sources-1]);
-  if (nb == 0)
-    {
-      nb_sources--;
-      states = realloc(states, nb_sources*sizeof(void *));
-      return;
-    }
-
-  getter = realloc(getter, nb_sources*sizeof(void *));
-  getter[nb_sources-1] = get;
-  cleaner = realloc(cleaner, nb_sources*sizeof(void *));
-  cleaner[nb_sources-1] = clean;
-
-  labels = realloc(labels, (nb_sensors+nb)*sizeof(char *));
-  labeler(labels+nb_sensors, states[nb_sources-1]);
-
-  values = realloc(values, (nb_sensors+nb)*sizeof(uint64_t));
-  nb_sensors += nb;
+    nb_sources++;
+    states = realloc(states, nb_sources * sizeof(void *));
+    int nb = init(arg, &states[nb_sources - 1]);
+    if (nb == 0)
+        {
+            nb_sources--;
+            states = realloc(states, nb_sources * sizeof(void *));
+            return;
+        }
+
+    getter = realloc(getter, nb_sources * sizeof(void *));
+    getter[nb_sources - 1] = get;
+    cleaner = realloc(cleaner, nb_sources * sizeof(void *));
+    cleaner[nb_sources - 1] = clean;
+
+    labels = realloc(labels, (nb_sensors + nb) * sizeof(char *));
+    labeler(labels + nb_sensors, states[nb_sources - 1]);
+
+    values = realloc(values, (nb_sensors + nb) * sizeof(uint64_t));
+    nb_sensors += nb;
 }
 
 int main(int argc, char **argv)
 {
-  int total_time=1;
-  int delta=0;
-  int frequency=1;
-  char **application = NULL;
-
-  int stat_mode = -1;
-
-  if(argc==1)
-    usage(argv);
-
-  output=stdout;
-
-  atexit(flushexit);
-  signal(15, flush);
-
-  int c;
-  while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application==NULL)
-    switch (c)
-      {
-      case 'f':
-        frequency=atoi(argv[optind]);
-        break;
-      case 't':
-        total_time=atoi(argv[optind]);
-        delta=1;
-        if(total_time==0)
-          {
-            total_time=1;
-            delta=0;
-          }
-        break;
-      case 'd':
-        add_source(init_network, argv[optind], label_network, get_network, clean_network);
-        break;
-      case 'i':
-        add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
-        break;
-      case 'o':
-        output = fopen(argv[optind],"wb");
-        break;
-      case 'e':
-        application=&argv[optind];
-        signal(17,sighandler);
-        break;
-      case 'p':
-        add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
-        break;
-      case 'r':
-        add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
-        break;
-      case 'R':
-        add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
-        break;
-      case 'u':
-        add_source(init_load, NULL, label_load, get_load, clean_load);
-        break;
-      case 'c':
-        add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
-        break;
-      case 's':
-        stat_mode=0;
-        break;
-      case 'l':
-        show_all_counters();
-        exit(EXIT_SUCCESS);
-      default:
-        usage(argv);
-      }
-
-
-  setvbuf(output, NULL, _IONBF, BUFSIZ);
-  struct timespec ts;
-  struct timespec ts_ref;
-
-  fprintf(output, "#timestamp ");
-
-  for(int i=0; i<nb_sensors; i++)
-    fprintf(output, "%s ", labels[i]);
-
-  if(stat_mode==0)
-    fprintf(output, "overhead ");
-
-  fprintf(output, "\n");
-
-  unsigned long int stat_data=0;
-
-  for (int temps = 0; temps <total_time*frequency; temps+=delta)
-    {
-      clock_gettime(CLOCK_MONOTONIC, &ts_ref);
-
-      // Get Data
-      unsigned int current = 0;
-      for(int i=0; i<nb_sources; i++)
-        current += getter[i](&values[current], states[i]);
-
-      if(application != NULL)
-        {
+    int total_time = 1;
+    int delta = 0;
+    int frequency = 1;
+    char **application = NULL;
 
-          if(fork()==0)
-            {
-              execvp(application[0], application);
-              exit(0);
-            }
-          pause();
-          clock_gettime(CLOCK_MONOTONIC, &ts);
-          if(ts.tv_nsec >= ts_ref.tv_nsec)
-            fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec), ts.tv_nsec-ts_ref.tv_nsec);
-          else
-            fprintf(output, "%ld.%09ld ", (ts.tv_sec-ts_ref.tv_sec)-1,1000000000+ts.tv_nsec-ts_ref.tv_nsec);
-        }
-      else
+    int stat_mode = -1;
+
+    if (argc == 1)
         {
-#ifdef DEBUG
-          clock_gettime(CLOCK_MONOTONIC, &ts);
-          fprintf(stderr, "%ld\n", (ts.tv_nsec-ts_ref.tv_nsec)/1000);
-          //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
-          //Group: mean: 309 std: 41 % med: 297 std: 39 %
-#endif
-          if(stat_mode==0)
+            usage(argv);
+        }
+
+    output = stdout;
+
+    atexit(flushexit);
+    signal(15, flush);
+
+    int c;
+    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL)
+        switch (c)
             {
-              clock_gettime(CLOCK_MONOTONIC, &ts);
-              if(ts.tv_nsec >= ts_ref.tv_nsec)
-                stat_data = ts.tv_nsec-ts_ref.tv_nsec;
-              else
-                stat_data = 1000000000+ts.tv_nsec-ts_ref.tv_nsec;
+            case 'f':
+                frequency = atoi(argv[optind]);
+                break;
+            case 't':
+                total_time = atoi(argv[optind]);
+                delta = 1;
+                if (total_time == 0)
+                    {
+                        total_time = 1;
+                        delta = 0;
+                    }
+                break;
+            case 'd':
+                add_source(init_network, argv[optind], label_network, get_network, clean_network);
+                break;
+            case 'i':
+                add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
+                break;
+            case 'o':
+                output = fopen(argv[optind], "wb");
+                break;
+            case 'e':
+                application = &argv[optind];
+                signal(17, sighandler);
+                break;
+            case 'p':
+                add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
+                break;
+            case 'r':
+                add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
+                break;
+            case 'R':
+                add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
+                break;
+            case 'u':
+                add_source(init_load, NULL, label_load, get_load, clean_load);
+                break;
+            case 'c':
+                add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
+                break;
+            case 's':
+                stat_mode = 0;
+                break;
+            case 'l':
+                show_all_counters();
+                exit(EXIT_SUCCESS);
+            default:
+                usage(argv);
             }
 
-          // Treat Data
-          fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
-        }
 
-      for(int i=0; i<nb_sensors; i++)
-        fprintf(output, "%" PRIu64 " ", values[i]);
+    setvbuf(output, NULL, _IONBF, BUFSIZ);
+    struct timespec ts;
+    struct timespec ts_ref;
 
-      if(stat_mode==0)
-        fprintf(output, "%ld ", stat_data);
+    fprintf(output, "#timestamp ");
 
-      fprintf(output, "\n");
+    for (int i = 0; i < nb_sensors; i++)
+        {
+            fprintf(output, "%s ", labels[i]);
+        }
 
-      if(application != NULL)
-        break;
+    if (stat_mode == 0)
+        {
+            fprintf(output, "overhead ");
+        }
 
-      clock_gettime(CLOCK_MONOTONIC, &ts);
-      usleep(1000*1000/frequency-(ts.tv_nsec/1000)%(1000*1000/frequency));
-    }
+    fprintf(output, "\n");
 
-  for(int i=0; i<nb_sources; i++)
-    cleaner[i](states[i]);
+    unsigned long int stat_data = 0;
 
-  if(nb_sources > 0)
-    {
-      free(getter);
-      free(cleaner);
-      free(labels);
-      free(values);
-      free(states);
-    }
+    for (int temps = 0; temps < total_time * frequency; temps += delta)
+        {
+            clock_gettime(CLOCK_MONOTONIC, &ts_ref);
+
+            // Get Data
+            unsigned int current = 0;
+            for (int i = 0; i < nb_sources; i++)
+                {
+                    current += getter[i](&values[current], states[i]);
+                }
+
+            if (application != NULL)
+                {
+
+                    if (fork() == 0)
+                        {
+                            execvp(application[0], application);
+                            exit(0);
+                        }
+                    pause();
+                    clock_gettime(CLOCK_MONOTONIC, &ts);
+                    if (ts.tv_nsec >= ts_ref.tv_nsec)
+                        {
+                            fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
+                        }
+                    else
+                        {
+                            fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
+                        }
+                }
+            else
+                {
+#ifdef DEBUG
+                    clock_gettime(CLOCK_MONOTONIC, &ts);
+                    fprintf(stderr, "%ld\n", (ts.tv_nsec - ts_ref.tv_nsec) / 1000);
+                    //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
+                    //Group: mean: 309 std: 41 % med: 297 std: 39 %
+#endif
+                    if (stat_mode == 0)
+                        {
+                            clock_gettime(CLOCK_MONOTONIC, &ts);
+                            if (ts.tv_nsec >= ts_ref.tv_nsec)
+                                {
+                                    stat_data = ts.tv_nsec - ts_ref.tv_nsec;
+                                }
+                            else
+                                {
+                                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
+                                }
+                        }
+
+                    // Treat Data
+                    fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
+                }
+
+            for (int i = 0; i < nb_sensors; i++)
+                {
+                    fprintf(output, "%" PRIu64 " ", values[i]);
+                }
+
+            if (stat_mode == 0)
+                {
+                    fprintf(output, "%ld ", stat_data);
+                }
+
+            fprintf(output, "\n");
+
+            if (application != NULL)
+                {
+                    break;
+                }
+
+            clock_gettime(CLOCK_MONOTONIC, &ts);
+            usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
+        }
+
+    for (int i = 0; i < nb_sources; i++)
+        {
+            cleaner[i](states[i]);
+        }
+
+    if (nb_sources > 0)
+        {
+            free(getter);
+            free(cleaner);
+            free(labels);
+            free(values);
+            free(states);
+        }
 }
 
 
diff --git a/src/network.c b/src/network.c
index 587319b..2cadf42 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,88 +26,88 @@
 
 struct network_t
 {
-  uint64_t values[4];
-  uint64_t tmp_values[4];
-  int sources[4];
+    uint64_t values[4];
+    uint64_t tmp_values[4];
+    int sources[4];
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
 {
-  if(sources==NULL)
-    return 0;
-  char buffer[128];
-  for(int i=0; i<4; i++)
-    {
-      pread(sources[i], buffer, 127, 0);
-
-      results[i] = strtoull(buffer, NULL, 10);
-    }
-  return 4;
+    if(sources==NULL)
+        return 0;
+    char buffer[128];
+    for(int i=0; i<4; i++)
+        {
+            pread(sources[i], buffer, 127, 0);
+
+            results[i] = strtoull(buffer, NULL, 10);
+        }
+    return 4;
 }
 
 
 
 unsigned int init_network(char *dev, void **ptr)
 {
-  if(dev==NULL)
-    return 0;
-
-  if(strcmp(dev,"X")==0)
-    {
-      int f = open("/proc/net/route", O_RDONLY);
-      char buffer[1000];
-      read(f, buffer, 999);
-      char *start_of_dev = index(buffer, '\n')+1;
-      char *end_of_dev = index(start_of_dev, '\t');
-      *end_of_dev='\0';
-      dev = start_of_dev;
-      close(f);
-    }
-
-  char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-                       "/sys/class/net/%s/statistics/rx_bytes",
-                       "/sys/class/net/%s/statistics/tx_packets",
-                       "/sys/class/net/%s/statistics/tx_bytes"
-                      };
-
-  struct network_t *state = malloc(sizeof(struct network_t));
-
-  char buffer2[256];
-  for(int i=0; i<4; i++)
-    {
-      sprintf(buffer2, filenames[i], dev);
-      state->sources[i] = open(buffer2, O_RDONLY);
-    }
-  *ptr = (void *) state;
-  _get_network(state->values, state->sources);
-
-  return 4;
+    if(dev==NULL)
+        return 0;
+
+    if(strcmp(dev,"X")==0)
+        {
+            int f = open("/proc/net/route", O_RDONLY);
+            char buffer[1000];
+            read(f, buffer, 999);
+            char *start_of_dev = index(buffer, '\n')+1;
+            char *end_of_dev = index(start_of_dev, '\t');
+            *end_of_dev='\0';
+            dev = start_of_dev;
+            close(f);
+        }
+
+    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
+                         "/sys/class/net/%s/statistics/rx_bytes",
+                         "/sys/class/net/%s/statistics/tx_packets",
+                         "/sys/class/net/%s/statistics/tx_bytes"
+                        };
+
+    struct network_t *state = malloc(sizeof(struct network_t));
+
+    char buffer2[256];
+    for(int i=0; i<4; i++)
+        {
+            sprintf(buffer2, filenames[i], dev);
+            state->sources[i] = open(buffer2, O_RDONLY);
+        }
+    *ptr = (void *) state;
+    _get_network(state->values, state->sources);
+
+    return 4;
 }
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
-  struct network_t *state = (struct network_t *) ptr;
-  _get_network(state->tmp_values, state->sources);
-  for(int i=0; i<4; i++)
-    results[i] = state->tmp_values[i] - state->values[i];
+    struct network_t *state = (struct network_t *) ptr;
+    _get_network(state->tmp_values, state->sources);
+    for(int i=0; i<4; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
 
-  memcpy(state->values, state->tmp_values, 4*sizeof(uint64_t));
-  return 4;
+    memcpy(state->values, state->tmp_values, 4*sizeof(uint64_t));
+    return 4;
 }
 
 void clean_network(void *ptr)
 {
-  struct network_t *state = (struct network_t *) ptr;
-  if(state==NULL)
-    return;
-  for(int i=0; i<4; i++)
-    close(state->sources[i]);
-  free(state);
+    struct network_t *state = (struct network_t *) ptr;
+    if(state==NULL)
+        return;
+    for(int i=0; i<4; i++)
+        close(state->sources[i]);
+    free(state);
 }
 
 char *_labels_network[4] = {"rxp", "rxb", "txp", "txb"};
 void label_network(char **labels, void *none)
 {
-  for(int i=0; i<4; i++)
-    labels[i] = _labels_network[i];
+    for(int i=0; i<4; i++)
+        labels[i] = _labels_network[i];
 }
diff --git a/src/rapl.c b/src/rapl.c
index 2536600..044a1b7 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -26,14 +26,14 @@
 
 struct _rapl_t
 {
-  powercap_rapl_pkg *pkgs;
-  uint32_t nb_pkgs;
-  uint32_t nb;
-  char **names;
-  uint32_t *zones;
-  uint32_t *packages;
-  uint64_t *values;
-  uint64_t *tmp_values;
+    powercap_rapl_pkg *pkgs;
+    uint32_t nb_pkgs;
+    uint32_t nb;
+    char **names;
+    uint32_t *zones;
+    uint32_t *packages;
+    uint64_t *values;
+    uint64_t *tmp_values;
 };
 
 typedef struct _rapl_t _rapl_t;
@@ -52,101 +52,101 @@ const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_COR
 // values [zone + package *nbzones] microjoules
 void _get_rapl(uint64_t *values, _rapl_t *rapl)
 {
-  for (int i = 0; i < rapl->nb; i++)
-    {
+    for (int i = 0; i < rapl->nb; i++)
+        {
 #ifdef DEBUG
-      int ret =
+            int ret =
 #endif
-        powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
-                                    rapl->zones[i],
-                                    &values[i]);
+                powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
+                                            rapl->zones[i],
+                                            &values[i]);
 #ifdef DEBUG
-      printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
+            printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
 #endif
-    }
+        }
 }
 
 unsigned int init_rapl(char *none, void **ptr)
 {
-  // get number of processor sockets
-  _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
-  rapl->nb = 0;
-  rapl->packages = NULL;
-  rapl->zones = NULL;
-
-  rapl->nb_pkgs = powercap_rapl_get_num_instances();
-  //rapl->nb_pkgs = powercap_rapl_get_num_packages();
-
-  if (rapl->nb_pkgs == 0)
-    {
-      perror("no packages found (maybe the kernel module isn't loaded?)");
-      exit(-1);
-    }
-  rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
-  for (int package = 0; package < rapl->nb_pkgs; package++)
-    if (powercap_rapl_init(package, &rapl->pkgs[package], 0))
-      {
-        perror("powercap_rapl_init, check access (root needed ?)");
-        exit(-1);
-      }
-
-  rapl->names = NULL;
-
-  char _name[MAX_LEN_NAME+1];
-  char _name2[MAX_LEN_NAME+11];
-
-  for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-    {
-      for(unsigned int zone=0; zone < nb_zones; zone++)
+    // get number of processor sockets
+    _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
+    rapl->nb = 0;
+    rapl->packages = NULL;
+    rapl->zones = NULL;
+
+    rapl->nb_pkgs = powercap_rapl_get_num_instances();
+    //rapl->nb_pkgs = powercap_rapl_get_num_packages();
+
+    if (rapl->nb_pkgs == 0)
         {
-          int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-                                            _name, MAX_LEN_NAME);
-          if (length>0)
+            perror("no packages found (maybe the kernel module isn't loaded?)");
+            exit(-1);
+        }
+    rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
+    for (int package = 0; package < rapl->nb_pkgs; package++)
+        if (powercap_rapl_init(package, &rapl->pkgs[package], 0))
             {
+                perror("powercap_rapl_init, check access (root needed ?)");
+                exit(-1);
+            }
 
-              sprintf(_name2, "%s%u", _name, package);
+    rapl->names = NULL;
 
-              rapl->nb++;
-              rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
-              rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
-              rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
-              rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+    char _name[MAX_LEN_NAME+1];
+    char _name2[MAX_LEN_NAME+11];
 
-              strcpy(rapl->names[rapl->nb-1], _name2);
-              rapl->zones[rapl->nb-1] = rapl_zones[zone];
-              rapl->packages[rapl->nb-1] = package;
-            }
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
+        {
+            for(unsigned int zone=0; zone < nb_zones; zone++)
+                {
+                    int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
+                                                      _name, MAX_LEN_NAME);
+                    if (length>0)
+                        {
+
+                            sprintf(_name2, "%s%u", _name, package);
+
+                            rapl->nb++;
+                            rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
+                            rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
+                            rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
+                            rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+
+                            strcpy(rapl->names[rapl->nb-1], _name2);
+                            rapl->zones[rapl->nb-1] = rapl_zones[zone];
+                            rapl->packages[rapl->nb-1] = package;
+                        }
 #ifdef DEBUG
-          printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
+                    printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
 #endif
+                }
         }
-    }
 #ifdef DEBUG
-  printf("Result of init\n");
-  for(int i=0; i<rapl->nb; i++)
-    printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
+    printf("Result of init\n");
+    for(int i=0; i<rapl->nb; i++)
+        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
 #endif
 
-  rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-  rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
 
-  _get_rapl(rapl->values, rapl);
+    _get_rapl(rapl->values, rapl);
 
-  *ptr = (void *)rapl;
-  return rapl->nb;
+    *ptr = (void *)rapl;
+    return rapl->nb;
 }
 
 
 
 unsigned int get_rapl(uint64_t *results, void *ptr)
 {
-  _rapl_t *state = (_rapl_t *) ptr;
-  _get_rapl(state->tmp_values, state);
-  for(int i=0; i<state->nb; i++)
-    results[i] = state->tmp_values[i] - state->values[i];
+    _rapl_t *state = (_rapl_t *) ptr;
+    _get_rapl(state->tmp_values, state);
+    for(int i=0; i<state->nb; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
 
-  memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-  return state->nb;
+    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
+    return state->nb;
 }
 
 
@@ -154,25 +154,25 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 
 void clean_rapl(void *ptr)
 {
-  _rapl_t *rapl = (_rapl_t *) ptr;
-  for (int package = 0; package < rapl->nb_pkgs; package++)
-    if (powercap_rapl_destroy(&rapl->pkgs[package]))
-      perror("powercap_rapl_destroy");
-  for (int elem=0; elem<rapl->nb; elem++)
-    free(rapl->names[elem]);
-
-  free(rapl->names);
-  free(rapl->pkgs);
-  free(rapl->zones);
-  free(rapl->packages);
-  free(rapl->values);
-  free(rapl->tmp_values);
-  free(rapl);
+    _rapl_t *rapl = (_rapl_t *) ptr;
+    for (int package = 0; package < rapl->nb_pkgs; package++)
+        if (powercap_rapl_destroy(&rapl->pkgs[package]))
+            perror("powercap_rapl_destroy");
+    for (int elem=0; elem<rapl->nb; elem++)
+        free(rapl->names[elem]);
+
+    free(rapl->names);
+    free(rapl->pkgs);
+    free(rapl->zones);
+    free(rapl->packages);
+    free(rapl->values);
+    free(rapl->tmp_values);
+    free(rapl);
 }
 
 void label_rapl(char **labels, void *ptr)
 {
-  _rapl_t *rapl = (_rapl_t *) ptr;
-  for(int i=0; i<rapl->nb; i++)
-    labels[i] = rapl->names[i];
+    _rapl_t *rapl = (_rapl_t *) ptr;
+    for(int i=0; i<rapl->nb; i++)
+        labels[i] = rapl->names[i];
 }
diff --git a/src/temperature.c b/src/temperature.c
index 9dec997..e9282dc 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -27,125 +27,125 @@
 
 struct temperature_t
 {
-  char **label_list;
-  int *fid_list;
-  int nb_elem;
+    char **label_list;
+    int *fid_list;
+    int nb_elem;
 };
 
 int get_string(char *filename, char *buffer, int max_size)
 {
-  int fid = open(filename, O_RDONLY);
-  //printf("Tries to open : %s : %d\n", filename, fid);
-  if(fid == -1)
-    return -1;
-
-  int nb = read(fid, buffer, max_size);
-  if(nb == -1)
-    {
-      close(fid);
-      return -1;
-    }
-
-  buffer[nb]=0;
-  close(fid);
-  return 0;
+    int fid = open(filename, O_RDONLY);
+    //printf("Tries to open : %s : %d\n", filename, fid);
+    if(fid == -1)
+        return -1;
+
+    int nb = read(fid, buffer, max_size);
+    if(nb == -1)
+        {
+            close(fid);
+            return -1;
+        }
+
+    buffer[nb]=0;
+    close(fid);
+    return 0;
 }
 
 void add_to_list(char ***list_name, char *source, int nb_elem)
 {
-  //printf("Adds: %s\n", source);
-  *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
-  (*list_name)[nb_elem] = malloc(strlen(source)+1);
-  strcpy((*list_name)[nb_elem], source);
+    //printf("Adds: %s\n", source);
+    *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
+    (*list_name)[nb_elem] = malloc(strlen(source)+1);
+    strcpy((*list_name)[nb_elem], source);
 
 }
 
 void add_temperature_sensor(int id_rep, struct temperature_t *state)
 {
-  static int key=0;
-  static char buffer_filename[512];
-  static char buffer_label[512];
+    static int key=0;
+    static char buffer_filename[512];
+    static char buffer_label[512];
 
-  int delta = sprintf(buffer_label, "Temp_%d_", key);
+    int delta = sprintf(buffer_label, "Temp_%d_", key);
 
-  for(int i=1;; i++)
-    {
-      sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
-      if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
-        break;
-
-      for(int pos = 0; pos < strlen(buffer_label); pos++)
+    for(int i=1;; i++)
         {
-          if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
-          if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+            sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+            if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
+                break;
+
+            for(int pos = 0; pos < strlen(buffer_label); pos++)
+                {
+                    if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
+                    if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+                }
+            add_to_list(&state->label_list, buffer_label, state->nb_elem);
+
+            sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+            state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
+            state->fid_list[state->nb_elem] = open(buffer_filename, O_RDONLY);
+
+            state->nb_elem++;
+            // printf("%s : %s\n", buffer_label, buffer_filename);
         }
-      add_to_list(&state->label_list, buffer_label, state->nb_elem);
-
-      sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
-      state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
-      state->fid_list[state->nb_elem] = open(buffer_filename, O_RDONLY);
 
-      state->nb_elem++;
-      // printf("%s : %s\n", buffer_label, buffer_filename);
-    }
-
-  key++;
+    key++;
 }
 
 unsigned int init_temperature(char *args, void **ptr)
 {
-  struct temperature_t *state = malloc(sizeof(struct temperature_t));
-  state->nb_elem = 0;
-  state->label_list = NULL;
-  state->fid_list = NULL;
-
-  char base_name[] = "/sys/class/hwmon/hwmon%d/name";
-  static char name[512];
-  static char buffer[512];
-
-  int i = 0;
-  sprintf(name, base_name, i);
-  while(get_string(name, buffer, 8) != -1)
-    {
-      if (strcmp(buffer, "coretemp")==0)
-        add_temperature_sensor(i, state);
-
-      i++;
-      sprintf(name, base_name, i);
-    }
-  *ptr = (void *) state;
-  return state->nb_elem;
+    struct temperature_t *state = malloc(sizeof(struct temperature_t));
+    state->nb_elem = 0;
+    state->label_list = NULL;
+    state->fid_list = NULL;
+
+    char base_name[] = "/sys/class/hwmon/hwmon%d/name";
+    static char name[512];
+    static char buffer[512];
+
+    int i = 0;
+    sprintf(name, base_name, i);
+    while(get_string(name, buffer, 8) != -1)
+        {
+            if (strcmp(buffer, "coretemp")==0)
+                add_temperature_sensor(i, state);
+
+            i++;
+            sprintf(name, base_name, i);
+        }
+    *ptr = (void *) state;
+    return state->nb_elem;
 }
 
 unsigned int get_temperature(uint64_t *results, void *ptr)
 {
-  struct temperature_t *state = (struct temperature_t *)ptr;
-  static char buffer[512];
-  for(int i=0; i<state->nb_elem; i++)
-    {
-      pread(state->fid_list[i], buffer, 100, 0);
-      results[i] = strtoull(buffer, NULL, 10);
-    }
-  return state->nb_elem;
+    struct temperature_t *state = (struct temperature_t *)ptr;
+    static char buffer[512];
+    for(int i=0; i<state->nb_elem; i++)
+        {
+            pread(state->fid_list[i], buffer, 100, 0);
+            results[i] = strtoull(buffer, NULL, 10);
+        }
+    return state->nb_elem;
 }
 
 void clean_temperature(void *ptr)
 {
-  struct temperature_t *state = (struct temperature_t *)ptr;
-
-  for(int i=0; i<state->nb_elem; i++)
-    {
-      free(state->label_list[i]);
-      close(state->fid_list[i]);
-    }
-  free(state->label_list);
-  free(state->fid_list);
-  free(state);
+    struct temperature_t *state = (struct temperature_t *)ptr;
+
+    for(int i=0; i<state->nb_elem; i++)
+        {
+            free(state->label_list[i]);
+            close(state->fid_list[i]);
+        }
+    free(state->label_list);
+    free(state->fid_list);
+    free(state);
 }
 
 void label_temperature(char **labels, void *ptr)
 {
-  struct temperature_t *state = (struct temperature_t *)ptr;
-  for(int i=0; i<state->nb_elem; i++)
-    labels[i] = state->label_list[i];
+    struct temperature_t *state = (struct temperature_t *)ptr;
+    for(int i=0; i<state->nb_elem; i++)
+        labels[i] = state->label_list[i];
 }
-- 
GitLab


From 6739c0277c2c1fad4833e00b8203e47a570143f4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 08:22:18 +0000
Subject: [PATCH 004/229] Replace multiple occurrences of int with define

---
 src/network.c | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)

diff --git a/src/network.c b/src/network.c
index 2cadf42..1032c85 100644
--- a/src/network.c
+++ b/src/network.c
@@ -24,11 +24,13 @@
 #include <string.h>
 #include <stdint.h>
 
+#define NB_SENSOR 4
+
 struct network_t
 {
-    uint64_t values[4];
-    uint64_t tmp_values[4];
-    int sources[4];
+    uint64_t values[NB_SENSOR];
+    uint64_t tmp_values[NB_SENSOR];
+    int sources[NB_SENSOR];
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
@@ -36,13 +38,13 @@ unsigned int _get_network(uint64_t *results, int *sources)
     if(sources==NULL)
         return 0;
     char buffer[128];
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         {
             pread(sources[i], buffer, 127, 0);
 
             results[i] = strtoull(buffer, NULL, 10);
         }
-    return 4;
+    return NB_SENSOR;
 }
 
 
@@ -73,7 +75,7 @@ unsigned int init_network(char *dev, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer2[256];
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         {
             sprintf(buffer2, filenames[i], dev);
             state->sources[i] = open(buffer2, O_RDONLY);
@@ -81,18 +83,18 @@ unsigned int init_network(char *dev, void **ptr)
     *ptr = (void *) state;
     _get_network(state->values, state->sources);
 
-    return 4;
+    return NB_SENSOR;
 }
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
     _get_network(state->tmp_values, state->sources);
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         results[i] = state->tmp_values[i] - state->values[i];
 
-    memcpy(state->values, state->tmp_values, 4*sizeof(uint64_t));
-    return 4;
+    memcpy(state->values, state->tmp_values, NB_SENSOR*sizeof(uint64_t));
+    return NB_SENSOR;
 }
 
 void clean_network(void *ptr)
@@ -100,14 +102,14 @@ void clean_network(void *ptr)
     struct network_t *state = (struct network_t *) ptr;
     if(state==NULL)
         return;
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         close(state->sources[i]);
     free(state);
 }
 
-char *_labels_network[4] = {"rxp", "rxb", "txp", "txb"};
+char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
 void label_network(char **labels, void *none)
 {
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_network[i];
 }
-- 
GitLab


From 13f506f0c8554e67bac9c3a82424f931492425f4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 08:25:19 +0000
Subject: [PATCH 005/229] Replace multiple occurrences of int with define

---
 src/infiniband.c | 16 +++++++++-------
 1 file changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/infiniband.c b/src/infiniband.c
index 4c1da1d..1f0171b 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -26,11 +26,13 @@
 
 #include <stdint.h>
 
+#define NB_SENSOR 4
+
 struct network_t
 {
-    uint64_t values[4];
-    uint64_t tmp_values[4];
-    int sources[4];
+    uint64_t values[NB_SENSOR];
+    uint64_t tmp_values[NB_SENSOR];
+    int sources[NB_SENSOR];
 };
 unsigned int _get_network(uint64_t *results, int *sources);
 
@@ -60,7 +62,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer[1024];
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         {
             sprintf(buffer, filenames[i], infi_path);
             state->sources[i] = open(buffer, O_RDONLY);
@@ -69,12 +71,12 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     *ptr = (void *) state;
     _get_network(state->values, state->sources);
 
-    return 4;
+    return NB_SENSOR;
 }
 
-char *_labels_infiniband[4] = {"irxp", "irxb", "itxp", "itxb"};
+char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
-    for(int i=0; i<4; i++)
+    for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_infiniband[i];
 }
-- 
GitLab


From 49467488ab26107953f6772084980d3bc088538e Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 10:57:33 +0000
Subject: [PATCH 006/229] Fix: error handling

---
 src/frapl.c       | 21 ++++++++++++++++++---
 src/load.c        | 16 ++++++++++++++--
 src/network.c     | 26 ++++++++++++++++++++++----
 src/temperature.c | 16 +++++++++++++---
 4 files changed, 67 insertions(+), 12 deletions(-)

diff --git a/src/frapl.c b/src/frapl.c
index f142c45..438af03 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -24,6 +24,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <errno.h>
 
 
 #define MAX_HEADER 128
@@ -32,7 +33,9 @@ char *get_frapl_string(const char *filename)
 {
     int fd = open(filename, O_RDONLY);
     if( fd == -1)
-        return NULL;
+        {
+            return NULL;
+        }
     char *result = malloc(MAX_HEADER);
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
@@ -71,7 +74,15 @@ void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
     strcpy(rapl->names[rapl->nb-1], name);
     //printf("%s\n", energy_uj);
 
-    rapl->fids[rapl->nb-1] = open(energy_uj, O_RDONLY);
+    int fd = open(energy_uj, O_RDONLY);
+
+    if (fd < 0)
+        {
+            fprintf(stderr, "%s ", energy_uj);
+            perror("open");
+            exit(1);
+        }
+    rapl->fids[rapl->nb-1] = fd;
 }
 
 
@@ -82,7 +93,11 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
     for (int i = 0; i < rapl->nb; i++)
         {
 
-            pread(rapl->fids[i], buffer, 100, 0);
+            if (pread(rapl->fids[i], buffer, 100, 0) < 0)
+                {
+                    perror("pread");
+                    exit(1);
+                }
             values[i] = strtoull(buffer, NULL, 10);
         }
 }
diff --git a/src/load.c b/src/load.c
index e345119..5a909b6 100644
--- a/src/load.c
+++ b/src/load.c
@@ -22,6 +22,7 @@
 #include <stdlib.h>
 #include <stdint.h>
 #include <string.h>
+#include <stdio.h>
 
 #define LOAD_BUFFER_SIZE 1024
 char buffer[LOAD_BUFFER_SIZE];
@@ -29,10 +30,15 @@ char buffer[LOAD_BUFFER_SIZE];
 static int load_fid=-1;
 static uint64_t load_values[10]= {0,0,0,0,0,0,0,0,0,0};
 static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
+static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
 {
-    pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0);
+    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0)
+        {
+            perror("pread");
+            exit(1);
+        }
     int pos=0;
     while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
     for(int i=0; i<10; i++)
@@ -47,7 +53,13 @@ void _get_load(uint64_t *results)
 
 unsigned int init_load(char *argument, void **state)
 {
-    load_fid = open("/proc/stat", O_RDONLY);
+    load_fid = open(stat, O_RDONLY);
+    if (load_fid < 0)
+        {
+            fprintf(stderr,"%s ",stat);
+            perror("open");
+            exit(1);
+        }
     _get_load(load_values);
     return 10;
 }
diff --git a/src/network.c b/src/network.c
index 1032c85..7a22f23 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,6 +26,7 @@
 
 #define NB_SENSOR 4
 
+static char *route = "/proc/net/route";
 struct network_t
 {
     uint64_t values[NB_SENSOR];
@@ -40,7 +41,11 @@ unsigned int _get_network(uint64_t *results, int *sources)
     char buffer[128];
     for(int i=0; i<NB_SENSOR; i++)
         {
-            pread(sources[i], buffer, 127, 0);
+            if (pread(sources[i], buffer, 127, 0) < 0)
+                {
+                    perror("pread");
+                    exit(1);
+                }
 
             results[i] = strtoull(buffer, NULL, 10);
         }
@@ -56,14 +61,27 @@ unsigned int init_network(char *dev, void **ptr)
 
     if(strcmp(dev,"X")==0)
         {
-            int f = open("/proc/net/route", O_RDONLY);
+            int fd = open(route, O_RDONLY);
+            if (fd < 0)
+                {
+                    fprintf(stderr, "%s ", route);
+                    perror("open");
+                    exit(1);
+                }
             char buffer[1000];
-            read(f, buffer, 999);
+
+            if ( read(fd, buffer, 999) < 0 )
+                {
+                    perror("read");
+                    close(fd);
+                    exit(1);
+                }
+
             char *start_of_dev = index(buffer, '\n')+1;
             char *end_of_dev = index(start_of_dev, '\t');
             *end_of_dev='\0';
             dev = start_of_dev;
-            close(f);
+            close(fd);
         }
 
     char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
diff --git a/src/temperature.c b/src/temperature.c
index e9282dc..d3e4c99 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -83,8 +83,14 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 
             sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
             state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
-            state->fid_list[state->nb_elem] = open(buffer_filename, O_RDONLY);
-
+            int fd = open(buffer_filename, O_RDONLY);
+            if (fd < 0)
+                {
+                    fprintf(stderr, "%s ", buffer_filename);
+                    perror("open");
+                    exit(1);
+                }
+            state->fid_list[state->nb_elem] = fd;
             state->nb_elem++;
             // printf("%s : %s\n", buffer_label, buffer_filename);
         }
@@ -123,7 +129,11 @@ unsigned int get_temperature(uint64_t *results, void *ptr)
     static char buffer[512];
     for(int i=0; i<state->nb_elem; i++)
         {
-            pread(state->fid_list[i], buffer, 100, 0);
+            if (pread(state->fid_list[i], buffer, 100, 0) < 0)
+                {
+                    perror("pread");
+                    exit(1);
+                }
             results[i] = strtoull(buffer, NULL, 10);
         }
     return state->nb_elem;
-- 
GitLab


From 78bb763f196699ccc098d0ff2ee4048573ce03d4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 12:10:26 +0000
Subject: [PATCH 007/229] fix: Werror flag

---
 makefile      |  2 +-
 src/frapl.c   | 15 +++++++++------
 src/load.c    |  3 +++
 src/network.c |  2 ++
 4 files changed, 15 insertions(+), 7 deletions(-)

diff --git a/makefile b/makefile
index 6aaf27c..cca83e7 100644
--- a/makefile
+++ b/makefile
@@ -8,7 +8,7 @@ OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters_individual.o rapl.o frapl.
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall # -Wextra -Werror -Wpedantic
+CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
 
 ASTYLE = astyle --style=gnu -xf -s4 -k3 -n -Z -Q
 
diff --git a/src/frapl.c b/src/frapl.c
index 438af03..1cc0ef9 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -28,6 +28,8 @@
 
 
 #define MAX_HEADER 128
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
 
 char *get_frapl_string(const char *filename)
 {
@@ -90,7 +92,7 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
 {
     static char buffer[512];
 
-    for (int i = 0; i < rapl->nb; i++)
+    for (unsigned int i = 0; i < rapl->nb; i++)
         {
 
             if (pread(rapl->fids[i], buffer, 100, 0) < 0)
@@ -105,6 +107,7 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
 
 unsigned int init_frapl(char *none, void **ptr)
 {
+	UNUSED(none);
     _frapl_t *rapl = malloc(sizeof(_frapl_t));
     rapl->nb = 0;
     rapl->names = NULL;
@@ -114,7 +117,7 @@ unsigned int init_frapl(char *none, void **ptr)
     char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
     char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-    for (int i=0;; i++)
+    for (unsigned int i=0;; i++)
         {
             sprintf(buffer, name_base, i, "name");
             char *tmp = get_frapl_string(buffer);
@@ -127,7 +130,7 @@ unsigned int init_frapl(char *none, void **ptr)
             add_frapl_source(rapl, tmp, buffer);
             free(tmp);
 
-            for (int j=0;; j++)
+            for (unsigned int j=0;; j++)
                 {
                     sprintf(buffer, name_sub, i, i, j, "name");
                     char *tmp_sub = get_frapl_string(buffer);
@@ -158,7 +161,7 @@ unsigned int get_frapl(uint64_t *results, void *ptr)
 {
     _frapl_t *state = (_frapl_t *) ptr;
     _get_frapl(state->tmp_values, state);
-    for(int i=0; i<state->nb; i++)
+    for(unsigned int i=0; i<state->nb; i++)
         results[i] = state->tmp_values[i] - state->values[i];
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
@@ -168,7 +171,7 @@ unsigned int get_frapl(uint64_t *results, void *ptr)
 void clean_frapl(void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-    for(int i=0; i<rapl->nb; i++)
+    for(unsigned int i=0; i<rapl->nb; i++)
         {
             free(rapl->names[i]);
             close(rapl->fids[i]);
@@ -184,6 +187,6 @@ void clean_frapl(void *ptr)
 void label_frapl(char **labels, void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-    for(int i=0; i<rapl->nb; i++)
+	for(unsigned int i=0; i<rapl->nb; i++)
         labels[i] = rapl->names[i];
 }
diff --git a/src/load.c b/src/load.c
index 5a909b6..18c49a4 100644
--- a/src/load.c
+++ b/src/load.c
@@ -25,6 +25,7 @@
 #include <stdio.h>
 
 #define LOAD_BUFFER_SIZE 1024
+#define UNUSED(expr) do { (void)(expr); } while (0)
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid=-1;
@@ -53,6 +54,8 @@ void _get_load(uint64_t *results)
 
 unsigned int init_load(char *argument, void **state)
 {
+	UNUSED(argument);
+	UNUSED(state);
     load_fid = open(stat, O_RDONLY);
     if (load_fid < 0)
         {
diff --git a/src/network.c b/src/network.c
index 7a22f23..d9575af 100644
--- a/src/network.c
+++ b/src/network.c
@@ -25,6 +25,7 @@
 #include <stdint.h>
 
 #define NB_SENSOR 4
+#define UNUSED(expr) do { (void)(expr); } while (0)
 
 static char *route = "/proc/net/route";
 struct network_t
@@ -128,6 +129,7 @@ void clean_network(void *ptr)
 char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
 void label_network(char **labels, void *none)
 {
+	UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_network[i];
 }
-- 
GitLab


From 5e9585022ae6f8935461621f8843090b95480aff Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 12:59:31 +0000
Subject: [PATCH 008/229] fix: unused

---
 src/load.c        |  3 +++
 src/mojitos.c     | 12 +++++++-----
 src/temperature.c |  5 ++++-
 3 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/src/load.c b/src/load.c
index 18c49a4..33ebdbf 100644
--- a/src/load.c
+++ b/src/load.c
@@ -69,6 +69,7 @@ unsigned int init_load(char *argument, void **state)
 
 unsigned int get_load(uint64_t *results, void *state)
 {
+	UNUSED(state);
     _get_load(tmp_load_values);
     for(int i=0; i<10; i++)
         results[i] = tmp_load_values[i] - load_values[i];
@@ -79,6 +80,7 @@ unsigned int get_load(uint64_t *results, void *state)
 
 void clean_load(void *state)
 {
+	UNUSED(state);
     close(load_fid);
 }
 
@@ -87,6 +89,7 @@ char *_labels[10] = {"user","nice","system","idle","iowait","irq",
                     };
 void label_load(char **labels, void *none)
 {
+	UNUSED(none);
     for(int i=0; i<10; i++)
         labels[i] = _labels[i];
 }
diff --git a/src/mojitos.c b/src/mojitos.c
index 23e71c3..ed6b462 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -33,7 +33,7 @@
 #include "load.h"
 #include "temperature.h"
 
-
+#define UNUSED(expr) do { (void)(expr); } while (0)
 
 void usage(char **argv)
 {
@@ -57,10 +57,12 @@ void usage(char **argv)
 
 void sighandler(int none)
 {
+	UNUSED(none);
 }
 
 void flush(int none)
 {
+	UNUSED(none);
     exit(0);
 }
 
@@ -190,7 +192,7 @@ int main(int argc, char **argv)
 
     fprintf(output, "#timestamp ");
 
-    for (int i = 0; i < nb_sensors; i++)
+    for (unsigned int i = 0; i < nb_sensors; i++)
         {
             fprintf(output, "%s ", labels[i]);
         }
@@ -210,7 +212,7 @@ int main(int argc, char **argv)
 
             // Get Data
             unsigned int current = 0;
-            for (int i = 0; i < nb_sources; i++)
+            for (unsigned int i = 0; i < nb_sources; i++)
                 {
                     current += getter[i](&values[current], states[i]);
                 }
@@ -259,7 +261,7 @@ int main(int argc, char **argv)
                     fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
                 }
 
-            for (int i = 0; i < nb_sensors; i++)
+            for (unsigned int i = 0; i < nb_sensors; i++)
                 {
                     fprintf(output, "%" PRIu64 " ", values[i]);
                 }
@@ -280,7 +282,7 @@ int main(int argc, char **argv)
             usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
         }
 
-    for (int i = 0; i < nb_sources; i++)
+    for (unsigned int i = 0; i < nb_sources; i++)
         {
             cleaner[i](states[i]);
         }
diff --git a/src/temperature.c b/src/temperature.c
index d3e4c99..e210f7b 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -25,6 +25,8 @@
 #include <stdio.h>
 #include <stdint.h>
 
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
 struct temperature_t
 {
     char **label_list;
@@ -74,7 +76,7 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
             if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
                 break;
 
-            for(int pos = 0; pos < strlen(buffer_label); pos++)
+            for(unsigned int pos = 0; pos < strlen(buffer_label); pos++)
                 {
                     if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
                     if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
@@ -100,6 +102,7 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 
 unsigned int init_temperature(char *args, void **ptr)
 {
+	UNUSED(args);
     struct temperature_t *state = malloc(sizeof(struct temperature_t));
     state->nb_elem = 0;
     state->label_list = NULL;
-- 
GitLab


From 165260432f2bfa39c581932e4beaf51fbc206217 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 8 Jan 2023 13:14:41 +0000
Subject: [PATCH 009/229] fix unsigned & unused

---
 src/counters_individual.c |  6 +++---
 src/infiniband.c          |  2 ++
 src/rapl.c                | 17 ++++++++++-------
 3 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/counters_individual.c b/src/counters_individual.c
index aff7fd0..0f597ad 100644
--- a/src/counters_individual.c
+++ b/src/counters_individual.c
@@ -45,7 +45,7 @@ typedef struct _counter_t *counter_t;
 
 void show_all_counters()
 {
-    for(int i=0; i<nb_counter_option; i++)
+    for(unsigned int i=0; i<nb_counter_option; i++)
         printf("%s\n", perf_static_info[i].name);
 }
 
@@ -67,7 +67,7 @@ void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
     while((token=strtok(perf_string, ",")) != NULL)
         {
             perf_string = NULL;
-            int i;
+            unsigned int i;
             for(i=0; i<nb_counter_option; i++)
                 {
                     if(strcmp(perf_static_info[i].name, token) == 0)
@@ -117,7 +117,7 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
             pe.config = names[i];
             counters->counters[i] = malloc(nbcores*sizeof(int));
 
-            for (int core=0; core<nbcores; core++)
+            for (unsigned int core=0; core<nbcores; core++)
                 {
                     counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
                 }
diff --git a/src/infiniband.c b/src/infiniband.c
index 1f0171b..7c6fff4 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -27,6 +27,7 @@
 #include <stdint.h>
 
 #define NB_SENSOR 4
+#define UNUSED(expr) do { (void)(expr); } while (0)
 
 struct network_t
 {
@@ -77,6 +78,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
+	UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_infiniband[i];
 }
diff --git a/src/rapl.c b/src/rapl.c
index 044a1b7..ab1b38c 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -24,6 +24,8 @@
 
 #include <powercap/powercap-rapl.h>
 
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
 struct _rapl_t
 {
     powercap_rapl_pkg *pkgs;
@@ -52,7 +54,7 @@ const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_COR
 // values [zone + package *nbzones] microjoules
 void _get_rapl(uint64_t *values, _rapl_t *rapl)
 {
-    for (int i = 0; i < rapl->nb; i++)
+    for (unsigned int i = 0; i < rapl->nb; i++)
         {
 #ifdef DEBUG
             int ret =
@@ -68,6 +70,7 @@ void _get_rapl(uint64_t *values, _rapl_t *rapl)
 
 unsigned int init_rapl(char *none, void **ptr)
 {
+	UNUSED(none);
     // get number of processor sockets
     _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
     rapl->nb = 0;
@@ -83,7 +86,7 @@ unsigned int init_rapl(char *none, void **ptr)
             exit(-1);
         }
     rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
-    for (int package = 0; package < rapl->nb_pkgs; package++)
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
         if (powercap_rapl_init(package, &rapl->pkgs[package], 0))
             {
                 perror("powercap_rapl_init, check access (root needed ?)");
@@ -123,7 +126,7 @@ unsigned int init_rapl(char *none, void **ptr)
         }
 #ifdef DEBUG
     printf("Result of init\n");
-    for(int i=0; i<rapl->nb; i++)
+    for(unsigned int i=0; i<rapl->nb; i++)
         printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
 #endif
 
@@ -142,7 +145,7 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 {
     _rapl_t *state = (_rapl_t *) ptr;
     _get_rapl(state->tmp_values, state);
-    for(int i=0; i<state->nb; i++)
+    for(unsigned int i=0; i<state->nb; i++)
         results[i] = state->tmp_values[i] - state->values[i];
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
@@ -155,10 +158,10 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 void clean_rapl(void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
-    for (int package = 0; package < rapl->nb_pkgs; package++)
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
         if (powercap_rapl_destroy(&rapl->pkgs[package]))
             perror("powercap_rapl_destroy");
-    for (int elem=0; elem<rapl->nb; elem++)
+    for (unsigned int elem=0; elem<rapl->nb; elem++)
         free(rapl->names[elem]);
 
     free(rapl->names);
@@ -173,6 +176,6 @@ void clean_rapl(void *ptr)
 void label_rapl(char **labels, void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
-    for(int i=0; i<rapl->nb; i++)
+    for(unsigned int i=0; i<rapl->nb; i++)
         labels[i] = rapl->names[i];
 }
-- 
GitLab


From 12903e30bd1f3911024a4661581782d7f31b06ca Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 9 Jan 2023 07:50:54 +0000
Subject: [PATCH 010/229] feature: builder, python to bash

---
 src/counters_option.sh | 71 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 src/counters_option.sh

diff --git a/src/counters_option.sh b/src/counters_option.sh
new file mode 100644
index 0000000..7d01bb7
--- /dev/null
+++ b/src/counters_option.sh
@@ -0,0 +1,71 @@
+#!/bin/bash
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+linux_include="/usr/include/linux/perf_event.h"
+
+string="#include <linux/perf_event.h>
+
+typedef struct counter_option {
+  char *name;
+  __u32 perf_type;
+  __u64 perf_key;
+} counter_option;
+
+static counter_option perf_static_info[] = {"
+echo "$string"
+
+nb=0
+
+black_list=( "stalled_cycles_frontend" "stalled_cycles_backend" "cache_l1i" "cache_op_write" "cache_result_miss" )
+
+while IFS= read -r line; do
+    if [[ $line == *"perf_hw_id"* ]]; then
+        mode="PERF_TYPE_HARDWARE"
+    elif [[ $line == *"perf_hw_cache_"* ]]; then
+        mode="PERF_TYPE_HW_CACHE"
+    elif [[ $line == *"perf_sw_id"* ]]; then
+        mode="PERF_TYPE_SOFTWARE"
+    elif [[ $line == *"PERF_COUNT_"* && $line == *"="* ]]; then
+        perf_name=$(echo "$line" | awk '{print $1}')
+        short_perf=$(echo "${perf_name:14}" | tr '[:upper:]' '[:lower:]')
+        if [[ " ${black_list[@]} " == *" $short_perf "* ]]; then
+            continue
+        fi
+        if [[ $mode == "PERF_TYPE_HW_CACHE" ]]; then
+			op_id=0
+            for op_id_str in 'r' 'w' 'p'; do
+                op_id_names=("PERF_COUNT_HW_CACHE_OP_READ" "PERF_COUNT_HW_CACHE_OP_WRITE" "PERF_COUNT_HW_CACHE_OP_PREFETCH")
+				result_id=0
+                for result_id_str in 'a' 'm'; do
+                    result_id_names=("PERF_COUNT_HW_CACHE_RESULT_ACCESS" "PERF_COUNT_HW_CACHE_RESULT_MISS")
+
+					printf "{ .name = \"%s_%s_%s\", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },\n" \
+							$short_perf                    														   \
+							$op_id_str                    													       \
+							$result_id_str                  												       \
+							$mode                    														       \
+							$perf_name                      												       \
+							${op_id_names[$op_id]}          												       \
+							${result_id_names[$result_id]}  												     
+
+                    nb=$((nb + 1))
+					((result_id++))
+                done
+				((op_id++))
+            done
+        else
+			printf "{ .name = \"%s\", .perf_type = %s, .perf_key = %s},\n" \
+					$short_perf											   \
+					$mode      									   		   \
+					$perf_name  	
+
+            nb=$((nb + 1))
+        fi
+    fi
+done < "$linux_include"
+
+echo '};'
+
+echo "static unsigned int nb_counter_option = $nb ;"
-- 
GitLab


From 93d0f9764639e2e1735ba7ed896780a54a8129c7 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 10:24:30 +0100
Subject: [PATCH 011/229] Convert counters_option.py to counters_option.sh

The "counters_option.h" generator is now a POSIX shell script. The
intent is to have a more portable script, and, hopefully, one that is
more readable as well.
---
 makefile               |   2 +-
 src/counters_option.py |  62 -----------------------
 src/counters_option.sh | 112 ++++++++++++++++++++++++-----------------
 3 files changed, 66 insertions(+), 110 deletions(-)
 delete mode 100755 src/counters_option.py

diff --git a/makefile b/makefile
index cca83e7..84d6fb5 100644
--- a/makefile
+++ b/makefile
@@ -26,7 +26,7 @@ $(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR
 	$(CC) $(CFLAGS) -c $< -o $@
 
 $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.py
-	python3 ./$(SRC_DIR)/counters_option.py > $(SRC_DIR)/counters_option.h
+	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
 
 $(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
diff --git a/src/counters_option.py b/src/counters_option.py
deleted file mode 100755
index 877a33a..0000000
--- a/src/counters_option.py
+++ /dev/null
@@ -1,62 +0,0 @@
-#! /usr/bin/python3
-
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-linux_include = '/usr/include/linux/perf_event.h'
-
-string = """#include <linux/perf_event.h>
-
-typedef struct counter_option {
-  char *name;
-  __u32 perf_type;
-  __u64 perf_key;
-} counter_option;
-
-static counter_option perf_static_info[] = {"""
-print(string)
-
-nb = 0
-
-black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
-              'cache_l1i', 'cache_op_write', 'cache_result_miss']
-
-with open(linux_include, 'r') as infile:
-    mode = ''
-    for line in infile:
-        if 'perf_hw_id' in line:
-            mode = 'PERF_TYPE_HARDWARE'
-        elif 'perf_hw_cache_' in line:
-            mode = 'PERF_TYPE_HW_CACHE'
-        elif 'perf_sw_id' in line:
-            mode = 'PERF_TYPE_SOFTWARE'
-        elif 'PERF_COUNT_' in line and '=' in line:
-            perf_name = line.split()[0]
-            short_perf = perf_name[14:].lower()
-            if short_perf in black_list:
-                continue
-            if mode == 'PERF_TYPE_HW_CACHE':
-                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
-                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
-                    for result_id, result_id_str in enumerate(['a', 'm']):
-                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
-
-                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
-                            short_perf, op_id_str, result_id_str,
-                            mode,
-                            perf_name,
-                            op_id_names[op_id],
-                            result_id_names[result_id])
-                                                                                     
-                        print(res)
-                        nb += 1
-
-            else:
-                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
-                print(res)
-                nb += 1
-
-
-print('};')
-
-print('static unsigned int nb_counter_option =',nb,';')
diff --git a/src/counters_option.sh b/src/counters_option.sh
index 7d01bb7..1e6a22a 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -3,9 +3,9 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 # Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
 
-linux_include="/usr/include/linux/perf_event.h"
+linux_include=/usr/include/linux/perf_event.h
 
-string="#include <linux/perf_event.h>
+echo '#include <linux/perf_event.h>
 
 typedef struct counter_option {
   char *name;
@@ -13,59 +13,77 @@ typedef struct counter_option {
   __u64 perf_key;
 } counter_option;
 
-static counter_option perf_static_info[] = {"
-echo "$string"
+static counter_option perf_static_info[] = {'
 
 nb=0
 
-black_list=( "stalled_cycles_frontend" "stalled_cycles_backend" "cache_l1i" "cache_op_write" "cache_result_miss" )
+while IFS= read line; do
+	case $line in
+	*perf_hw_id*)
+        mode=PERF_TYPE_HARDWARE
+		;;
+    *perf_hw_cache_*)
+        mode=PERF_TYPE_HW_CACHE
+		;;
+    *perf_sw_id*)
+        mode=PERF_TYPE_SOFTWARE
+		;;
+    *PERF_COUNT_*=*)
+		perf_name=$(echo "$line" | awk '{print $1}')
+		short_perf=$(echo "$perf_name" | sed 's/PERF_COUNT_[HS]W_//' | tr 'A-Z' 'a-z')
+		case $short_perf in
+		# blacklist
+		stalled_cycles_frontend|stalled_cycles_backend|cache_l1i|cache_op_write|cache_result_miss)
+			continue
+			;;
+		esac
 
-while IFS= read -r line; do
-    if [[ $line == *"perf_hw_id"* ]]; then
-        mode="PERF_TYPE_HARDWARE"
-    elif [[ $line == *"perf_hw_cache_"* ]]; then
-        mode="PERF_TYPE_HW_CACHE"
-    elif [[ $line == *"perf_sw_id"* ]]; then
-        mode="PERF_TYPE_SOFTWARE"
-    elif [[ $line == *"PERF_COUNT_"* && $line == *"="* ]]; then
-        perf_name=$(echo "$line" | awk '{print $1}')
-        short_perf=$(echo "${perf_name:14}" | tr '[:upper:]' '[:lower:]')
-        if [[ " ${black_list[@]} " == *" $short_perf "* ]]; then
-            continue
-        fi
-        if [[ $mode == "PERF_TYPE_HW_CACHE" ]]; then
-			op_id=0
-            for op_id_str in 'r' 'w' 'p'; do
-                op_id_names=("PERF_COUNT_HW_CACHE_OP_READ" "PERF_COUNT_HW_CACHE_OP_WRITE" "PERF_COUNT_HW_CACHE_OP_PREFETCH")
-				result_id=0
-                for result_id_str in 'a' 'm'; do
-                    result_id_names=("PERF_COUNT_HW_CACHE_RESULT_ACCESS" "PERF_COUNT_HW_CACHE_RESULT_MISS")
+		if [ "$mode" != 'PERF_TYPE_HW_CACHE' ]; then
+			printf '{ .name = "%s", .perf_type = %s, .perf_key = %s},\n' \
+					"$short_perf" \
+					"$mode" \
+					"$perf_name"
 
-					printf "{ .name = \"%s_%s_%s\", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },\n" \
-							$short_perf                    														   \
-							$op_id_str                    													       \
-							$result_id_str                  												       \
-							$mode                    														       \
-							$perf_name                      												       \
-							${op_id_names[$op_id]}          												       \
-							${result_id_names[$result_id]}  												     
+            : $((nb += 1))
+			continue
+		fi
 
-                    nb=$((nb + 1))
-					((result_id++))
-                done
-				((op_id++))
-            done
-        else
-			printf "{ .name = \"%s\", .perf_type = %s, .perf_key = %s},\n" \
-					$short_perf											   \
-					$mode      									   		   \
-					$perf_name  	
+		# $mode == PERF_TYPE_HW_CACHE
+        for op_id in \
+        	'r PERF_COUNT_HW_CACHE_OP_READ' \
+        	'w PERF_COUNT_HW_CACHE_OP_WRITE' \
+        	'p PERF_COUNT_HW_CACHE_OP_PREFETCH'
+        do
+            op_id_str=${op_id% *}
+            op_id_name=${op_id#* }
+
+            for result_id in \
+            	'a PERF_COUNT_HW_CACHE_RESULT_ACCESS' \
+            	'm PERF_COUNT_HW_CACHE_RESULT_MISS'
+            do
+                result_id_str=${result_id% *}
+                result_id_name=${result_id#* }
 
-            nb=$((nb + 1))
-        fi
-    fi
+            	printf '{'
+            	printf ' .name = "%s_%s_%s",' \
+            		"$short_perf" \
+            		"$op_id_str" \
+            		"$result_id_str"
+            	printf ' .perf_type = %s,' \
+            		"$mode"
+            	printf ' .perf_key = %s | (%s >> 8) | (%s >> 16)' \
+            		"$perf_name" \
+            		"$op_id_name" \
+            		"$result_id_name"
+            	printf ' },\n'
+                : $((nb += 1))
+            done
+        done
+		;;
+	esac
 done < "$linux_include"
 
 echo '};'
 
-echo "static unsigned int nb_counter_option = $nb ;"
+printf 'static unsigned int nb_counter_option = %d;\n' "$nb"
+
-- 
GitLab


From 2a8704563c88a623f549688c6d3fa2e7704ab14b Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 10:28:09 +0100
Subject: [PATCH 012/229] msc: basic reformating

---
 src/frapl.c       |  4 ++--
 src/infiniband.c  |  2 +-
 src/load.c        | 10 +++++-----
 src/mojitos.c     |  4 ++--
 src/network.c     |  2 +-
 src/rapl.c        |  2 +-
 src/temperature.c |  2 +-
 7 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/src/frapl.c b/src/frapl.c
index 1cc0ef9..6048e1d 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -107,7 +107,7 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
 
 unsigned int init_frapl(char *none, void **ptr)
 {
-	UNUSED(none);
+    UNUSED(none);
     _frapl_t *rapl = malloc(sizeof(_frapl_t));
     rapl->nb = 0;
     rapl->names = NULL;
@@ -187,6 +187,6 @@ void clean_frapl(void *ptr)
 void label_frapl(char **labels, void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-	for(unsigned int i=0; i<rapl->nb; i++)
+    for(unsigned int i=0; i<rapl->nb; i++)
         labels[i] = rapl->names[i];
 }
diff --git a/src/infiniband.c b/src/infiniband.c
index 7c6fff4..5f0d1d3 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -78,7 +78,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_infiniband[i];
 }
diff --git a/src/load.c b/src/load.c
index 33ebdbf..c6ff82a 100644
--- a/src/load.c
+++ b/src/load.c
@@ -54,8 +54,8 @@ void _get_load(uint64_t *results)
 
 unsigned int init_load(char *argument, void **state)
 {
-	UNUSED(argument);
-	UNUSED(state);
+    UNUSED(argument);
+    UNUSED(state);
     load_fid = open(stat, O_RDONLY);
     if (load_fid < 0)
         {
@@ -69,7 +69,7 @@ unsigned int init_load(char *argument, void **state)
 
 unsigned int get_load(uint64_t *results, void *state)
 {
-	UNUSED(state);
+    UNUSED(state);
     _get_load(tmp_load_values);
     for(int i=0; i<10; i++)
         results[i] = tmp_load_values[i] - load_values[i];
@@ -80,7 +80,7 @@ unsigned int get_load(uint64_t *results, void *state)
 
 void clean_load(void *state)
 {
-	UNUSED(state);
+    UNUSED(state);
     close(load_fid);
 }
 
@@ -89,7 +89,7 @@ char *_labels[10] = {"user","nice","system","idle","iowait","irq",
                     };
 void label_load(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<10; i++)
         labels[i] = _labels[i];
 }
diff --git a/src/mojitos.c b/src/mojitos.c
index ed6b462..fe56307 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -57,12 +57,12 @@ void usage(char **argv)
 
 void sighandler(int none)
 {
-	UNUSED(none);
+    UNUSED(none);
 }
 
 void flush(int none)
 {
-	UNUSED(none);
+    UNUSED(none);
     exit(0);
 }
 
diff --git a/src/network.c b/src/network.c
index d9575af..f5dc7d2 100644
--- a/src/network.c
+++ b/src/network.c
@@ -129,7 +129,7 @@ void clean_network(void *ptr)
 char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
 void label_network(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_network[i];
 }
diff --git a/src/rapl.c b/src/rapl.c
index ab1b38c..bb0a26f 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -70,7 +70,7 @@ void _get_rapl(uint64_t *values, _rapl_t *rapl)
 
 unsigned int init_rapl(char *none, void **ptr)
 {
-	UNUSED(none);
+    UNUSED(none);
     // get number of processor sockets
     _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
     rapl->nb = 0;
diff --git a/src/temperature.c b/src/temperature.c
index e210f7b..6868efb 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -102,7 +102,7 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 
 unsigned int init_temperature(char *args, void **ptr)
 {
-	UNUSED(args);
+    UNUSED(args);
     struct temperature_t *state = malloc(sizeof(struct temperature_t));
     state->nb_elem = 0;
     state->label_list = NULL;
-- 
GitLab


From 1f9e3275176f35d0636011ee4f5f060c622a5b7f Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 10:30:46 +0100
Subject: [PATCH 013/229] Correcting shebang on src/counters_option.sh

---
 src/counters_option.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/counters_option.sh b/src/counters_option.sh
index 1e6a22a..5d1e577 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 # SPDX-License-Identifier: GPL-3.0-or-later
 # Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-- 
GitLab


From 97d53cb266c74b98f8cbd88fb7970de993dcdd72 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 9 Jan 2023 11:42:31 +0000
Subject: [PATCH 014/229] close #2: add PANIC macro

---
 src/mojitos.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/src/mojitos.c b/src/mojitos.c
index ed6b462..b205baa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -34,6 +34,14 @@
 #include "temperature.h"
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
+#define PANIC(code, fmt, ...)  				 \
+	do {									 \
+		fprintf(stderr, "Exit on error: ");  \
+		fprintf(stderr, fmt, ##__VA_ARGS__); \
+		fprintf(stderr, "\n"); 			     \
+		exit(code); 						 \
+	} while (0)
+
 
 void usage(char **argv)
 {
@@ -136,9 +144,11 @@ int main(int argc, char **argv)
         switch (c)
             {
             case 'f':
+				if (optind >= argc) PANIC(1,"-f, no frequency provided");
                 frequency = atoi(argv[optind]);
                 break;
             case 't':
+				if (optind >= argc) PANIC(1,"-t, no time provided");
                 total_time = atoi(argv[optind]);
                 delta = 1;
                 if (total_time == 0)
@@ -154,6 +164,7 @@ int main(int argc, char **argv)
                 add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
                 break;
             case 'o':
+				if (optind >= argc) PANIC(1,"-o, no logfile provided");
                 output = fopen(argv[optind], "wb");
                 break;
             case 'e':
@@ -161,6 +172,7 @@ int main(int argc, char **argv)
                 signal(17, sighandler);
                 break;
             case 'p':
+				if (optind >= argc) PANIC(1,"-p, no counter provided");
                 add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
                 break;
             case 'r':
-- 
GitLab


From edb624615b580fbf43ed66b017df7e16af7ba942 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 9 Jan 2023 12:39:04 +0000
Subject: [PATCH 015/229] fix: -o

---
 src/mojitos.c | 26 +++++++++++++++++---------
 1 file changed, 17 insertions(+), 9 deletions(-)

diff --git a/src/mojitos.c b/src/mojitos.c
index b205baa..b5e6748 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -1,4 +1,5 @@
 /*******************************************************
+
  Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
@@ -65,20 +66,23 @@ void usage(char **argv)
 
 void sighandler(int none)
 {
-	UNUSED(none);
+    UNUSED(none);
 }
 
 void flush(int none)
 {
-	UNUSED(none);
+    UNUSED(none);
     exit(0);
 }
 
 FILE *output;
 void flushexit()
 {
-    fflush(output);
-    fclose(output);
+    if (output != NULL)
+        {
+            fflush(output);
+            fclose(output);
+        }
 }
 
 typedef unsigned int (initializer_t)(char *, void **);
@@ -144,11 +148,11 @@ int main(int argc, char **argv)
         switch (c)
             {
             case 'f':
-				if (optind >= argc) PANIC(1,"-f, no frequency provided");
+                if (optind >= argc) PANIC(1,"-f, no frequency provided");
                 frequency = atoi(argv[optind]);
                 break;
             case 't':
-				if (optind >= argc) PANIC(1,"-t, no time provided");
+                if (optind >= argc) PANIC(1,"-t, no time provided");
                 total_time = atoi(argv[optind]);
                 delta = 1;
                 if (total_time == 0)
@@ -164,15 +168,19 @@ int main(int argc, char **argv)
                 add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
                 break;
             case 'o':
-				if (optind >= argc) PANIC(1,"-o, no logfile provided");
-                output = fopen(argv[optind], "wb");
+                if (optind >= argc) PANIC(1,"-o, no logfile provided");
+                if ((output = fopen(argv[optind], "wb")) == NULL)
+                    {
+                        perror("fopen");
+                        PANIC(1, "-o %s", argv[optind]);
+                    }
                 break;
             case 'e':
                 application = &argv[optind];
                 signal(17, sighandler);
                 break;
             case 'p':
-				if (optind >= argc) PANIC(1,"-p, no counter provided");
+                if (optind >= argc) PANIC(1,"-p, no counter provided");
                 add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
                 break;
             case 'r':
-- 
GitLab


From a0e916eb8ada2141e32225a1a9a80445d2125652 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 16 Jan 2023 09:41:47 +0000
Subject: [PATCH 016/229] Style update

---
 makefile                  |   2 +-
 src/counters_group.c      |  59 ++++----
 src/counters_individual.c | 111 +++++++--------
 src/frapl.c               | 102 ++++++--------
 src/infiniband.c          |  29 ++--
 src/load.c                |  41 +++---
 src/mojitos.c             | 290 +++++++++++++++++---------------------
 src/network.c             |  71 +++++-----
 src/rapl.c                |  81 +++++------
 src/temperature.c         |  97 ++++++-------
 10 files changed, 399 insertions(+), 484 deletions(-)

diff --git a/makefile b/makefile
index cca83e7..bf7d070 100644
--- a/makefile
+++ b/makefile
@@ -10,7 +10,7 @@ OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 CC = gcc
 CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
 
-ASTYLE = astyle --style=gnu -xf -s4 -k3 -n -Z -Q
+ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
 # depending on the context it may need to be changed to all: mojitos mojitos_group
diff --git a/src/counters_group.c b/src/counters_group.c
index 0154a94..000e67a 100644
--- a/src/counters_group.c
+++ b/src/counters_group.c
@@ -29,8 +29,7 @@
 
 #include "counters.h"
 
-struct _counter_t
-{
+struct _counter_t {
     int nbcores;
     int nbperf;
     int *counters;
@@ -40,12 +39,11 @@ static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                             int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-    if (res == -1)
-        {
-            perror("perf_event_open");
-            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-            exit(EXIT_FAILURE);
-        }
+    if (res == -1) {
+        perror("perf_event_open");
+        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+        exit(EXIT_FAILURE);
+    }
     return res;
 }
 
@@ -64,18 +62,16 @@ counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *name
     pe.read_format = PERF_FORMAT_GROUP;
     counters->counters = malloc((nbcores+1)*sizeof(int));
 
-    for (int core=0; core<nbcores; core++)
-        {
-            counters->counters[core]=-1;
-            for(int idperf=0; idperf<nb_perf; idperf ++)
-                {
-                    pe.type = types[idperf];
-                    pe.config = names[idperf];
-                    int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-                    if(counters->counters[core]==-1)
-                        counters->counters[core]=res;
-                }
+    for (int core=0; core<nbcores; core++) {
+        counters->counters[core]=-1;
+        for(int idperf=0; idperf<nb_perf; idperf ++) {
+            pe.type = types[idperf];
+            pe.config = names[idperf];
+            int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
+            if(counters->counters[core]==-1)
+                counters->counters[core]=res;
         }
+    }
     return counters;
 }
 
@@ -98,11 +94,9 @@ void reset_counters(counter_t counters)
         ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
 }
 
-struct read_format
-{
+struct read_format {
     uint64_t nr;
-    struct
-    {
+    struct {
         uint64_t value;
     } values[];
 };
@@ -117,17 +111,14 @@ void get_counters(counter_t counters, long long *values)
 
     memset(values, 0, nb_perf*sizeof(long long));
 
-    for (int core=0; core<counters->nbcores; core++)
-        {
-            if (-1 == read(counters->counters[core], buffer, buffer_size))
-                {
-                    perror("PB Lecture resultat");
-                    exit(EXIT_FAILURE);
-                }
-            for(int idperf=0; idperf<=nb_perf; idperf++)
-                {
-                    values[idperf] += buffer->values[idperf].value;
-                }
+    for (int core=0; core<counters->nbcores; core++) {
+        if (-1 == read(counters->counters[core], buffer, buffer_size)) {
+            perror("PB Lecture resultat");
+            exit(EXIT_FAILURE);
+        }
+        for(int idperf=0; idperf<=nb_perf; idperf++) {
+            values[idperf] += buffer->values[idperf].value;
         }
+    }
     reset_counters(counters);
 }
diff --git a/src/counters_individual.c b/src/counters_individual.c
index 0f597ad..5a24eed 100644
--- a/src/counters_individual.c
+++ b/src/counters_individual.c
@@ -28,8 +28,7 @@
 #include <asm/unistd.h>
 #include <stdint.h>
 
-struct _counter_t
-{
+struct _counter_t {
     int nbcores;
     int nbperf;
     int **counters;
@@ -53,49 +52,43 @@ void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
 {
     *perf_type = malloc(nb*sizeof(__u32));
     *perf_key  = malloc(nb*sizeof(__u64));
-    for(int i=0; i<nb; i++)
-        {
-            (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
-            (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
-        }
+    for(int i=0; i<nb; i++) {
+        (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
+        (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
+    }
 }
 void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
 {
     char *token;
     *nb_perf=0;
     *perf_indexes=NULL;
-    while((token=strtok(perf_string, ",")) != NULL)
-        {
-            perf_string = NULL;
-            unsigned int i;
-            for(i=0; i<nb_counter_option; i++)
-                {
-                    if(strcmp(perf_static_info[i].name, token) == 0)
-                        {
-                            (*nb_perf)++;
-                            (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-                            (*perf_indexes)[*nb_perf-1]=i;
-                            break;
-                        }
-                }
-            if(i == nb_counter_option)
-                {
-                    fprintf(stderr, "Unknown performance counter: %s\n", token);
-                    exit(EXIT_FAILURE);
-                }
+    while((token=strtok(perf_string, ",")) != NULL) {
+        perf_string = NULL;
+        unsigned int i;
+        for(i=0; i<nb_counter_option; i++) {
+            if(strcmp(perf_static_info[i].name, token) == 0) {
+                (*nb_perf)++;
+                (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
+                (*perf_indexes)[*nb_perf-1]=i;
+                break;
+            }
         }
+        if(i == nb_counter_option) {
+            fprintf(stderr, "Unknown performance counter: %s\n", token);
+            exit(EXIT_FAILURE);
+        }
+    }
 }
 
 static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                             int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-    if (res == -1)
-        {
-            perror("perf_event_open");
-            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-            exit(EXIT_FAILURE);
-        }
+    if (res == -1) {
+        perror("perf_event_open");
+        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+        exit(EXIT_FAILURE);
+    }
     return res;
 }
 
@@ -111,29 +104,26 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
     counters->nbperf = nb_perf;
     counters->nbcores=nbcores;
     counters->counters=malloc(nb_perf*sizeof(int *));
-    for (int i=0; i<nb_perf; i++)
-        {
-            pe.type = types[i];
-            pe.config = names[i];
-            counters->counters[i] = malloc(nbcores*sizeof(int));
-
-            for (unsigned int core=0; core<nbcores; core++)
-                {
-                    counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
-                }
+    for (int i=0; i<nb_perf; i++) {
+        pe.type = types[i];
+        pe.config = names[i];
+        counters->counters[i] = malloc(nbcores*sizeof(int));
+
+        for (unsigned int core=0; core<nbcores; core++) {
+            counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
         }
+    }
     return counters;
 }
 
 void clean_counters(void *ptr)
 {
     counter_t counters = (counter_t) ptr;
-    for(int counter=0; counter<counters->nbperf; counter++)
-        {
-            for(int core=0; core<counters->nbcores; core++)
-                close(counters->counters[counter][core]);
-            free(counters->counters[counter]);
-        }
+    for(int counter=0; counter<counters->nbperf; counter++) {
+        for(int core=0; core<counters->nbcores; core++)
+            close(counters->counters[counter][core]);
+        free(counters->counters[counter]);
+    }
     free(counters->counters);
     free(counters->counters_values);
     free(counters->tmp_counters_values);
@@ -158,21 +148,18 @@ void reset_counters(counter_t counters)
 
 void _get_counters(counter_t counters, uint64_t *values)
 {
-    for(int i=0; i<counters->nbperf; i++)
-        {
-            uint64_t accu=0;
-            uint64_t count=0;
-            for (int core=0; core<counters->nbcores; core++)
-                {
-                    if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t)))
-                        {
-                            fprintf(stderr, "Cannot read result");
-                            exit(EXIT_FAILURE);
-                        }
-                    accu += count;
-                }
-            values[i] = accu;
+    for(int i=0; i<counters->nbperf; i++) {
+        uint64_t accu=0;
+        uint64_t count=0;
+        for (int core=0; core<counters->nbcores; core++) {
+            if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
+                fprintf(stderr, "Cannot read result");
+                exit(EXIT_FAILURE);
+            }
+            accu += count;
         }
+        values[i] = accu;
+    }
 }
 
 
diff --git a/src/frapl.c b/src/frapl.c
index 1cc0ef9..9874a12 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -34,10 +34,9 @@
 char *get_frapl_string(const char *filename)
 {
     int fd = open(filename, O_RDONLY);
-    if( fd == -1)
-        {
-            return NULL;
-        }
+    if( fd == -1) {
+        return NULL;
+    }
     char *result = malloc(MAX_HEADER);
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
@@ -54,8 +53,7 @@ void test_append(char *name, int i)
 }
 
 
-struct _frapl_t
-{
+struct _frapl_t {
     unsigned int nb;
     char **names;
     int *fids;
@@ -78,12 +76,11 @@ void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
 
     int fd = open(energy_uj, O_RDONLY);
 
-    if (fd < 0)
-        {
-            fprintf(stderr, "%s ", energy_uj);
-            perror("open");
-            exit(1);
-        }
+    if (fd < 0) {
+        fprintf(stderr, "%s ", energy_uj);
+        perror("open");
+        exit(1);
+    }
     rapl->fids[rapl->nb-1] = fd;
 }
 
@@ -92,22 +89,20 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
 {
     static char buffer[512];
 
-    for (unsigned int i = 0; i < rapl->nb; i++)
-        {
+    for (unsigned int i = 0; i < rapl->nb; i++) {
 
-            if (pread(rapl->fids[i], buffer, 100, 0) < 0)
-                {
-                    perror("pread");
-                    exit(1);
-                }
-            values[i] = strtoull(buffer, NULL, 10);
+        if (pread(rapl->fids[i], buffer, 100, 0) < 0) {
+            perror("pread");
+            exit(1);
         }
+        values[i] = strtoull(buffer, NULL, 10);
+    }
 }
 
 
 unsigned int init_frapl(char *none, void **ptr)
 {
-	UNUSED(none);
+    UNUSED(none);
     _frapl_t *rapl = malloc(sizeof(_frapl_t));
     rapl->nb = 0;
     rapl->names = NULL;
@@ -117,35 +112,33 @@ unsigned int init_frapl(char *none, void **ptr)
     char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
     char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-    for (unsigned int i=0;; i++)
-        {
-            sprintf(buffer, name_base, i, "name");
-            char *tmp = get_frapl_string(buffer);
-            if (tmp == NULL) break;
-            //printf("%s\n", tmp);
-            test_append(tmp, i);
-            //printf("%s -> %s\n", buffer, tmp);
-
-            sprintf(buffer, name_base, i, "energy_uj");
-            add_frapl_source(rapl, tmp, buffer);
-            free(tmp);
-
-            for (unsigned int j=0;; j++)
-                {
-                    sprintf(buffer, name_sub, i, i, j, "name");
-                    char *tmp_sub = get_frapl_string(buffer);
-                    if (tmp_sub == NULL) break;
-                    //printf("%s\n", tmp_sub);
-                    test_append(tmp_sub, i);
-                    //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-                    sprintf(buffer, name_sub, i, i, j, "energy_uj");
-                    add_frapl_source(rapl, tmp_sub, buffer);
-
-                    free(tmp_sub);
-                }
+    for (unsigned int i=0;; i++) {
+        sprintf(buffer, name_base, i, "name");
+        char *tmp = get_frapl_string(buffer);
+        if (tmp == NULL) break;
+        //printf("%s\n", tmp);
+        test_append(tmp, i);
+        //printf("%s -> %s\n", buffer, tmp);
+
+        sprintf(buffer, name_base, i, "energy_uj");
+        add_frapl_source(rapl, tmp, buffer);
+        free(tmp);
+
+        for (unsigned int j=0;; j++) {
+            sprintf(buffer, name_sub, i, i, j, "name");
+            char *tmp_sub = get_frapl_string(buffer);
+            if (tmp_sub == NULL) break;
+            //printf("%s\n", tmp_sub);
+            test_append(tmp_sub, i);
+            //printf("%s -> %s\n", buffer, tmp_sub);
+
+
+            sprintf(buffer, name_sub, i, i, j, "energy_uj");
+            add_frapl_source(rapl, tmp_sub, buffer);
+
+            free(tmp_sub);
         }
+    }
 
     rapl->values = calloc(sizeof(uint64_t), rapl->nb);
     rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
@@ -171,11 +164,10 @@ unsigned int get_frapl(uint64_t *results, void *ptr)
 void clean_frapl(void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        {
-            free(rapl->names[i]);
-            close(rapl->fids[i]);
-        }
+    for(unsigned int i=0; i<rapl->nb; i++) {
+        free(rapl->names[i]);
+        close(rapl->fids[i]);
+    }
     free(rapl->names);
     free(rapl->fids);
     free(rapl->values);
@@ -187,6 +179,6 @@ void clean_frapl(void *ptr)
 void label_frapl(char **labels, void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-	for(unsigned int i=0; i<rapl->nb; i++)
+    for(unsigned int i=0; i<rapl->nb; i++)
         labels[i] = rapl->names[i];
 }
diff --git a/src/infiniband.c b/src/infiniband.c
index 7c6fff4..6621759 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -29,8 +29,7 @@
 #define NB_SENSOR 4
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
-struct network_t
-{
+struct network_t {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
@@ -43,16 +42,15 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     if(infi_path==NULL)
         return 0;
 
-    if(strcmp(infi_path,"X")==0)
-        {
+    if(strcmp(infi_path,"X")==0) {
 
-            glob_t res;
+        glob_t res;
 
-            glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
-            if(res.gl_pathc == 0)
-                return 0;
-            infi_path = res.gl_pathv[0];
-        }
+        glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
+        if(res.gl_pathc == 0)
+            return 0;
+        infi_path = res.gl_pathv[0];
+    }
 
     char *filenames[] = {"%s/port_rcv_packets",
                          "%s/port_rcv_data",
@@ -63,11 +61,10 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer[1024];
-    for(int i=0; i<NB_SENSOR; i++)
-        {
-            sprintf(buffer, filenames[i], infi_path);
-            state->sources[i] = open(buffer, O_RDONLY);
-        }
+    for(int i=0; i<NB_SENSOR; i++) {
+        sprintf(buffer, filenames[i], infi_path);
+        state->sources[i] = open(buffer, O_RDONLY);
+    }
 
     *ptr = (void *) state;
     _get_network(state->values, state->sources);
@@ -78,7 +75,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_infiniband[i];
 }
diff --git a/src/load.c b/src/load.c
index 33ebdbf..4f11346 100644
--- a/src/load.c
+++ b/src/load.c
@@ -35,41 +35,38 @@ static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
 {
-    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0)
-        {
-            perror("pread");
-            exit(1);
-        }
+    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0) {
+        perror("pread");
+        exit(1);
+    }
     int pos=0;
     while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
-    for(int i=0; i<10; i++)
-        {
-            results[i] = strtoull(buffer+pos, NULL, 10);
-            while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
-            pos++;
-        }
+    for(int i=0; i<10; i++) {
+        results[i] = strtoull(buffer+pos, NULL, 10);
+        while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
+        pos++;
+    }
 }
 
 // Public interface
 
 unsigned int init_load(char *argument, void **state)
 {
-	UNUSED(argument);
-	UNUSED(state);
+    UNUSED(argument);
+    UNUSED(state);
     load_fid = open(stat, O_RDONLY);
-    if (load_fid < 0)
-        {
-            fprintf(stderr,"%s ",stat);
-            perror("open");
-            exit(1);
-        }
+    if (load_fid < 0) {
+        fprintf(stderr,"%s ",stat);
+        perror("open");
+        exit(1);
+    }
     _get_load(load_values);
     return 10;
 }
 
 unsigned int get_load(uint64_t *results, void *state)
 {
-	UNUSED(state);
+    UNUSED(state);
     _get_load(tmp_load_values);
     for(int i=0; i<10; i++)
         results[i] = tmp_load_values[i] - load_values[i];
@@ -80,7 +77,7 @@ unsigned int get_load(uint64_t *results, void *state)
 
 void clean_load(void *state)
 {
-	UNUSED(state);
+    UNUSED(state);
     close(load_fid);
 }
 
@@ -89,7 +86,7 @@ char *_labels[10] = {"user","nice","system","idle","iowait","irq",
                     };
 void label_load(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<10; i++)
         labels[i] = _labels[i];
 }
diff --git a/src/mojitos.c b/src/mojitos.c
index b5e6748..3569d1b 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -78,11 +78,10 @@ void flush(int none)
 FILE *output;
 void flushexit()
 {
-    if (output != NULL)
-        {
-            fflush(output);
-            fclose(output);
-        }
+    if (output != NULL) {
+        fflush(output);
+        fclose(output);
+    }
 }
 
 typedef unsigned int (initializer_t)(char *, void **);
@@ -105,12 +104,11 @@ void add_source(initializer_t init, char *arg, labeler_t labeler,
     nb_sources++;
     states = realloc(states, nb_sources * sizeof(void *));
     int nb = init(arg, &states[nb_sources - 1]);
-    if (nb == 0)
-        {
-            nb_sources--;
-            states = realloc(states, nb_sources * sizeof(void *));
-            return;
-        }
+    if (nb == 0) {
+        nb_sources--;
+        states = realloc(states, nb_sources * sizeof(void *));
+        return;
+    }
 
     getter = realloc(getter, nb_sources * sizeof(void *));
     getter[nb_sources - 1] = get;
@@ -133,10 +131,9 @@ int main(int argc, char **argv)
 
     int stat_mode = -1;
 
-    if (argc == 1)
-        {
-            usage(argv);
-        }
+    if (argc == 1) {
+        usage(argv);
+    }
 
     output = stdout;
 
@@ -145,65 +142,62 @@ int main(int argc, char **argv)
 
     int c;
     while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL)
-        switch (c)
-            {
-            case 'f':
-                if (optind >= argc) PANIC(1,"-f, no frequency provided");
-                frequency = atoi(argv[optind]);
-                break;
-            case 't':
-                if (optind >= argc) PANIC(1,"-t, no time provided");
-                total_time = atoi(argv[optind]);
-                delta = 1;
-                if (total_time == 0)
-                    {
-                        total_time = 1;
-                        delta = 0;
-                    }
-                break;
-            case 'd':
-                add_source(init_network, argv[optind], label_network, get_network, clean_network);
-                break;
-            case 'i':
-                add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
-                break;
-            case 'o':
-                if (optind >= argc) PANIC(1,"-o, no logfile provided");
-                if ((output = fopen(argv[optind], "wb")) == NULL)
-                    {
-                        perror("fopen");
-                        PANIC(1, "-o %s", argv[optind]);
-                    }
-                break;
-            case 'e':
-                application = &argv[optind];
-                signal(17, sighandler);
-                break;
-            case 'p':
-                if (optind >= argc) PANIC(1,"-p, no counter provided");
-                add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
-                break;
-            case 'r':
-                add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
-                break;
-            case 'R':
-                add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
-                break;
-            case 'u':
-                add_source(init_load, NULL, label_load, get_load, clean_load);
-                break;
-            case 'c':
-                add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
-                break;
-            case 's':
-                stat_mode = 0;
-                break;
-            case 'l':
-                show_all_counters();
-                exit(EXIT_SUCCESS);
-            default:
-                usage(argv);
+        switch (c) {
+        case 'f':
+            if (optind >= argc) PANIC(1,"-f, no frequency provided");
+            frequency = atoi(argv[optind]);
+            break;
+        case 't':
+            if (optind >= argc) PANIC(1,"-t, no time provided");
+            total_time = atoi(argv[optind]);
+            delta = 1;
+            if (total_time == 0) {
+                total_time = 1;
+                delta = 0;
             }
+            break;
+        case 'd':
+            add_source(init_network, argv[optind], label_network, get_network, clean_network);
+            break;
+        case 'i':
+            add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
+            break;
+        case 'o':
+            if (optind >= argc) PANIC(1,"-o, no logfile provided");
+            if ((output = fopen(argv[optind], "wb")) == NULL) {
+                perror("fopen");
+                PANIC(1, "-o %s", argv[optind]);
+            }
+            break;
+        case 'e':
+            application = &argv[optind];
+            signal(17, sighandler);
+            break;
+        case 'p':
+            if (optind >= argc) PANIC(1,"-p, no counter provided");
+            add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
+            break;
+        case 'r':
+            add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
+            break;
+        case 'R':
+            add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
+            break;
+        case 'u':
+            add_source(init_load, NULL, label_load, get_load, clean_load);
+            break;
+        case 'c':
+            add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
+            break;
+        case 's':
+            stat_mode = 0;
+            break;
+        case 'l':
+            show_all_counters();
+            exit(EXIT_SUCCESS);
+        default:
+            usage(argv);
+        }
 
 
     setvbuf(output, NULL, _IONBF, BUFSIZ);
@@ -212,109 +206,89 @@ int main(int argc, char **argv)
 
     fprintf(output, "#timestamp ");
 
-    for (unsigned int i = 0; i < nb_sensors; i++)
-        {
-            fprintf(output, "%s ", labels[i]);
-        }
+    for (unsigned int i = 0; i < nb_sensors; i++) {
+        fprintf(output, "%s ", labels[i]);
+    }
 
-    if (stat_mode == 0)
-        {
-            fprintf(output, "overhead ");
-        }
+    if (stat_mode == 0) {
+        fprintf(output, "overhead ");
+    }
 
     fprintf(output, "\n");
 
     unsigned long int stat_data = 0;
 
-    for (int temps = 0; temps < total_time * frequency; temps += delta)
-        {
-            clock_gettime(CLOCK_MONOTONIC, &ts_ref);
+    for (int temps = 0; temps < total_time * frequency; temps += delta) {
+        clock_gettime(CLOCK_MONOTONIC, &ts_ref);
 
-            // Get Data
-            unsigned int current = 0;
-            for (unsigned int i = 0; i < nb_sources; i++)
-                {
-                    current += getter[i](&values[current], states[i]);
-                }
+        // Get Data
+        unsigned int current = 0;
+        for (unsigned int i = 0; i < nb_sources; i++) {
+            current += getter[i](&values[current], states[i]);
+        }
 
-            if (application != NULL)
-                {
-
-                    if (fork() == 0)
-                        {
-                            execvp(application[0], application);
-                            exit(0);
-                        }
-                    pause();
-                    clock_gettime(CLOCK_MONOTONIC, &ts);
-                    if (ts.tv_nsec >= ts_ref.tv_nsec)
-                        {
-                            fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
-                        }
-                    else
-                        {
-                            fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
-                        }
-                }
-            else
-                {
+        if (application != NULL) {
+
+            if (fork() == 0) {
+                execvp(application[0], application);
+                exit(0);
+            }
+            pause();
+            clock_gettime(CLOCK_MONOTONIC, &ts);
+            if (ts.tv_nsec >= ts_ref.tv_nsec) {
+                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
+            } else {
+                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
+            }
+        } else {
 #ifdef DEBUG
-                    clock_gettime(CLOCK_MONOTONIC, &ts);
-                    fprintf(stderr, "%ld\n", (ts.tv_nsec - ts_ref.tv_nsec) / 1000);
-                    //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
-                    //Group: mean: 309 std: 41 % med: 297 std: 39 %
+            clock_gettime(CLOCK_MONOTONIC, &ts);
+            fprintf(stderr, "%ld\n", (ts.tv_nsec - ts_ref.tv_nsec) / 1000);
+            //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
+            //Group: mean: 309 std: 41 % med: 297 std: 39 %
 #endif
-                    if (stat_mode == 0)
-                        {
-                            clock_gettime(CLOCK_MONOTONIC, &ts);
-                            if (ts.tv_nsec >= ts_ref.tv_nsec)
-                                {
-                                    stat_data = ts.tv_nsec - ts_ref.tv_nsec;
-                                }
-                            else
-                                {
-                                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
-                                }
-                        }
-
-                    // Treat Data
-                    fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
-                }
-
-            for (unsigned int i = 0; i < nb_sensors; i++)
-                {
-                    fprintf(output, "%" PRIu64 " ", values[i]);
-                }
-
-            if (stat_mode == 0)
-                {
-                    fprintf(output, "%ld ", stat_data);
+            if (stat_mode == 0) {
+                clock_gettime(CLOCK_MONOTONIC, &ts);
+                if (ts.tv_nsec >= ts_ref.tv_nsec) {
+                    stat_data = ts.tv_nsec - ts_ref.tv_nsec;
+                } else {
+                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
                 }
+            }
 
-            fprintf(output, "\n");
-
-            if (application != NULL)
-                {
-                    break;
-                }
+            // Treat Data
+            fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
+        }
 
-            clock_gettime(CLOCK_MONOTONIC, &ts);
-            usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
+        for (unsigned int i = 0; i < nb_sensors; i++) {
+            fprintf(output, "%" PRIu64 " ", values[i]);
         }
 
-    for (unsigned int i = 0; i < nb_sources; i++)
-        {
-            cleaner[i](states[i]);
+        if (stat_mode == 0) {
+            fprintf(output, "%ld ", stat_data);
         }
 
-    if (nb_sources > 0)
-        {
-            free(getter);
-            free(cleaner);
-            free(labels);
-            free(values);
-            free(states);
+        fprintf(output, "\n");
+
+        if (application != NULL) {
+            break;
         }
+
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
+    }
+
+    for (unsigned int i = 0; i < nb_sources; i++) {
+        cleaner[i](states[i]);
+    }
+
+    if (nb_sources > 0) {
+        free(getter);
+        free(cleaner);
+        free(labels);
+        free(values);
+        free(states);
+    }
 }
 
 
diff --git a/src/network.c b/src/network.c
index d9575af..647b4b3 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,8 +28,7 @@
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
 static char *route = "/proc/net/route";
-struct network_t
-{
+struct network_t {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
@@ -40,16 +39,14 @@ unsigned int _get_network(uint64_t *results, int *sources)
     if(sources==NULL)
         return 0;
     char buffer[128];
-    for(int i=0; i<NB_SENSOR; i++)
-        {
-            if (pread(sources[i], buffer, 127, 0) < 0)
-                {
-                    perror("pread");
-                    exit(1);
-                }
-
-            results[i] = strtoull(buffer, NULL, 10);
+    for(int i=0; i<NB_SENSOR; i++) {
+        if (pread(sources[i], buffer, 127, 0) < 0) {
+            perror("pread");
+            exit(1);
         }
+
+        results[i] = strtoull(buffer, NULL, 10);
+    }
     return NB_SENSOR;
 }
 
@@ -60,31 +57,28 @@ unsigned int init_network(char *dev, void **ptr)
     if(dev==NULL)
         return 0;
 
-    if(strcmp(dev,"X")==0)
-        {
-            int fd = open(route, O_RDONLY);
-            if (fd < 0)
-                {
-                    fprintf(stderr, "%s ", route);
-                    perror("open");
-                    exit(1);
-                }
-            char buffer[1000];
-
-            if ( read(fd, buffer, 999) < 0 )
-                {
-                    perror("read");
-                    close(fd);
-                    exit(1);
-                }
-
-            char *start_of_dev = index(buffer, '\n')+1;
-            char *end_of_dev = index(start_of_dev, '\t');
-            *end_of_dev='\0';
-            dev = start_of_dev;
+    if(strcmp(dev,"X")==0) {
+        int fd = open(route, O_RDONLY);
+        if (fd < 0) {
+            fprintf(stderr, "%s ", route);
+            perror("open");
+            exit(1);
+        }
+        char buffer[1000];
+
+        if ( read(fd, buffer, 999) < 0 ) {
+            perror("read");
             close(fd);
+            exit(1);
         }
 
+        char *start_of_dev = index(buffer, '\n')+1;
+        char *end_of_dev = index(start_of_dev, '\t');
+        *end_of_dev='\0';
+        dev = start_of_dev;
+        close(fd);
+    }
+
     char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
                          "/sys/class/net/%s/statistics/rx_bytes",
                          "/sys/class/net/%s/statistics/tx_packets",
@@ -94,11 +88,10 @@ unsigned int init_network(char *dev, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer2[256];
-    for(int i=0; i<NB_SENSOR; i++)
-        {
-            sprintf(buffer2, filenames[i], dev);
-            state->sources[i] = open(buffer2, O_RDONLY);
-        }
+    for(int i=0; i<NB_SENSOR; i++) {
+        sprintf(buffer2, filenames[i], dev);
+        state->sources[i] = open(buffer2, O_RDONLY);
+    }
     *ptr = (void *) state;
     _get_network(state->values, state->sources);
 
@@ -129,7 +122,7 @@ void clean_network(void *ptr)
 char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
 void label_network(char **labels, void *none)
 {
-	UNUSED(none);
+    UNUSED(none);
     for(int i=0; i<NB_SENSOR; i++)
         labels[i] = _labels_network[i];
 }
diff --git a/src/rapl.c b/src/rapl.c
index ab1b38c..30d38c1 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -26,8 +26,7 @@
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
-struct _rapl_t
-{
+struct _rapl_t {
     powercap_rapl_pkg *pkgs;
     uint32_t nb_pkgs;
     uint32_t nb;
@@ -54,23 +53,22 @@ const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_COR
 // values [zone + package *nbzones] microjoules
 void _get_rapl(uint64_t *values, _rapl_t *rapl)
 {
-    for (unsigned int i = 0; i < rapl->nb; i++)
-        {
+    for (unsigned int i = 0; i < rapl->nb; i++) {
 #ifdef DEBUG
-            int ret =
+        int ret =
 #endif
-                powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
-                                            rapl->zones[i],
-                                            &values[i]);
+            powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
+                                        rapl->zones[i],
+                                        &values[i]);
 #ifdef DEBUG
-            printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
+        printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
 #endif
-        }
+    }
 }
 
 unsigned int init_rapl(char *none, void **ptr)
 {
-	UNUSED(none);
+    UNUSED(none);
     // get number of processor sockets
     _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
     rapl->nb = 0;
@@ -80,50 +78,45 @@ unsigned int init_rapl(char *none, void **ptr)
     rapl->nb_pkgs = powercap_rapl_get_num_instances();
     //rapl->nb_pkgs = powercap_rapl_get_num_packages();
 
-    if (rapl->nb_pkgs == 0)
-        {
-            perror("no packages found (maybe the kernel module isn't loaded?)");
-            exit(-1);
-        }
+    if (rapl->nb_pkgs == 0) {
+        perror("no packages found (maybe the kernel module isn't loaded?)");
+        exit(-1);
+    }
     rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_init(package, &rapl->pkgs[package], 0))
-            {
-                perror("powercap_rapl_init, check access (root needed ?)");
-                exit(-1);
-            }
+        if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
+            perror("powercap_rapl_init, check access (root needed ?)");
+            exit(-1);
+        }
 
     rapl->names = NULL;
 
     char _name[MAX_LEN_NAME+1];
     char _name2[MAX_LEN_NAME+11];
 
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        {
-            for(unsigned int zone=0; zone < nb_zones; zone++)
-                {
-                    int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-                                                      _name, MAX_LEN_NAME);
-                    if (length>0)
-                        {
-
-                            sprintf(_name2, "%s%u", _name, package);
-
-                            rapl->nb++;
-                            rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
-                            rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
-                            rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
-                            rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
-
-                            strcpy(rapl->names[rapl->nb-1], _name2);
-                            rapl->zones[rapl->nb-1] = rapl_zones[zone];
-                            rapl->packages[rapl->nb-1] = package;
-                        }
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
+        for(unsigned int zone=0; zone < nb_zones; zone++) {
+            int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
+                                              _name, MAX_LEN_NAME);
+            if (length>0) {
+
+                sprintf(_name2, "%s%u", _name, package);
+
+                rapl->nb++;
+                rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
+                rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
+                rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
+                rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+
+                strcpy(rapl->names[rapl->nb-1], _name2);
+                rapl->zones[rapl->nb-1] = rapl_zones[zone];
+                rapl->packages[rapl->nb-1] = package;
+            }
 #ifdef DEBUG
-                    printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
+            printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
 #endif
-                }
         }
+    }
 #ifdef DEBUG
     printf("Result of init\n");
     for(unsigned int i=0; i<rapl->nb; i++)
diff --git a/src/temperature.c b/src/temperature.c
index e210f7b..cdef158 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -27,8 +27,7 @@
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
-struct temperature_t
-{
+struct temperature_t {
     char **label_list;
     int *fid_list;
     int nb_elem;
@@ -42,11 +41,10 @@ int get_string(char *filename, char *buffer, int max_size)
         return -1;
 
     int nb = read(fid, buffer, max_size);
-    if(nb == -1)
-        {
-            close(fid);
-            return -1;
-        }
+    if(nb == -1) {
+        close(fid);
+        return -1;
+    }
 
     buffer[nb]=0;
     close(fid);
@@ -70,39 +68,36 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 
     int delta = sprintf(buffer_label, "Temp_%d_", key);
 
-    for(int i=1;; i++)
-        {
-            sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
-            if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
-                break;
-
-            for(unsigned int pos = 0; pos < strlen(buffer_label); pos++)
-                {
-                    if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
-                    if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
-                }
-            add_to_list(&state->label_list, buffer_label, state->nb_elem);
-
-            sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
-            state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
-            int fd = open(buffer_filename, O_RDONLY);
-            if (fd < 0)
-                {
-                    fprintf(stderr, "%s ", buffer_filename);
-                    perror("open");
-                    exit(1);
-                }
-            state->fid_list[state->nb_elem] = fd;
-            state->nb_elem++;
-            // printf("%s : %s\n", buffer_label, buffer_filename);
+    for(int i=1;; i++) {
+        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+        if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
+            break;
+
+        for(unsigned int pos = 0; pos < strlen(buffer_label); pos++) {
+            if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
+            if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+        }
+        add_to_list(&state->label_list, buffer_label, state->nb_elem);
+
+        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+        state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
+        int fd = open(buffer_filename, O_RDONLY);
+        if (fd < 0) {
+            fprintf(stderr, "%s ", buffer_filename);
+            perror("open");
+            exit(1);
         }
+        state->fid_list[state->nb_elem] = fd;
+        state->nb_elem++;
+        // printf("%s : %s\n", buffer_label, buffer_filename);
+    }
 
     key++;
 }
 
 unsigned int init_temperature(char *args, void **ptr)
 {
-	UNUSED(args);
+    UNUSED(args);
     struct temperature_t *state = malloc(sizeof(struct temperature_t));
     state->nb_elem = 0;
     state->label_list = NULL;
@@ -114,14 +109,13 @@ unsigned int init_temperature(char *args, void **ptr)
 
     int i = 0;
     sprintf(name, base_name, i);
-    while(get_string(name, buffer, 8) != -1)
-        {
-            if (strcmp(buffer, "coretemp")==0)
-                add_temperature_sensor(i, state);
+    while(get_string(name, buffer, 8) != -1) {
+        if (strcmp(buffer, "coretemp")==0)
+            add_temperature_sensor(i, state);
 
-            i++;
-            sprintf(name, base_name, i);
-        }
+        i++;
+        sprintf(name, base_name, i);
+    }
     *ptr = (void *) state;
     return state->nb_elem;
 }
@@ -130,15 +124,13 @@ unsigned int get_temperature(uint64_t *results, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
     static char buffer[512];
-    for(int i=0; i<state->nb_elem; i++)
-        {
-            if (pread(state->fid_list[i], buffer, 100, 0) < 0)
-                {
-                    perror("pread");
-                    exit(1);
-                }
-            results[i] = strtoull(buffer, NULL, 10);
+    for(int i=0; i<state->nb_elem; i++) {
+        if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
+            perror("pread");
+            exit(1);
         }
+        results[i] = strtoull(buffer, NULL, 10);
+    }
     return state->nb_elem;
 }
 
@@ -146,11 +138,10 @@ void clean_temperature(void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
 
-    for(int i=0; i<state->nb_elem; i++)
-        {
-            free(state->label_list[i]);
-            close(state->fid_list[i]);
-        }
+    for(int i=0; i<state->nb_elem; i++) {
+        free(state->label_list[i]);
+        close(state->fid_list[i]);
+    }
     free(state->label_list);
     free(state->fid_list);
     free(state);
-- 
GitLab


From 619d27218686342aa1e4fb23db42b2976b086463 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 10:48:01 +0100
Subject: [PATCH 017/229] remove "mojitos_group"

- rm src/counters_group.c
- mv src/counters_individual.c src/counters.c
- remove the mojitos_group target from makefile
---
 makefile                                  |   5 +-
 src/{counters_individual.c => counters.c} |   0
 src/counters_group.c                      | 124 ----------------------
 3 files changed, 1 insertion(+), 128 deletions(-)
 rename src/{counters_individual.c => counters.c} (100%)
 delete mode 100644 src/counters_group.c

diff --git a/makefile b/makefile
index bf7d070..ab8c2dc 100644
--- a/makefile
+++ b/makefile
@@ -4,7 +4,7 @@ SRC_DIR = src
 OBJ_DIR = obj
 BIN_DIR = bin
 
-OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters_individual.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
+OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
@@ -19,9 +19,6 @@ all: mojitos
 mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
 	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
 
-mojitos_group: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS_GRP) $(SRC_DIR)/counters_option.h
-	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos_group $(OBJECTS_GRP) -lpowercap
-
 $(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
diff --git a/src/counters_individual.c b/src/counters.c
similarity index 100%
rename from src/counters_individual.c
rename to src/counters.c
diff --git a/src/counters_group.c b/src/counters_group.c
deleted file mode 100644
index 000e67a..0000000
--- a/src/counters_group.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <linux/perf_event.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <asm/unistd.h>
-
-#include "counters.h"
-
-struct _counter_t {
-    int nbcores;
-    int nbperf;
-    int *counters;
-};
-
-static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                            int cpu, int group_fd, unsigned long flags)
-{
-    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-    if (res == -1) {
-        perror("perf_event_open");
-        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-        exit(EXIT_FAILURE);
-    }
-    return res;
-}
-
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
-{
-    struct perf_event_attr pe;
-    struct _counter_t *counters = malloc(sizeof(struct _counter_t));
-
-    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
-    counters->nbcores=nbcores;
-    counters->nbperf=nb_perf;
-    memset(&pe, 0, sizeof(struct perf_event_attr));
-    pe.size = sizeof(struct perf_event_attr);
-    pe.disabled = 1;
-
-    pe.read_format = PERF_FORMAT_GROUP;
-    counters->counters = malloc((nbcores+1)*sizeof(int));
-
-    for (int core=0; core<nbcores; core++) {
-        counters->counters[core]=-1;
-        for(int idperf=0; idperf<nb_perf; idperf ++) {
-            pe.type = types[idperf];
-            pe.config = names[idperf];
-            int res=perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-            if(counters->counters[core]==-1)
-                counters->counters[core]=res;
-        }
-    }
-    return counters;
-}
-
-void clean_counters(counter_t counters)
-{
-    for(int core=0; core<counters->nbcores; core++)
-        close(counters->counters[core]);
-    free(counters->counters);
-    free(counters);
-}
-
-void start_counters(counter_t counters)
-{
-    for(int core=0; core<counters->nbcores; core++)
-        ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
-}
-void reset_counters(counter_t counters)
-{
-    for(int core=0; core<counters->nbcores; core++)
-        ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
-}
-
-struct read_format {
-    uint64_t nr;
-    struct {
-        uint64_t value;
-    } values[];
-};
-
-void get_counters(counter_t counters, long long *values)
-{
-    int nb_perf = counters->nbperf;
-    size_t buffer_size = sizeof(uint64_t)*(1+nb_perf);
-    struct read_format *buffer = NULL;
-    if(buffer==NULL)
-        buffer = malloc(buffer_size);
-
-    memset(values, 0, nb_perf*sizeof(long long));
-
-    for (int core=0; core<counters->nbcores; core++) {
-        if (-1 == read(counters->counters[core], buffer, buffer_size)) {
-            perror("PB Lecture resultat");
-            exit(EXIT_FAILURE);
-        }
-        for(int idperf=0; idperf<=nb_perf; idperf++) {
-            values[idperf] += buffer->values[idperf].value;
-        }
-    }
-    reset_counters(counters);
-}
-- 
GitLab


From d24dabec7b03c5e99a5f99a9cbf4f8fb0cdd748f Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Mon, 16 Jan 2023 11:26:30 +0100
Subject: [PATCH 018/229] =?UTF-8?q?r=C3=A9cup=20vieilles=20modifs?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 frapl.c   |  3 +++
 mojitos.c |  2 +-
 rapl.c    | 10 +++++++---
 3 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/frapl.c b/frapl.c
index 433a28c..657fd35 100644
--- a/frapl.c
+++ b/frapl.c
@@ -74,11 +74,14 @@ void add_frapl_source(_frapl_t* rapl, char*name, char*energy_uj) {
 void _get_frapl(uint64_t *values, _frapl_t* rapl) {
   static char buffer[512];
 
+  printf("Results : ");
   for (int i = 0; i < rapl->nb; i++) {
 
     pread(rapl->fids[i], buffer, 100, 0);
     values[i] = strtoull(buffer, NULL, 10);
+    printf("%d", values[i]);
   }
+  printf("\n");
 }
 
 
diff --git a/mojitos.c b/mojitos.c
index e80e692..029a24d 100644
--- a/mojitos.c
+++ b/mojitos.c
@@ -194,7 +194,7 @@ int main(int argc, char **argv) {
     unsigned int current = 0;
     for(int i=0; i<nb_sources; i++)
       current += getter[i](&values[current], states[i]);
-    
+      printf("Current : %d\n");
     if(application != NULL) {
 
       if(fork()==0){
diff --git a/rapl.c b/rapl.c
index 14b4a58..f23106d 100644
--- a/rapl.c
+++ b/rapl.c
@@ -132,9 +132,13 @@ unsigned int init_rapl(char* none, void **ptr) {
 unsigned int get_rapl(uint64_t* results, void* ptr) {
   _rapl_t* state = (_rapl_t*) ptr;
   _get_rapl(state->tmp_values, state);
-  for(int i=0; i<state->nb; i++)
-    results[i] = state->tmp_values[i] - state->values[i];
-
+  printf("results");
+    for (unsigned int i = 0; i < state->nb; i++)
+        {
+            results[i] = state->tmp_values[i] - state->values[i];
+            printf("%d, ", results[i]);
+        }
+    printf("\n");
   memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
   return state->nb;
 }
-- 
GitLab


From f71bec95a3305582ff26059104085b6e8775297d Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Mon, 16 Jan 2023 11:46:36 +0100
Subject: [PATCH 019/229] =?UTF-8?q?WSL=20fait=20des=20b=C3=AAtises=20faite?=
 =?UTF-8?q?s=20pas=20gaffe?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .gitignore             |    8 +-
 LICENSE                | 1348 ++++++++++++++++++++--------------------
 README.md              |  200 +++---
 makefile               |   96 +--
 src/counters.c         |  424 ++++++-------
 src/counters.h         |   52 +-
 src/counters_option.py |  124 ++--
 src/frapl.c            |  368 +++++------
 src/frapl.h            |   50 +-
 src/infiniband.c       |  162 ++---
 src/infiniband.h       |   44 +-
 src/load.c             |  184 +++---
 src/load.h             |   48 +-
 src/mojitos.c          |  592 +++++++++---------
 src/network.c          |  256 ++++----
 src/network.h          |   50 +-
 src/rapl.c             |  348 +++++------
 src/rapl.h             |   50 +-
 src/temperature.c      |  310 ++++-----
 src/temperature.h      |   48 +-
 20 files changed, 2381 insertions(+), 2381 deletions(-)

diff --git a/.gitignore b/.gitignore
index f5893ce..5a8f74f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-*.o
-src/counters_option.h
-bin
-obj
+*.o
+src/counters_option.h
+bin
+obj
diff --git a/LICENSE b/LICENSE
index f288702..3877ae0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,674 +1,674 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<https://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<https://www.gnu.org/licenses/why-not-lgpl.html>.
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/README.md b/README.md
index 2cf04f1..16d5d13 100644
--- a/README.md
+++ b/README.md
@@ -1,100 +1,100 @@
-# MOJITO/S
-
-An Open Source System, Energy and Network Monitoring Tools at the O/S level
-
-## Documentation
-
-MojitO/S runs on GNU/Linux
-Usage
-
-```python
-Usage : ./mojitos [-t time] [-f freq] [-r] [-p perf_list] [-l]  \
-                  [-u] [-d network_device] [-o logfile] [-e command arguments...]
-```
-
-Timing
-- If time is 0 then mojitos loops infinitively
-- If -e is present, time and freq are not used
-
-Configuration
-- -r activates RAPL (deprecated)
-- -R activates RAPL
-- -p activates performance counters. perf_list is coma separated list of performance counters without space.
-- -l lists the possible performance counters and quits
-- -d activates network monitoring
-- -u activates system-level load monitoring
-- -s activates statistics of overhead in nanoseconds
-
-MojitO/S is published under the GPL3 license and is part of the [Energumen Project](https://www.irit.fr/energumen/)
-
-<img src="https://www.irit.fr/energumen/images/energumen.png" width="100">
-
-## Installation Instructions
-
-Dependencies
-```bash
-sudo apt install libpowercap0 libpowercap-dev powercap-utils python3
-```
-Download the source code
-```bash
-git clone https://gitlab.irit.fr/sepia-pub/mojitos.git
-```
-Compile the code
-```bash
-cd mojitos
-make
-```
-To execute mojitos without being root to monitor performance counters
-```bash
-sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
-```
-To execute mohitos without being root for accessing RAPL
-```bash
-sudo chmod a+w /sys/class/powercap/intel-rapl/*/*
-sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
-```
-
-## Tutorial and Examples
-
-RAPL values during 2 seconds with a frequency of 2 Hz
-```bash
-$ ./mojitos -t 2 -f 2 -r
-#timestamp package-00 core0 dram0 
-1036389.135659868 10986 2869 1526 
-1036389.500183551 1291440 255736 515562 
-1036390.000754048 1333553 228393 689513 
-1036390.500113978 1581967 267944 701536 
-```
-Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
-
-```bash
-$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
-#timestamp cpu_cycles cache_ll page_faults 
-1036846.351749455 571199 1232 0 
-1036847.001098880 348173344 2451387 872 
-1036848.000166158 388112961 2509305 791 
-1036849.000191883 402255979 2625283 799 
-```
-
-Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
-```bash
-$ ./mojitos -t 0 -f 1 -d enp0s25
-#timestamp rxp rxb txp txb 
-1036559.277376027 0 0 0 0 
-1036560.000161101 4 581 2 179 
-1036561.000083968 178 268675 55 4954 
-1036562.000076162 11 1010 5 510 
-1036563.000069724 17 1643 12 3602 
-1036564.000113394 990 1493008 369 27299 
-```
-
-Overhead of the monitoring for RAPL and cpu_cycle
-```bash
-$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
-#timestamp cpu_cycles package-00 core0 dram0 overhead 
-1036988.197227391 162214 19898 4944 1586 149612 
-1036989.000151326 332613664 2513116 379577 1115171 739573 
-1036990.000116433 482150700 3321341 587218 1380673 315719 
-1036991.000182835 525984292 3592582 691221 1385982 272182 
-1036992.000165117 397678789 2770561 444030 1375729 510379 
-```
+# MOJITO/S
+
+An Open Source System, Energy and Network Monitoring Tools at the O/S level
+
+## Documentation
+
+MojitO/S runs on GNU/Linux
+Usage
+
+```python
+Usage : ./mojitos [-t time] [-f freq] [-r] [-p perf_list] [-l]  \
+                  [-u] [-d network_device] [-o logfile] [-e command arguments...]
+```
+
+Timing
+- If time is 0 then mojitos loops infinitively
+- If -e is present, time and freq are not used
+
+Configuration
+- -r activates RAPL (deprecated)
+- -R activates RAPL
+- -p activates performance counters. perf_list is coma separated list of performance counters without space.
+- -l lists the possible performance counters and quits
+- -d activates network monitoring
+- -u activates system-level load monitoring
+- -s activates statistics of overhead in nanoseconds
+
+MojitO/S is published under the GPL3 license and is part of the [Energumen Project](https://www.irit.fr/energumen/)
+
+<img src="https://www.irit.fr/energumen/images/energumen.png" width="100">
+
+## Installation Instructions
+
+Dependencies
+```bash
+sudo apt install libpowercap0 libpowercap-dev powercap-utils python3
+```
+Download the source code
+```bash
+git clone https://gitlab.irit.fr/sepia-pub/mojitos.git
+```
+Compile the code
+```bash
+cd mojitos
+make
+```
+To execute mojitos without being root to monitor performance counters
+```bash
+sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
+```
+To execute mohitos without being root for accessing RAPL
+```bash
+sudo chmod a+w /sys/class/powercap/intel-rapl/*/*
+sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
+```
+
+## Tutorial and Examples
+
+RAPL values during 2 seconds with a frequency of 2 Hz
+```bash
+$ ./mojitos -t 2 -f 2 -r
+#timestamp package-00 core0 dram0 
+1036389.135659868 10986 2869 1526 
+1036389.500183551 1291440 255736 515562 
+1036390.000754048 1333553 228393 689513 
+1036390.500113978 1581967 267944 701536 
+```
+Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
+
+```bash
+$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
+#timestamp cpu_cycles cache_ll page_faults 
+1036846.351749455 571199 1232 0 
+1036847.001098880 348173344 2451387 872 
+1036848.000166158 388112961 2509305 791 
+1036849.000191883 402255979 2625283 799 
+```
+
+Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
+```bash
+$ ./mojitos -t 0 -f 1 -d enp0s25
+#timestamp rxp rxb txp txb 
+1036559.277376027 0 0 0 0 
+1036560.000161101 4 581 2 179 
+1036561.000083968 178 268675 55 4954 
+1036562.000076162 11 1010 5 510 
+1036563.000069724 17 1643 12 3602 
+1036564.000113394 990 1493008 369 27299 
+```
+
+Overhead of the monitoring for RAPL and cpu_cycle
+```bash
+$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
+#timestamp cpu_cycles package-00 core0 dram0 overhead 
+1036988.197227391 162214 19898 4944 1586 149612 
+1036989.000151326 332613664 2513116 379577 1115171 739573 
+1036990.000116433 482150700 3321341 587218 1380673 315719 
+1036991.000182835 525984292 3592582 691221 1385982 272182 
+1036992.000165117 397678789 2770561 444030 1375729 510379 
+```
diff --git a/makefile b/makefile
index ab8c2dc..7229c46 100644
--- a/makefile
+++ b/makefile
@@ -1,48 +1,48 @@
-.PHONY: all clean mojitos mojitos_group debug format
-
-SRC_DIR = src
-OBJ_DIR = obj
-BIN_DIR = bin
-
-OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
-OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
-
-CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
-
-ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
-
-
-# depending on the context it may need to be changed to all: mojitos mojitos_group
-all: mojitos
-
-mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
-	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
-
-$(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
-	$(CC) $(CFLAGS) -c $< -o $@
-
-$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.py
-	python3 ./$(SRC_DIR)/counters_option.py > $(SRC_DIR)/counters_option.h
-
-$(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
-	$(CC) $(CFLAGS) -c $< -o $@
-
-$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c $(SRC_DIR)/%.h
-	$(CC) $(CFLAGS) -c $< -o $@
-
-$(OBJ_DIR):
-	mkdir -p $(OBJ_DIR)
-
-$(BIN_DIR):
-	mkdir -p $(BIN_DIR)
-
-debug: CFLAGS += -DDEBUG -g
-debug: all
-
-format:
-	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
-
-clean:
-	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-	\rm -f $(SRC_DIR)/counters_option.h
+.PHONY: all clean mojitos mojitos_group debug format
+
+SRC_DIR = src
+OBJ_DIR = obj
+BIN_DIR = bin
+
+OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
+OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
+
+CC = gcc
+CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
+
+ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
+
+
+# depending on the context it may need to be changed to all: mojitos mojitos_group
+all: mojitos
+
+mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
+	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
+
+$(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.py
+	python3 ./$(SRC_DIR)/counters_option.py > $(SRC_DIR)/counters_option.h
+
+$(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c $(SRC_DIR)/%.h
+	$(CC) $(CFLAGS) -c $< -o $@
+
+$(OBJ_DIR):
+	mkdir -p $(OBJ_DIR)
+
+$(BIN_DIR):
+	mkdir -p $(BIN_DIR)
+
+debug: CFLAGS += -DDEBUG -g
+debug: all
+
+format:
+	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
+
+clean:
+	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
+	\rm -f $(SRC_DIR)/counters_option.h
diff --git a/src/counters.c b/src/counters.c
index 5a24eed..643c9a3 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -1,212 +1,212 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <linux/perf_event.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <asm/unistd.h>
-#include <stdint.h>
-
-struct _counter_t {
-    int nbcores;
-    int nbperf;
-    int **counters;
-    uint64_t *counters_values;
-    uint64_t *tmp_counters_values;
-
-    int *perf_indexes;
-
-};
-typedef struct _counter_t *counter_t;
-
-#include "counters_option.h"
-
-void show_all_counters()
-{
-    for(unsigned int i=0; i<nb_counter_option; i++)
-        printf("%s\n", perf_static_info[i].name);
-}
-
-void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
-{
-    *perf_type = malloc(nb*sizeof(__u32));
-    *perf_key  = malloc(nb*sizeof(__u64));
-    for(int i=0; i<nb; i++) {
-        (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
-        (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
-    }
-}
-void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
-{
-    char *token;
-    *nb_perf=0;
-    *perf_indexes=NULL;
-    while((token=strtok(perf_string, ",")) != NULL) {
-        perf_string = NULL;
-        unsigned int i;
-        for(i=0; i<nb_counter_option; i++) {
-            if(strcmp(perf_static_info[i].name, token) == 0) {
-                (*nb_perf)++;
-                (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-                (*perf_indexes)[*nb_perf-1]=i;
-                break;
-            }
-        }
-        if(i == nb_counter_option) {
-            fprintf(stderr, "Unknown performance counter: %s\n", token);
-            exit(EXIT_FAILURE);
-        }
-    }
-}
-
-static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                            int cpu, int group_fd, unsigned long flags)
-{
-    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-    if (res == -1) {
-        perror("perf_event_open");
-        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-        exit(EXIT_FAILURE);
-    }
-    return res;
-}
-
-counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
-{
-    struct perf_event_attr pe;
-    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
-    memset(&pe, 0, sizeof(struct perf_event_attr));
-    pe.size = sizeof(struct perf_event_attr);
-    pe.disabled = 1;
-
-    counter_t counters = malloc(sizeof(struct _counter_t));
-    counters->nbperf = nb_perf;
-    counters->nbcores=nbcores;
-    counters->counters=malloc(nb_perf*sizeof(int *));
-    for (int i=0; i<nb_perf; i++) {
-        pe.type = types[i];
-        pe.config = names[i];
-        counters->counters[i] = malloc(nbcores*sizeof(int));
-
-        for (unsigned int core=0; core<nbcores; core++) {
-            counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
-        }
-    }
-    return counters;
-}
-
-void clean_counters(void *ptr)
-{
-    counter_t counters = (counter_t) ptr;
-    for(int counter=0; counter<counters->nbperf; counter++) {
-        for(int core=0; core<counters->nbcores; core++)
-            close(counters->counters[counter][core]);
-        free(counters->counters[counter]);
-    }
-    free(counters->counters);
-    free(counters->counters_values);
-    free(counters->tmp_counters_values);
-    free(counters->perf_indexes);
-
-    free(counters);
-}
-
-void start_counters(counter_t counters)
-{
-    for(int counter=0; counter<counters->nbperf; counter++)
-        for(int core=0; core<counters->nbcores; core++)
-            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
-}
-
-void reset_counters(counter_t counters)
-{
-    for(int counter=0; counter<counters->nbperf; counter++)
-        for(int core=0; core<counters->nbcores; core++)
-            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
-}
-
-void _get_counters(counter_t counters, uint64_t *values)
-{
-    for(int i=0; i<counters->nbperf; i++) {
-        uint64_t accu=0;
-        uint64_t count=0;
-        for (int core=0; core<counters->nbcores; core++) {
-            if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
-                fprintf(stderr, "Cannot read result");
-                exit(EXIT_FAILURE);
-            }
-            accu += count;
-        }
-        values[i] = accu;
-    }
-}
-
-
-
-
-
-
-unsigned int init_counters(char *args, void **state)
-{
-    int nb_perf;
-    int *perf_indexes=NULL;
-
-    perf_event_list(args, &nb_perf, &perf_indexes);
-
-    __u32 *perf_type;
-    __u64 *perf_key;
-    perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
-    counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
-    free(perf_type);
-    free(perf_key);
-
-    fd->perf_indexes = perf_indexes;
-    fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
-    fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
-    start_counters(fd);
-    _get_counters(fd, fd->counters_values);
-    *state = (void *) fd;
-
-    return nb_perf;
-}
-
-unsigned int get_counters(uint64_t *results, void *ptr)
-{
-    counter_t state = (counter_t) ptr;
-
-    _get_counters(state, state->tmp_counters_values);
-    for(int i=0; i<state->nbperf; i++)
-        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
-
-    memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
-    return state->nbperf;
-}
-
-void label_counters(char **labels, void *ptr)
-{
-    counter_t state = (counter_t) ptr;
-    for(int i=0; i<state->nbperf; i++)
-        labels[i] = perf_static_info[state->perf_indexes[i]].name;
-
-}
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <linux/perf_event.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <asm/unistd.h>
+#include <stdint.h>
+
+struct _counter_t {
+    int nbcores;
+    int nbperf;
+    int **counters;
+    uint64_t *counters_values;
+    uint64_t *tmp_counters_values;
+
+    int *perf_indexes;
+
+};
+typedef struct _counter_t *counter_t;
+
+#include "counters_option.h"
+
+void show_all_counters()
+{
+    for(unsigned int i=0; i<nb_counter_option; i++)
+        printf("%s\n", perf_static_info[i].name);
+}
+
+void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
+{
+    *perf_type = malloc(nb*sizeof(__u32));
+    *perf_key  = malloc(nb*sizeof(__u64));
+    for(int i=0; i<nb; i++) {
+        (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
+        (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
+    }
+}
+void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
+{
+    char *token;
+    *nb_perf=0;
+    *perf_indexes=NULL;
+    while((token=strtok(perf_string, ",")) != NULL) {
+        perf_string = NULL;
+        unsigned int i;
+        for(i=0; i<nb_counter_option; i++) {
+            if(strcmp(perf_static_info[i].name, token) == 0) {
+                (*nb_perf)++;
+                (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
+                (*perf_indexes)[*nb_perf-1]=i;
+                break;
+            }
+        }
+        if(i == nb_counter_option) {
+            fprintf(stderr, "Unknown performance counter: %s\n", token);
+            exit(EXIT_FAILURE);
+        }
+    }
+}
+
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                            int cpu, int group_fd, unsigned long flags)
+{
+    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+    if (res == -1) {
+        perror("perf_event_open");
+        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+        exit(EXIT_FAILURE);
+    }
+    return res;
+}
+
+counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+{
+    struct perf_event_attr pe;
+    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
+    memset(&pe, 0, sizeof(struct perf_event_attr));
+    pe.size = sizeof(struct perf_event_attr);
+    pe.disabled = 1;
+
+    counter_t counters = malloc(sizeof(struct _counter_t));
+    counters->nbperf = nb_perf;
+    counters->nbcores=nbcores;
+    counters->counters=malloc(nb_perf*sizeof(int *));
+    for (int i=0; i<nb_perf; i++) {
+        pe.type = types[i];
+        pe.config = names[i];
+        counters->counters[i] = malloc(nbcores*sizeof(int));
+
+        for (unsigned int core=0; core<nbcores; core++) {
+            counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
+        }
+    }
+    return counters;
+}
+
+void clean_counters(void *ptr)
+{
+    counter_t counters = (counter_t) ptr;
+    for(int counter=0; counter<counters->nbperf; counter++) {
+        for(int core=0; core<counters->nbcores; core++)
+            close(counters->counters[counter][core]);
+        free(counters->counters[counter]);
+    }
+    free(counters->counters);
+    free(counters->counters_values);
+    free(counters->tmp_counters_values);
+    free(counters->perf_indexes);
+
+    free(counters);
+}
+
+void start_counters(counter_t counters)
+{
+    for(int counter=0; counter<counters->nbperf; counter++)
+        for(int core=0; core<counters->nbcores; core++)
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
+}
+
+void reset_counters(counter_t counters)
+{
+    for(int counter=0; counter<counters->nbperf; counter++)
+        for(int core=0; core<counters->nbcores; core++)
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
+}
+
+void _get_counters(counter_t counters, uint64_t *values)
+{
+    for(int i=0; i<counters->nbperf; i++) {
+        uint64_t accu=0;
+        uint64_t count=0;
+        for (int core=0; core<counters->nbcores; core++) {
+            if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
+                fprintf(stderr, "Cannot read result");
+                exit(EXIT_FAILURE);
+            }
+            accu += count;
+        }
+        values[i] = accu;
+    }
+}
+
+
+
+
+
+
+unsigned int init_counters(char *args, void **state)
+{
+    int nb_perf;
+    int *perf_indexes=NULL;
+
+    perf_event_list(args, &nb_perf, &perf_indexes);
+
+    __u32 *perf_type;
+    __u64 *perf_key;
+    perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
+    counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
+    free(perf_type);
+    free(perf_key);
+
+    fd->perf_indexes = perf_indexes;
+    fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
+    fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
+    start_counters(fd);
+    _get_counters(fd, fd->counters_values);
+    *state = (void *) fd;
+
+    return nb_perf;
+}
+
+unsigned int get_counters(uint64_t *results, void *ptr)
+{
+    counter_t state = (counter_t) ptr;
+
+    _get_counters(state, state->tmp_counters_values);
+    for(int i=0; i<state->nbperf; i++)
+        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+
+    memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
+    return state->nbperf;
+}
+
+void label_counters(char **labels, void *ptr)
+{
+    counter_t state = (counter_t) ptr;
+    for(int i=0; i<state->nbperf; i++)
+        labels[i] = perf_static_info[state->perf_indexes[i]].name;
+
+}
diff --git a/src/counters.h b/src/counters.h
index af20717..bd2d0a5 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,26 +1,26 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_counters(char *, void **);
-unsigned int get_counters(uint64_t *results, void *);
-void clean_counters(void *);
-void label_counters(char **labels, void *);
-
-void show_all_counters();
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_counters(char *, void **);
+unsigned int get_counters(uint64_t *results, void *);
+void clean_counters(void *);
+void label_counters(char **labels, void *);
+
+void show_all_counters();
diff --git a/src/counters_option.py b/src/counters_option.py
index 877a33a..d853e41 100755
--- a/src/counters_option.py
+++ b/src/counters_option.py
@@ -1,62 +1,62 @@
-#! /usr/bin/python3
-
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-linux_include = '/usr/include/linux/perf_event.h'
-
-string = """#include <linux/perf_event.h>
-
-typedef struct counter_option {
-  char *name;
-  __u32 perf_type;
-  __u64 perf_key;
-} counter_option;
-
-static counter_option perf_static_info[] = {"""
-print(string)
-
-nb = 0
-
-black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
-              'cache_l1i', 'cache_op_write', 'cache_result_miss']
-
-with open(linux_include, 'r') as infile:
-    mode = ''
-    for line in infile:
-        if 'perf_hw_id' in line:
-            mode = 'PERF_TYPE_HARDWARE'
-        elif 'perf_hw_cache_' in line:
-            mode = 'PERF_TYPE_HW_CACHE'
-        elif 'perf_sw_id' in line:
-            mode = 'PERF_TYPE_SOFTWARE'
-        elif 'PERF_COUNT_' in line and '=' in line:
-            perf_name = line.split()[0]
-            short_perf = perf_name[14:].lower()
-            if short_perf in black_list:
-                continue
-            if mode == 'PERF_TYPE_HW_CACHE':
-                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
-                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
-                    for result_id, result_id_str in enumerate(['a', 'm']):
-                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
-
-                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
-                            short_perf, op_id_str, result_id_str,
-                            mode,
-                            perf_name,
-                            op_id_names[op_id],
-                            result_id_names[result_id])
-                                                                                     
-                        print(res)
-                        nb += 1
-
-            else:
-                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
-                print(res)
-                nb += 1
-
-
-print('};')
-
-print('static unsigned int nb_counter_option =',nb,';')
+#! /usr/bin/python3
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+linux_include = '/usr/include/linux/perf_event.h'
+
+string = """#include <linux/perf_event.h>
+
+typedef struct counter_option {
+  char *name;
+  __u32 perf_type;
+  __u64 perf_key;
+} counter_option;
+
+static counter_option perf_static_info[] = {"""
+print(string)
+
+nb = 0
+
+black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
+              'cache_l1i', 'cache_op_write', 'cache_result_miss']
+
+with open(linux_include, 'r') as infile:
+    mode = ''
+    for line in infile:
+        if 'perf_hw_id' in line:
+            mode = 'PERF_TYPE_HARDWARE'
+        elif 'perf_hw_cache_' in line:
+            mode = 'PERF_TYPE_HW_CACHE'
+        elif 'perf_sw_id' in line:
+            mode = 'PERF_TYPE_SOFTWARE'
+        elif 'PERF_COUNT_' in line and '=' in line:
+            perf_name = line.split()[0]
+            short_perf = perf_name[14:].lower()
+            if short_perf in black_list:
+                continue
+            if mode == 'PERF_TYPE_HW_CACHE':
+                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
+                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
+                    for result_id, result_id_str in enumerate(['a', 'm']):
+                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
+
+                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
+                            short_perf, op_id_str, result_id_str,
+                            mode,
+                            perf_name,
+                            op_id_names[op_id],
+                            result_id_names[result_id])
+                                                                                     
+                        print(res)
+                        nb += 1
+
+            else:
+                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
+                print(res)
+                nb += 1
+
+
+print('};')
+
+print('static unsigned int nb_counter_option =',nb,';')
diff --git a/src/frapl.c b/src/frapl.c
index 9874a12..62c94bc 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -1,184 +1,184 @@
-/*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-
-
-#define MAX_HEADER 128
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-
-char *get_frapl_string(const char *filename)
-{
-    int fd = open(filename, O_RDONLY);
-    if( fd == -1) {
-        return NULL;
-    }
-    char *result = malloc(MAX_HEADER);
-    int nb = read(fd, result, MAX_HEADER);
-    close(fd);
-    result[nb-1] = 0;
-    return (result);
-}
-
-void test_append(char *name, int i)
-{
-    //char last = name[strlen(name)-1];
-    //if (last>='0' && last <= '9')
-    //  return;
-    sprintf(name+strlen(name), "%d", i);
-}
-
-
-struct _frapl_t {
-    unsigned int nb;
-    char **names;
-    int *fids;
-    uint64_t *values;
-    uint64_t *tmp_values;
-
-};
-typedef struct _frapl_t _frapl_t;
-
-
-void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
-{
-    rapl->nb += 1;
-    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
-    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
-
-    rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
-    strcpy(rapl->names[rapl->nb-1], name);
-    //printf("%s\n", energy_uj);
-
-    int fd = open(energy_uj, O_RDONLY);
-
-    if (fd < 0) {
-        fprintf(stderr, "%s ", energy_uj);
-        perror("open");
-        exit(1);
-    }
-    rapl->fids[rapl->nb-1] = fd;
-}
-
-
-void _get_frapl(uint64_t *values, _frapl_t *rapl)
-{
-    static char buffer[512];
-
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-
-        if (pread(rapl->fids[i], buffer, 100, 0) < 0) {
-            perror("pread");
-            exit(1);
-        }
-        values[i] = strtoull(buffer, NULL, 10);
-    }
-}
-
-
-unsigned int init_frapl(char *none, void **ptr)
-{
-    UNUSED(none);
-    _frapl_t *rapl = malloc(sizeof(_frapl_t));
-    rapl->nb = 0;
-    rapl->names = NULL;
-    rapl->fids = NULL;
-
-    char buffer[1024];
-    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
-    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
-
-    for (unsigned int i=0;; i++) {
-        sprintf(buffer, name_base, i, "name");
-        char *tmp = get_frapl_string(buffer);
-        if (tmp == NULL) break;
-        //printf("%s\n", tmp);
-        test_append(tmp, i);
-        //printf("%s -> %s\n", buffer, tmp);
-
-        sprintf(buffer, name_base, i, "energy_uj");
-        add_frapl_source(rapl, tmp, buffer);
-        free(tmp);
-
-        for (unsigned int j=0;; j++) {
-            sprintf(buffer, name_sub, i, i, j, "name");
-            char *tmp_sub = get_frapl_string(buffer);
-            if (tmp_sub == NULL) break;
-            //printf("%s\n", tmp_sub);
-            test_append(tmp_sub, i);
-            //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-            sprintf(buffer, name_sub, i, i, j, "energy_uj");
-            add_frapl_source(rapl, tmp_sub, buffer);
-
-            free(tmp_sub);
-        }
-    }
-
-    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
-
-    _get_frapl(rapl->values, rapl);
-
-    *ptr = (void *)rapl;
-    return rapl->nb;
-}
-
-
-unsigned int get_frapl(uint64_t *results, void *ptr)
-{
-    _frapl_t *state = (_frapl_t *) ptr;
-    _get_frapl(state->tmp_values, state);
-    for(unsigned int i=0; i<state->nb; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
-
-    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-    return state->nb;
-}
-
-void clean_frapl(void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++) {
-        free(rapl->names[i]);
-        close(rapl->fids[i]);
-    }
-    free(rapl->names);
-    free(rapl->fids);
-    free(rapl->values);
-    free(rapl->tmp_values);
-    free(rapl);
-}
-
-
-void label_frapl(char **labels, void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        labels[i] = rapl->names[i];
-}
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
+
+
+#define MAX_HEADER 128
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+
+char *get_frapl_string(const char *filename)
+{
+    int fd = open(filename, O_RDONLY);
+    if( fd == -1) {
+        return NULL;
+    }
+    char *result = malloc(MAX_HEADER);
+    int nb = read(fd, result, MAX_HEADER);
+    close(fd);
+    result[nb-1] = 0;
+    return (result);
+}
+
+void test_append(char *name, int i)
+{
+    //char last = name[strlen(name)-1];
+    //if (last>='0' && last <= '9')
+    //  return;
+    sprintf(name+strlen(name), "%d", i);
+}
+
+
+struct _frapl_t {
+    unsigned int nb;
+    char **names;
+    int *fids;
+    uint64_t *values;
+    uint64_t *tmp_values;
+
+};
+typedef struct _frapl_t _frapl_t;
+
+
+void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
+{
+    rapl->nb += 1;
+    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
+    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
+
+    rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
+    strcpy(rapl->names[rapl->nb-1], name);
+    //printf("%s\n", energy_uj);
+
+    int fd = open(energy_uj, O_RDONLY);
+
+    if (fd < 0) {
+        fprintf(stderr, "%s ", energy_uj);
+        perror("open");
+        exit(1);
+    }
+    rapl->fids[rapl->nb-1] = fd;
+}
+
+
+void _get_frapl(uint64_t *values, _frapl_t *rapl)
+{
+    static char buffer[512];
+
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+
+        if (pread(rapl->fids[i], buffer, 100, 0) < 0) {
+            perror("pread");
+            exit(1);
+        }
+        values[i] = strtoull(buffer, NULL, 10);
+    }
+}
+
+
+unsigned int init_frapl(char *none, void **ptr)
+{
+    UNUSED(none);
+    _frapl_t *rapl = malloc(sizeof(_frapl_t));
+    rapl->nb = 0;
+    rapl->names = NULL;
+    rapl->fids = NULL;
+
+    char buffer[1024];
+    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
+    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
+
+    for (unsigned int i=0;; i++) {
+        sprintf(buffer, name_base, i, "name");
+        char *tmp = get_frapl_string(buffer);
+        if (tmp == NULL) break;
+        //printf("%s\n", tmp);
+        test_append(tmp, i);
+        //printf("%s -> %s\n", buffer, tmp);
+
+        sprintf(buffer, name_base, i, "energy_uj");
+        add_frapl_source(rapl, tmp, buffer);
+        free(tmp);
+
+        for (unsigned int j=0;; j++) {
+            sprintf(buffer, name_sub, i, i, j, "name");
+            char *tmp_sub = get_frapl_string(buffer);
+            if (tmp_sub == NULL) break;
+            //printf("%s\n", tmp_sub);
+            test_append(tmp_sub, i);
+            //printf("%s -> %s\n", buffer, tmp_sub);
+
+
+            sprintf(buffer, name_sub, i, i, j, "energy_uj");
+            add_frapl_source(rapl, tmp_sub, buffer);
+
+            free(tmp_sub);
+        }
+    }
+
+    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
+
+    _get_frapl(rapl->values, rapl);
+
+    *ptr = (void *)rapl;
+    return rapl->nb;
+}
+
+
+unsigned int get_frapl(uint64_t *results, void *ptr)
+{
+    _frapl_t *state = (_frapl_t *) ptr;
+    _get_frapl(state->tmp_values, state);
+    for(unsigned int i=0; i<state->nb; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
+
+    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
+    return state->nb;
+}
+
+void clean_frapl(void *ptr)
+{
+    _frapl_t *rapl = (_frapl_t *) ptr;
+    for(unsigned int i=0; i<rapl->nb; i++) {
+        free(rapl->names[i]);
+        close(rapl->fids[i]);
+    }
+    free(rapl->names);
+    free(rapl->fids);
+    free(rapl->values);
+    free(rapl->tmp_values);
+    free(rapl);
+}
+
+
+void label_frapl(char **labels, void *ptr)
+{
+    _frapl_t *rapl = (_frapl_t *) ptr;
+    for(unsigned int i=0; i<rapl->nb; i++)
+        labels[i] = rapl->names[i];
+}
diff --git a/src/frapl.h b/src/frapl.h
index 937108e..8ce4e00 100644
--- a/src/frapl.h
+++ b/src/frapl.h
@@ -1,25 +1,25 @@
-/*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_frapl(char *, void **);
-unsigned int get_frapl(uint64_t *results, void *);
-void clean_frapl(void *);
-void label_frapl(char **labels, void *);
-
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_frapl(char *, void **);
+unsigned int get_frapl(uint64_t *results, void *);
+void clean_frapl(void *);
+void label_frapl(char **labels, void *);
+
diff --git a/src/infiniband.c b/src/infiniband.c
index 6621759..bbc2dce 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -1,81 +1,81 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-#include <stdlib.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-
-#include <glob.h>
-
-#include <stdint.h>
-
-#define NB_SENSOR 4
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-struct network_t {
-    uint64_t values[NB_SENSOR];
-    uint64_t tmp_values[NB_SENSOR];
-    int sources[NB_SENSOR];
-};
-unsigned int _get_network(uint64_t *results, int *sources);
-
-
-unsigned int init_infiniband(char *infi_path, void **ptr)
-{
-    if(infi_path==NULL)
-        return 0;
-
-    if(strcmp(infi_path,"X")==0) {
-
-        glob_t res;
-
-        glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
-        if(res.gl_pathc == 0)
-            return 0;
-        infi_path = res.gl_pathv[0];
-    }
-
-    char *filenames[] = {"%s/port_rcv_packets",
-                         "%s/port_rcv_data",
-                         "%s/port_xmit_packets",
-                         "%s/port_xmit_data"
-                        };
-
-    struct network_t *state = malloc(sizeof(struct network_t));
-
-    char buffer[1024];
-    for(int i=0; i<NB_SENSOR; i++) {
-        sprintf(buffer, filenames[i], infi_path);
-        state->sources[i] = open(buffer, O_RDONLY);
-    }
-
-    *ptr = (void *) state;
-    _get_network(state->values, state->sources);
-
-    return NB_SENSOR;
-}
-
-char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
-void label_infiniband(char **labels, void *none)
-{
-    UNUSED(none);
-    for(int i=0; i<NB_SENSOR; i++)
-        labels[i] = _labels_infiniband[i];
-}
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+#include <stdlib.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <glob.h>
+
+#include <stdint.h>
+
+#define NB_SENSOR 4
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+struct network_t {
+    uint64_t values[NB_SENSOR];
+    uint64_t tmp_values[NB_SENSOR];
+    int sources[NB_SENSOR];
+};
+unsigned int _get_network(uint64_t *results, int *sources);
+
+
+unsigned int init_infiniband(char *infi_path, void **ptr)
+{
+    if(infi_path==NULL)
+        return 0;
+
+    if(strcmp(infi_path,"X")==0) {
+
+        glob_t res;
+
+        glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
+        if(res.gl_pathc == 0)
+            return 0;
+        infi_path = res.gl_pathv[0];
+    }
+
+    char *filenames[] = {"%s/port_rcv_packets",
+                         "%s/port_rcv_data",
+                         "%s/port_xmit_packets",
+                         "%s/port_xmit_data"
+                        };
+
+    struct network_t *state = malloc(sizeof(struct network_t));
+
+    char buffer[1024];
+    for(int i=0; i<NB_SENSOR; i++) {
+        sprintf(buffer, filenames[i], infi_path);
+        state->sources[i] = open(buffer, O_RDONLY);
+    }
+
+    *ptr = (void *) state;
+    _get_network(state->values, state->sources);
+
+    return NB_SENSOR;
+}
+
+char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
+void label_infiniband(char **labels, void *none)
+{
+    UNUSED(none);
+    for(int i=0; i<NB_SENSOR; i++)
+        labels[i] = _labels_infiniband[i];
+}
diff --git a/src/infiniband.h b/src/infiniband.h
index 1f6aaf9..4234964 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -1,22 +1,22 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_infiniband(char *infi_path, void **ptr);
-void label_infiniband(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_infiniband(char *infi_path, void **ptr);
+void label_infiniband(char **labels, void *);
diff --git a/src/load.c b/src/load.c
index 4f11346..92b1088 100644
--- a/src/load.c
+++ b/src/load.c
@@ -1,92 +1,92 @@
-/*******************************************************
- Copyright (C) 2019-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <stdio.h>
-
-#define LOAD_BUFFER_SIZE 1024
-#define UNUSED(expr) do { (void)(expr); } while (0)
-char buffer[LOAD_BUFFER_SIZE];
-
-static int load_fid=-1;
-static uint64_t load_values[10]= {0,0,0,0,0,0,0,0,0,0};
-static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
-static char *stat = "/proc/stat";
-
-void _get_load(uint64_t *results)
-{
-    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0) {
-        perror("pread");
-        exit(1);
-    }
-    int pos=0;
-    while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
-    for(int i=0; i<10; i++) {
-        results[i] = strtoull(buffer+pos, NULL, 10);
-        while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
-        pos++;
-    }
-}
-
-// Public interface
-
-unsigned int init_load(char *argument, void **state)
-{
-    UNUSED(argument);
-    UNUSED(state);
-    load_fid = open(stat, O_RDONLY);
-    if (load_fid < 0) {
-        fprintf(stderr,"%s ",stat);
-        perror("open");
-        exit(1);
-    }
-    _get_load(load_values);
-    return 10;
-}
-
-unsigned int get_load(uint64_t *results, void *state)
-{
-    UNUSED(state);
-    _get_load(tmp_load_values);
-    for(int i=0; i<10; i++)
-        results[i] = tmp_load_values[i] - load_values[i];
-
-    memcpy(load_values, tmp_load_values, sizeof(load_values));
-    return 10;
-}
-
-void clean_load(void *state)
-{
-    UNUSED(state);
-    close(load_fid);
-}
-
-char *_labels[10] = {"user","nice","system","idle","iowait","irq",
-                     "softirq","steal","guest","guest_nice"
-                    };
-void label_load(char **labels, void *none)
-{
-    UNUSED(none);
-    for(int i=0; i<10; i++)
-        labels[i] = _labels[i];
-}
+/*******************************************************
+ Copyright (C) 2019-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+
+#define LOAD_BUFFER_SIZE 1024
+#define UNUSED(expr) do { (void)(expr); } while (0)
+char buffer[LOAD_BUFFER_SIZE];
+
+static int load_fid=-1;
+static uint64_t load_values[10]= {0,0,0,0,0,0,0,0,0,0};
+static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
+static char *stat = "/proc/stat";
+
+void _get_load(uint64_t *results)
+{
+    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0) {
+        perror("pread");
+        exit(1);
+    }
+    int pos=0;
+    while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
+    for(int i=0; i<10; i++) {
+        results[i] = strtoull(buffer+pos, NULL, 10);
+        while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
+        pos++;
+    }
+}
+
+// Public interface
+
+unsigned int init_load(char *argument, void **state)
+{
+    UNUSED(argument);
+    UNUSED(state);
+    load_fid = open(stat, O_RDONLY);
+    if (load_fid < 0) {
+        fprintf(stderr,"%s ",stat);
+        perror("open");
+        exit(1);
+    }
+    _get_load(load_values);
+    return 10;
+}
+
+unsigned int get_load(uint64_t *results, void *state)
+{
+    UNUSED(state);
+    _get_load(tmp_load_values);
+    for(int i=0; i<10; i++)
+        results[i] = tmp_load_values[i] - load_values[i];
+
+    memcpy(load_values, tmp_load_values, sizeof(load_values));
+    return 10;
+}
+
+void clean_load(void *state)
+{
+    UNUSED(state);
+    close(load_fid);
+}
+
+char *_labels[10] = {"user","nice","system","idle","iowait","irq",
+                     "softirq","steal","guest","guest_nice"
+                    };
+void label_load(char **labels, void *none)
+{
+    UNUSED(none);
+    for(int i=0; i<10; i++)
+        labels[i] = _labels[i];
+}
diff --git a/src/load.h b/src/load.h
index 299fa3e..78c1b40 100644
--- a/src/load.h
+++ b/src/load.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_load(char *, void **);
-unsigned int get_load(uint64_t *results, void *);
-void clean_load(void *);
-void label_load(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_load(char *, void **);
+unsigned int get_load(uint64_t *results, void *);
+void clean_load(void *);
+void label_load(char **labels, void *);
diff --git a/src/mojitos.c b/src/mojitos.c
index 3569d1b..7d680b1 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -1,296 +1,296 @@
-/*******************************************************
-
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <signal.h>
-#include <inttypes.h>
-#include <unistd.h>
-
-#include "counters.h"
-#include "rapl.h"
-#include "frapl.h"
-#include "network.h"
-#include "infiniband.h"
-#include "load.h"
-#include "temperature.h"
-
-#define UNUSED(expr) do { (void)(expr); } while (0)
-#define PANIC(code, fmt, ...)  				 \
-	do {									 \
-		fprintf(stderr, "Exit on error: ");  \
-		fprintf(stderr, fmt, ##__VA_ARGS__); \
-		fprintf(stderr, "\n"); 			     \
-		exit(code); 						 \
-	} while (0)
-
-
-void usage(char **argv)
-{
-    printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
-           "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
-           "if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n"
-           "-r activates RAPL\n"
-           "-R activates the file version of RAPL\n"
-           "-p activates performance counters\n"
-           "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
-           "-l lists the possible performance counters and quits\n"
-           "-d activates network monitoring (if network_device is X, tries to detect it automatically)\n"
-           "-i activates infiniband monitoring (if infiniband_path is X, tries to detect it automatically)\n"
-           "-s activates statistics of overhead in nanoseconds\n"
-           "-u activates report of system load\n"
-           "-c activates report of processor temperature\n"
-           , argv[0]);
-    exit(EXIT_SUCCESS);
-}
-
-void sighandler(int none)
-{
-    UNUSED(none);
-}
-
-void flush(int none)
-{
-    UNUSED(none);
-    exit(0);
-}
-
-FILE *output;
-void flushexit()
-{
-    if (output != NULL) {
-        fflush(output);
-        fclose(output);
-    }
-}
-
-typedef unsigned int (initializer_t)(char *, void **);
-typedef void (labeler_t)(char **, void *);
-typedef unsigned int (*getter_t)(uint64_t *, void *);
-typedef void (*cleaner_t)(void *);
-
-unsigned int nb_sources = 0;
-void **states = NULL;
-getter_t *getter = NULL;
-cleaner_t *cleaner = NULL;
-
-unsigned int nb_sensors = 0;
-char **labels = NULL;
-uint64_t *values = NULL;
-
-void add_source(initializer_t init, char *arg, labeler_t labeler,
-                getter_t get, cleaner_t clean)
-{
-    nb_sources++;
-    states = realloc(states, nb_sources * sizeof(void *));
-    int nb = init(arg, &states[nb_sources - 1]);
-    if (nb == 0) {
-        nb_sources--;
-        states = realloc(states, nb_sources * sizeof(void *));
-        return;
-    }
-
-    getter = realloc(getter, nb_sources * sizeof(void *));
-    getter[nb_sources - 1] = get;
-    cleaner = realloc(cleaner, nb_sources * sizeof(void *));
-    cleaner[nb_sources - 1] = clean;
-
-    labels = realloc(labels, (nb_sensors + nb) * sizeof(char *));
-    labeler(labels + nb_sensors, states[nb_sources - 1]);
-
-    values = realloc(values, (nb_sensors + nb) * sizeof(uint64_t));
-    nb_sensors += nb;
-}
-
-int main(int argc, char **argv)
-{
-    int total_time = 1;
-    int delta = 0;
-    int frequency = 1;
-    char **application = NULL;
-
-    int stat_mode = -1;
-
-    if (argc == 1) {
-        usage(argv);
-    }
-
-    output = stdout;
-
-    atexit(flushexit);
-    signal(15, flush);
-
-    int c;
-    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL)
-        switch (c) {
-        case 'f':
-            if (optind >= argc) PANIC(1,"-f, no frequency provided");
-            frequency = atoi(argv[optind]);
-            break;
-        case 't':
-            if (optind >= argc) PANIC(1,"-t, no time provided");
-            total_time = atoi(argv[optind]);
-            delta = 1;
-            if (total_time == 0) {
-                total_time = 1;
-                delta = 0;
-            }
-            break;
-        case 'd':
-            add_source(init_network, argv[optind], label_network, get_network, clean_network);
-            break;
-        case 'i':
-            add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
-            break;
-        case 'o':
-            if (optind >= argc) PANIC(1,"-o, no logfile provided");
-            if ((output = fopen(argv[optind], "wb")) == NULL) {
-                perror("fopen");
-                PANIC(1, "-o %s", argv[optind]);
-            }
-            break;
-        case 'e':
-            application = &argv[optind];
-            signal(17, sighandler);
-            break;
-        case 'p':
-            if (optind >= argc) PANIC(1,"-p, no counter provided");
-            add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
-            break;
-        case 'r':
-            add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
-            break;
-        case 'R':
-            add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
-            break;
-        case 'u':
-            add_source(init_load, NULL, label_load, get_load, clean_load);
-            break;
-        case 'c':
-            add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
-            break;
-        case 's':
-            stat_mode = 0;
-            break;
-        case 'l':
-            show_all_counters();
-            exit(EXIT_SUCCESS);
-        default:
-            usage(argv);
-        }
-
-
-    setvbuf(output, NULL, _IONBF, BUFSIZ);
-    struct timespec ts;
-    struct timespec ts_ref;
-
-    fprintf(output, "#timestamp ");
-
-    for (unsigned int i = 0; i < nb_sensors; i++) {
-        fprintf(output, "%s ", labels[i]);
-    }
-
-    if (stat_mode == 0) {
-        fprintf(output, "overhead ");
-    }
-
-    fprintf(output, "\n");
-
-    unsigned long int stat_data = 0;
-
-    for (int temps = 0; temps < total_time * frequency; temps += delta) {
-        clock_gettime(CLOCK_MONOTONIC, &ts_ref);
-
-        // Get Data
-        unsigned int current = 0;
-        for (unsigned int i = 0; i < nb_sources; i++) {
-            current += getter[i](&values[current], states[i]);
-        }
-
-        if (application != NULL) {
-
-            if (fork() == 0) {
-                execvp(application[0], application);
-                exit(0);
-            }
-            pause();
-            clock_gettime(CLOCK_MONOTONIC, &ts);
-            if (ts.tv_nsec >= ts_ref.tv_nsec) {
-                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
-            } else {
-                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
-            }
-        } else {
-#ifdef DEBUG
-            clock_gettime(CLOCK_MONOTONIC, &ts);
-            fprintf(stderr, "%ld\n", (ts.tv_nsec - ts_ref.tv_nsec) / 1000);
-            //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
-            //Group: mean: 309 std: 41 % med: 297 std: 39 %
-#endif
-            if (stat_mode == 0) {
-                clock_gettime(CLOCK_MONOTONIC, &ts);
-                if (ts.tv_nsec >= ts_ref.tv_nsec) {
-                    stat_data = ts.tv_nsec - ts_ref.tv_nsec;
-                } else {
-                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
-                }
-            }
-
-            // Treat Data
-            fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
-        }
-
-        for (unsigned int i = 0; i < nb_sensors; i++) {
-            fprintf(output, "%" PRIu64 " ", values[i]);
-        }
-
-        if (stat_mode == 0) {
-            fprintf(output, "%ld ", stat_data);
-        }
-
-        fprintf(output, "\n");
-
-        if (application != NULL) {
-            break;
-        }
-
-        clock_gettime(CLOCK_MONOTONIC, &ts);
-        usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
-    }
-
-    for (unsigned int i = 0; i < nb_sources; i++) {
-        cleaner[i](states[i]);
-    }
-
-    if (nb_sources > 0) {
-        free(getter);
-        free(cleaner);
-        free(labels);
-        free(values);
-        free(states);
-    }
-}
-
-
-
-
+/*******************************************************
+
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <signal.h>
+#include <inttypes.h>
+#include <unistd.h>
+
+#include "counters.h"
+#include "rapl.h"
+#include "frapl.h"
+#include "network.h"
+#include "infiniband.h"
+#include "load.h"
+#include "temperature.h"
+
+#define UNUSED(expr) do { (void)(expr); } while (0)
+#define PANIC(code, fmt, ...)  				 \
+	do {									 \
+		fprintf(stderr, "Exit on error: ");  \
+		fprintf(stderr, fmt, ##__VA_ARGS__); \
+		fprintf(stderr, "\n"); 			     \
+		exit(code); 						 \
+	} while (0)
+
+
+void usage(char **argv)
+{
+    printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
+           "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
+           "if time==0 then loops infinitively\n"
+           "if -e is present, time and freq are not used\n"
+           "-r activates RAPL\n"
+           "-R activates the file version of RAPL\n"
+           "-p activates performance counters\n"
+           "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
+           "-l lists the possible performance counters and quits\n"
+           "-d activates network monitoring (if network_device is X, tries to detect it automatically)\n"
+           "-i activates infiniband monitoring (if infiniband_path is X, tries to detect it automatically)\n"
+           "-s activates statistics of overhead in nanoseconds\n"
+           "-u activates report of system load\n"
+           "-c activates report of processor temperature\n"
+           , argv[0]);
+    exit(EXIT_SUCCESS);
+}
+
+void sighandler(int none)
+{
+    UNUSED(none);
+}
+
+void flush(int none)
+{
+    UNUSED(none);
+    exit(0);
+}
+
+FILE *output;
+void flushexit()
+{
+    if (output != NULL) {
+        fflush(output);
+        fclose(output);
+    }
+}
+
+typedef unsigned int (initializer_t)(char *, void **);
+typedef void (labeler_t)(char **, void *);
+typedef unsigned int (*getter_t)(uint64_t *, void *);
+typedef void (*cleaner_t)(void *);
+
+unsigned int nb_sources = 0;
+void **states = NULL;
+getter_t *getter = NULL;
+cleaner_t *cleaner = NULL;
+
+unsigned int nb_sensors = 0;
+char **labels = NULL;
+uint64_t *values = NULL;
+
+void add_source(initializer_t init, char *arg, labeler_t labeler,
+                getter_t get, cleaner_t clean)
+{
+    nb_sources++;
+    states = realloc(states, nb_sources * sizeof(void *));
+    int nb = init(arg, &states[nb_sources - 1]);
+    if (nb == 0) {
+        nb_sources--;
+        states = realloc(states, nb_sources * sizeof(void *));
+        return;
+    }
+
+    getter = realloc(getter, nb_sources * sizeof(void *));
+    getter[nb_sources - 1] = get;
+    cleaner = realloc(cleaner, nb_sources * sizeof(void *));
+    cleaner[nb_sources - 1] = clean;
+
+    labels = realloc(labels, (nb_sensors + nb) * sizeof(char *));
+    labeler(labels + nb_sensors, states[nb_sources - 1]);
+
+    values = realloc(values, (nb_sensors + nb) * sizeof(uint64_t));
+    nb_sensors += nb;
+}
+
+int main(int argc, char **argv)
+{
+    int total_time = 1;
+    int delta = 0;
+    int frequency = 1;
+    char **application = NULL;
+
+    int stat_mode = -1;
+
+    if (argc == 1) {
+        usage(argv);
+    }
+
+    output = stdout;
+
+    atexit(flushexit);
+    signal(15, flush);
+
+    int c;
+    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL)
+        switch (c) {
+        case 'f':
+            if (optind >= argc) PANIC(1,"-f, no frequency provided");
+            frequency = atoi(argv[optind]);
+            break;
+        case 't':
+            if (optind >= argc) PANIC(1,"-t, no time provided");
+            total_time = atoi(argv[optind]);
+            delta = 1;
+            if (total_time == 0) {
+                total_time = 1;
+                delta = 0;
+            }
+            break;
+        case 'd':
+            add_source(init_network, argv[optind], label_network, get_network, clean_network);
+            break;
+        case 'i':
+            add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
+            break;
+        case 'o':
+            if (optind >= argc) PANIC(1,"-o, no logfile provided");
+            if ((output = fopen(argv[optind], "wb")) == NULL) {
+                perror("fopen");
+                PANIC(1, "-o %s", argv[optind]);
+            }
+            break;
+        case 'e':
+            application = &argv[optind];
+            signal(17, sighandler);
+            break;
+        case 'p':
+            if (optind >= argc) PANIC(1,"-p, no counter provided");
+            add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
+            break;
+        case 'r':
+            add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
+            break;
+        case 'R':
+            add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
+            break;
+        case 'u':
+            add_source(init_load, NULL, label_load, get_load, clean_load);
+            break;
+        case 'c':
+            add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
+            break;
+        case 's':
+            stat_mode = 0;
+            break;
+        case 'l':
+            show_all_counters();
+            exit(EXIT_SUCCESS);
+        default:
+            usage(argv);
+        }
+
+
+    setvbuf(output, NULL, _IONBF, BUFSIZ);
+    struct timespec ts;
+    struct timespec ts_ref;
+
+    fprintf(output, "#timestamp ");
+
+    for (unsigned int i = 0; i < nb_sensors; i++) {
+        fprintf(output, "%s ", labels[i]);
+    }
+
+    if (stat_mode == 0) {
+        fprintf(output, "overhead ");
+    }
+
+    fprintf(output, "\n");
+
+    unsigned long int stat_data = 0;
+
+    for (int temps = 0; temps < total_time * frequency; temps += delta) {
+        clock_gettime(CLOCK_MONOTONIC, &ts_ref);
+
+        // Get Data
+        unsigned int current = 0;
+        for (unsigned int i = 0; i < nb_sources; i++) {
+            current += getter[i](&values[current], states[i]);
+        }
+
+        if (application != NULL) {
+
+            if (fork() == 0) {
+                execvp(application[0], application);
+                exit(0);
+            }
+            pause();
+            clock_gettime(CLOCK_MONOTONIC, &ts);
+            if (ts.tv_nsec >= ts_ref.tv_nsec) {
+                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
+            } else {
+                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
+            }
+        } else {
+#ifdef DEBUG
+            clock_gettime(CLOCK_MONOTONIC, &ts);
+            fprintf(stderr, "%ld\n", (ts.tv_nsec - ts_ref.tv_nsec) / 1000);
+            //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
+            //Group: mean: 309 std: 41 % med: 297 std: 39 %
+#endif
+            if (stat_mode == 0) {
+                clock_gettime(CLOCK_MONOTONIC, &ts);
+                if (ts.tv_nsec >= ts_ref.tv_nsec) {
+                    stat_data = ts.tv_nsec - ts_ref.tv_nsec;
+                } else {
+                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
+                }
+            }
+
+            // Treat Data
+            fprintf(output, "%ld.%09ld ", ts_ref.tv_sec, ts_ref.tv_nsec);
+        }
+
+        for (unsigned int i = 0; i < nb_sensors; i++) {
+            fprintf(output, "%" PRIu64 " ", values[i]);
+        }
+
+        if (stat_mode == 0) {
+            fprintf(output, "%ld ", stat_data);
+        }
+
+        fprintf(output, "\n");
+
+        if (application != NULL) {
+            break;
+        }
+
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        usleep(1000 * 1000 / frequency - (ts.tv_nsec / 1000) % (1000 * 1000 / frequency));
+    }
+
+    for (unsigned int i = 0; i < nb_sources; i++) {
+        cleaner[i](states[i]);
+    }
+
+    if (nb_sources > 0) {
+        free(getter);
+        free(cleaner);
+        free(labels);
+        free(values);
+        free(states);
+    }
+}
+
+
+
+
diff --git a/src/network.c b/src/network.c
index 647b4b3..6896efc 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1,128 +1,128 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-#include <unistd.h>
-#include <fcntl.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdint.h>
-
-#define NB_SENSOR 4
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-static char *route = "/proc/net/route";
-struct network_t {
-    uint64_t values[NB_SENSOR];
-    uint64_t tmp_values[NB_SENSOR];
-    int sources[NB_SENSOR];
-};
-
-unsigned int _get_network(uint64_t *results, int *sources)
-{
-    if(sources==NULL)
-        return 0;
-    char buffer[128];
-    for(int i=0; i<NB_SENSOR; i++) {
-        if (pread(sources[i], buffer, 127, 0) < 0) {
-            perror("pread");
-            exit(1);
-        }
-
-        results[i] = strtoull(buffer, NULL, 10);
-    }
-    return NB_SENSOR;
-}
-
-
-
-unsigned int init_network(char *dev, void **ptr)
-{
-    if(dev==NULL)
-        return 0;
-
-    if(strcmp(dev,"X")==0) {
-        int fd = open(route, O_RDONLY);
-        if (fd < 0) {
-            fprintf(stderr, "%s ", route);
-            perror("open");
-            exit(1);
-        }
-        char buffer[1000];
-
-        if ( read(fd, buffer, 999) < 0 ) {
-            perror("read");
-            close(fd);
-            exit(1);
-        }
-
-        char *start_of_dev = index(buffer, '\n')+1;
-        char *end_of_dev = index(start_of_dev, '\t');
-        *end_of_dev='\0';
-        dev = start_of_dev;
-        close(fd);
-    }
-
-    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-                         "/sys/class/net/%s/statistics/rx_bytes",
-                         "/sys/class/net/%s/statistics/tx_packets",
-                         "/sys/class/net/%s/statistics/tx_bytes"
-                        };
-
-    struct network_t *state = malloc(sizeof(struct network_t));
-
-    char buffer2[256];
-    for(int i=0; i<NB_SENSOR; i++) {
-        sprintf(buffer2, filenames[i], dev);
-        state->sources[i] = open(buffer2, O_RDONLY);
-    }
-    *ptr = (void *) state;
-    _get_network(state->values, state->sources);
-
-    return NB_SENSOR;
-}
-
-unsigned int get_network(uint64_t *results, void *ptr)
-{
-    struct network_t *state = (struct network_t *) ptr;
-    _get_network(state->tmp_values, state->sources);
-    for(int i=0; i<NB_SENSOR; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
-
-    memcpy(state->values, state->tmp_values, NB_SENSOR*sizeof(uint64_t));
-    return NB_SENSOR;
-}
-
-void clean_network(void *ptr)
-{
-    struct network_t *state = (struct network_t *) ptr;
-    if(state==NULL)
-        return;
-    for(int i=0; i<NB_SENSOR; i++)
-        close(state->sources[i]);
-    free(state);
-}
-
-char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void *none)
-{
-    UNUSED(none);
-    for(int i=0; i<NB_SENSOR; i++)
-        labels[i] = _labels_network[i];
-}
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+
+#define NB_SENSOR 4
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+static char *route = "/proc/net/route";
+struct network_t {
+    uint64_t values[NB_SENSOR];
+    uint64_t tmp_values[NB_SENSOR];
+    int sources[NB_SENSOR];
+};
+
+unsigned int _get_network(uint64_t *results, int *sources)
+{
+    if(sources==NULL)
+        return 0;
+    char buffer[128];
+    for(int i=0; i<NB_SENSOR; i++) {
+        if (pread(sources[i], buffer, 127, 0) < 0) {
+            perror("pread");
+            exit(1);
+        }
+
+        results[i] = strtoull(buffer, NULL, 10);
+    }
+    return NB_SENSOR;
+}
+
+
+
+unsigned int init_network(char *dev, void **ptr)
+{
+    if(dev==NULL)
+        return 0;
+
+    if(strcmp(dev,"X")==0) {
+        int fd = open(route, O_RDONLY);
+        if (fd < 0) {
+            fprintf(stderr, "%s ", route);
+            perror("open");
+            exit(1);
+        }
+        char buffer[1000];
+
+        if ( read(fd, buffer, 999) < 0 ) {
+            perror("read");
+            close(fd);
+            exit(1);
+        }
+
+        char *start_of_dev = index(buffer, '\n')+1;
+        char *end_of_dev = index(start_of_dev, '\t');
+        *end_of_dev='\0';
+        dev = start_of_dev;
+        close(fd);
+    }
+
+    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
+                         "/sys/class/net/%s/statistics/rx_bytes",
+                         "/sys/class/net/%s/statistics/tx_packets",
+                         "/sys/class/net/%s/statistics/tx_bytes"
+                        };
+
+    struct network_t *state = malloc(sizeof(struct network_t));
+
+    char buffer2[256];
+    for(int i=0; i<NB_SENSOR; i++) {
+        sprintf(buffer2, filenames[i], dev);
+        state->sources[i] = open(buffer2, O_RDONLY);
+    }
+    *ptr = (void *) state;
+    _get_network(state->values, state->sources);
+
+    return NB_SENSOR;
+}
+
+unsigned int get_network(uint64_t *results, void *ptr)
+{
+    struct network_t *state = (struct network_t *) ptr;
+    _get_network(state->tmp_values, state->sources);
+    for(int i=0; i<NB_SENSOR; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
+
+    memcpy(state->values, state->tmp_values, NB_SENSOR*sizeof(uint64_t));
+    return NB_SENSOR;
+}
+
+void clean_network(void *ptr)
+{
+    struct network_t *state = (struct network_t *) ptr;
+    if(state==NULL)
+        return;
+    for(int i=0; i<NB_SENSOR; i++)
+        close(state->sources[i]);
+    free(state);
+}
+
+char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
+void label_network(char **labels, void *none)
+{
+    UNUSED(none);
+    for(int i=0; i<NB_SENSOR; i++)
+        labels[i] = _labels_network[i];
+}
diff --git a/src/network.h b/src/network.h
index 3ba9ae5..b770560 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,25 +1,25 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_network(char *, void **);
-unsigned int get_network(uint64_t *results, void *);
-void clean_network(void *);
-void label_network(char **labels, void *);
-
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_network(char *, void **);
+unsigned int get_network(uint64_t *results, void *);
+void clean_network(void *);
+void label_network(char **labels, void *);
+
diff --git a/src/rapl.c b/src/rapl.c
index 30d38c1..eb4666a 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -1,174 +1,174 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <powercap/powercap-rapl.h>
-
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-struct _rapl_t {
-    powercap_rapl_pkg *pkgs;
-    uint32_t nb_pkgs;
-    uint32_t nb;
-    char **names;
-    uint32_t *zones;
-    uint32_t *packages;
-    uint64_t *values;
-    uint64_t *tmp_values;
-};
-
-typedef struct _rapl_t _rapl_t;
-
-
-
-
-
-
-const int nb_zones = 3;
-const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_CORE,   POWERCAP_RAPL_ZONE_DRAM};
-
-
-#define MAX_LEN_NAME 100
-
-// values [zone + package *nbzones] microjoules
-void _get_rapl(uint64_t *values, _rapl_t *rapl)
-{
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-#ifdef DEBUG
-        int ret =
-#endif
-            powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
-                                        rapl->zones[i],
-                                        &values[i]);
-#ifdef DEBUG
-        printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
-#endif
-    }
-}
-
-unsigned int init_rapl(char *none, void **ptr)
-{
-    UNUSED(none);
-    // get number of processor sockets
-    _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
-    rapl->nb = 0;
-    rapl->packages = NULL;
-    rapl->zones = NULL;
-
-    rapl->nb_pkgs = powercap_rapl_get_num_instances();
-    //rapl->nb_pkgs = powercap_rapl_get_num_packages();
-
-    if (rapl->nb_pkgs == 0) {
-        perror("no packages found (maybe the kernel module isn't loaded?)");
-        exit(-1);
-    }
-    rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
-            perror("powercap_rapl_init, check access (root needed ?)");
-            exit(-1);
-        }
-
-    rapl->names = NULL;
-
-    char _name[MAX_LEN_NAME+1];
-    char _name2[MAX_LEN_NAME+11];
-
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
-        for(unsigned int zone=0; zone < nb_zones; zone++) {
-            int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-                                              _name, MAX_LEN_NAME);
-            if (length>0) {
-
-                sprintf(_name2, "%s%u", _name, package);
-
-                rapl->nb++;
-                rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
-                rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
-                rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
-                rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
-
-                strcpy(rapl->names[rapl->nb-1], _name2);
-                rapl->zones[rapl->nb-1] = rapl_zones[zone];
-                rapl->packages[rapl->nb-1] = package;
-            }
-#ifdef DEBUG
-            printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
-#endif
-        }
-    }
-#ifdef DEBUG
-    printf("Result of init\n");
-    for(unsigned int i=0; i<rapl->nb; i++)
-        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
-#endif
-
-    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
-
-    _get_rapl(rapl->values, rapl);
-
-    *ptr = (void *)rapl;
-    return rapl->nb;
-}
-
-
-
-unsigned int get_rapl(uint64_t *results, void *ptr)
-{
-    _rapl_t *state = (_rapl_t *) ptr;
-    _get_rapl(state->tmp_values, state);
-    for(unsigned int i=0; i<state->nb; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
-
-    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-    return state->nb;
-}
-
-
-
-
-void clean_rapl(void *ptr)
-{
-    _rapl_t *rapl = (_rapl_t *) ptr;
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_destroy(&rapl->pkgs[package]))
-            perror("powercap_rapl_destroy");
-    for (unsigned int elem=0; elem<rapl->nb; elem++)
-        free(rapl->names[elem]);
-
-    free(rapl->names);
-    free(rapl->pkgs);
-    free(rapl->zones);
-    free(rapl->packages);
-    free(rapl->values);
-    free(rapl->tmp_values);
-    free(rapl);
-}
-
-void label_rapl(char **labels, void *ptr)
-{
-    _rapl_t *rapl = (_rapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        labels[i] = rapl->names[i];
-}
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <powercap/powercap-rapl.h>
+
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+struct _rapl_t {
+    powercap_rapl_pkg *pkgs;
+    uint32_t nb_pkgs;
+    uint32_t nb;
+    char **names;
+    uint32_t *zones;
+    uint32_t *packages;
+    uint64_t *values;
+    uint64_t *tmp_values;
+};
+
+typedef struct _rapl_t _rapl_t;
+
+
+
+
+
+
+const int nb_zones = 3;
+const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_CORE,   POWERCAP_RAPL_ZONE_DRAM};
+
+
+#define MAX_LEN_NAME 100
+
+// values [zone + package *nbzones] microjoules
+void _get_rapl(uint64_t *values, _rapl_t *rapl)
+{
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+#ifdef DEBUG
+        int ret =
+#endif
+            powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
+                                        rapl->zones[i],
+                                        &values[i]);
+#ifdef DEBUG
+        printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
+#endif
+    }
+}
+
+unsigned int init_rapl(char *none, void **ptr)
+{
+    UNUSED(none);
+    // get number of processor sockets
+    _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
+    rapl->nb = 0;
+    rapl->packages = NULL;
+    rapl->zones = NULL;
+
+    rapl->nb_pkgs = powercap_rapl_get_num_instances();
+    //rapl->nb_pkgs = powercap_rapl_get_num_packages();
+
+    if (rapl->nb_pkgs == 0) {
+        perror("no packages found (maybe the kernel module isn't loaded?)");
+        exit(-1);
+    }
+    rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
+        if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
+            perror("powercap_rapl_init, check access (root needed ?)");
+            exit(-1);
+        }
+
+    rapl->names = NULL;
+
+    char _name[MAX_LEN_NAME+1];
+    char _name2[MAX_LEN_NAME+11];
+
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
+        for(unsigned int zone=0; zone < nb_zones; zone++) {
+            int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
+                                              _name, MAX_LEN_NAME);
+            if (length>0) {
+
+                sprintf(_name2, "%s%u", _name, package);
+
+                rapl->nb++;
+                rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
+                rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
+                rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
+                rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+
+                strcpy(rapl->names[rapl->nb-1], _name2);
+                rapl->zones[rapl->nb-1] = rapl_zones[zone];
+                rapl->packages[rapl->nb-1] = package;
+            }
+#ifdef DEBUG
+            printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
+#endif
+        }
+    }
+#ifdef DEBUG
+    printf("Result of init\n");
+    for(unsigned int i=0; i<rapl->nb; i++)
+        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
+#endif
+
+    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
+    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
+
+    _get_rapl(rapl->values, rapl);
+
+    *ptr = (void *)rapl;
+    return rapl->nb;
+}
+
+
+
+unsigned int get_rapl(uint64_t *results, void *ptr)
+{
+    _rapl_t *state = (_rapl_t *) ptr;
+    _get_rapl(state->tmp_values, state);
+    for(unsigned int i=0; i<state->nb; i++)
+        results[i] = state->tmp_values[i] - state->values[i];
+
+    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
+    return state->nb;
+}
+
+
+
+
+void clean_rapl(void *ptr)
+{
+    _rapl_t *rapl = (_rapl_t *) ptr;
+    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
+        if (powercap_rapl_destroy(&rapl->pkgs[package]))
+            perror("powercap_rapl_destroy");
+    for (unsigned int elem=0; elem<rapl->nb; elem++)
+        free(rapl->names[elem]);
+
+    free(rapl->names);
+    free(rapl->pkgs);
+    free(rapl->zones);
+    free(rapl->packages);
+    free(rapl->values);
+    free(rapl->tmp_values);
+    free(rapl);
+}
+
+void label_rapl(char **labels, void *ptr)
+{
+    _rapl_t *rapl = (_rapl_t *) ptr;
+    for(unsigned int i=0; i<rapl->nb; i++)
+        labels[i] = rapl->names[i];
+}
diff --git a/src/rapl.h b/src/rapl.h
index 74cc515..78006d3 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -1,25 +1,25 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_rapl(char *, void **);
-unsigned int get_rapl(uint64_t *results, void *);
-void clean_rapl(void *);
-void label_rapl(char **labels, void *);
-
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_rapl(char *, void **);
+unsigned int get_rapl(uint64_t *results, void *);
+void clean_rapl(void *);
+void label_rapl(char **labels, void *);
+
diff --git a/src/temperature.c b/src/temperature.c
index cdef158..7f673b4 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -1,155 +1,155 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stdio.h>
-#include <stdint.h>
-
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-struct temperature_t {
-    char **label_list;
-    int *fid_list;
-    int nb_elem;
-};
-
-int get_string(char *filename, char *buffer, int max_size)
-{
-    int fid = open(filename, O_RDONLY);
-    //printf("Tries to open : %s : %d\n", filename, fid);
-    if(fid == -1)
-        return -1;
-
-    int nb = read(fid, buffer, max_size);
-    if(nb == -1) {
-        close(fid);
-        return -1;
-    }
-
-    buffer[nb]=0;
-    close(fid);
-    return 0;
-}
-
-void add_to_list(char ***list_name, char *source, int nb_elem)
-{
-    //printf("Adds: %s\n", source);
-    *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
-    (*list_name)[nb_elem] = malloc(strlen(source)+1);
-    strcpy((*list_name)[nb_elem], source);
-
-}
-
-void add_temperature_sensor(int id_rep, struct temperature_t *state)
-{
-    static int key=0;
-    static char buffer_filename[512];
-    static char buffer_label[512];
-
-    int delta = sprintf(buffer_label, "Temp_%d_", key);
-
-    for(int i=1;; i++) {
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
-        if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
-            break;
-
-        for(unsigned int pos = 0; pos < strlen(buffer_label); pos++) {
-            if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
-            if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
-        }
-        add_to_list(&state->label_list, buffer_label, state->nb_elem);
-
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
-        state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
-        int fd = open(buffer_filename, O_RDONLY);
-        if (fd < 0) {
-            fprintf(stderr, "%s ", buffer_filename);
-            perror("open");
-            exit(1);
-        }
-        state->fid_list[state->nb_elem] = fd;
-        state->nb_elem++;
-        // printf("%s : %s\n", buffer_label, buffer_filename);
-    }
-
-    key++;
-}
-
-unsigned int init_temperature(char *args, void **ptr)
-{
-    UNUSED(args);
-    struct temperature_t *state = malloc(sizeof(struct temperature_t));
-    state->nb_elem = 0;
-    state->label_list = NULL;
-    state->fid_list = NULL;
-
-    char base_name[] = "/sys/class/hwmon/hwmon%d/name";
-    static char name[512];
-    static char buffer[512];
-
-    int i = 0;
-    sprintf(name, base_name, i);
-    while(get_string(name, buffer, 8) != -1) {
-        if (strcmp(buffer, "coretemp")==0)
-            add_temperature_sensor(i, state);
-
-        i++;
-        sprintf(name, base_name, i);
-    }
-    *ptr = (void *) state;
-    return state->nb_elem;
-}
-
-unsigned int get_temperature(uint64_t *results, void *ptr)
-{
-    struct temperature_t *state = (struct temperature_t *)ptr;
-    static char buffer[512];
-    for(int i=0; i<state->nb_elem; i++) {
-        if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
-            perror("pread");
-            exit(1);
-        }
-        results[i] = strtoull(buffer, NULL, 10);
-    }
-    return state->nb_elem;
-}
-
-void clean_temperature(void *ptr)
-{
-    struct temperature_t *state = (struct temperature_t *)ptr;
-
-    for(int i=0; i<state->nb_elem; i++) {
-        free(state->label_list[i]);
-        close(state->fid_list[i]);
-    }
-    free(state->label_list);
-    free(state->fid_list);
-    free(state);
-}
-
-void label_temperature(char **labels, void *ptr)
-{
-    struct temperature_t *state = (struct temperature_t *)ptr;
-    for(int i=0; i<state->nb_elem; i++)
-        labels[i] = state->label_list[i];
-}
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdint.h>
+
+#define UNUSED(expr) do { (void)(expr); } while (0)
+
+struct temperature_t {
+    char **label_list;
+    int *fid_list;
+    int nb_elem;
+};
+
+int get_string(char *filename, char *buffer, int max_size)
+{
+    int fid = open(filename, O_RDONLY);
+    //printf("Tries to open : %s : %d\n", filename, fid);
+    if(fid == -1)
+        return -1;
+
+    int nb = read(fid, buffer, max_size);
+    if(nb == -1) {
+        close(fid);
+        return -1;
+    }
+
+    buffer[nb]=0;
+    close(fid);
+    return 0;
+}
+
+void add_to_list(char ***list_name, char *source, int nb_elem)
+{
+    //printf("Adds: %s\n", source);
+    *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
+    (*list_name)[nb_elem] = malloc(strlen(source)+1);
+    strcpy((*list_name)[nb_elem], source);
+
+}
+
+void add_temperature_sensor(int id_rep, struct temperature_t *state)
+{
+    static int key=0;
+    static char buffer_filename[512];
+    static char buffer_label[512];
+
+    int delta = sprintf(buffer_label, "Temp_%d_", key);
+
+    for(int i=1;; i++) {
+        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+        if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
+            break;
+
+        for(unsigned int pos = 0; pos < strlen(buffer_label); pos++) {
+            if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
+            if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+        }
+        add_to_list(&state->label_list, buffer_label, state->nb_elem);
+
+        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+        state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
+        int fd = open(buffer_filename, O_RDONLY);
+        if (fd < 0) {
+            fprintf(stderr, "%s ", buffer_filename);
+            perror("open");
+            exit(1);
+        }
+        state->fid_list[state->nb_elem] = fd;
+        state->nb_elem++;
+        // printf("%s : %s\n", buffer_label, buffer_filename);
+    }
+
+    key++;
+}
+
+unsigned int init_temperature(char *args, void **ptr)
+{
+    UNUSED(args);
+    struct temperature_t *state = malloc(sizeof(struct temperature_t));
+    state->nb_elem = 0;
+    state->label_list = NULL;
+    state->fid_list = NULL;
+
+    char base_name[] = "/sys/class/hwmon/hwmon%d/name";
+    static char name[512];
+    static char buffer[512];
+
+    int i = 0;
+    sprintf(name, base_name, i);
+    while(get_string(name, buffer, 8) != -1) {
+        if (strcmp(buffer, "coretemp")==0)
+            add_temperature_sensor(i, state);
+
+        i++;
+        sprintf(name, base_name, i);
+    }
+    *ptr = (void *) state;
+    return state->nb_elem;
+}
+
+unsigned int get_temperature(uint64_t *results, void *ptr)
+{
+    struct temperature_t *state = (struct temperature_t *)ptr;
+    static char buffer[512];
+    for(int i=0; i<state->nb_elem; i++) {
+        if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
+            perror("pread");
+            exit(1);
+        }
+        results[i] = strtoull(buffer, NULL, 10);
+    }
+    return state->nb_elem;
+}
+
+void clean_temperature(void *ptr)
+{
+    struct temperature_t *state = (struct temperature_t *)ptr;
+
+    for(int i=0; i<state->nb_elem; i++) {
+        free(state->label_list[i]);
+        close(state->fid_list[i]);
+    }
+    free(state->label_list);
+    free(state->fid_list);
+    free(state);
+}
+
+void label_temperature(char **labels, void *ptr)
+{
+    struct temperature_t *state = (struct temperature_t *)ptr;
+    for(int i=0; i<state->nb_elem; i++)
+        labels[i] = state->label_list[i];
+}
diff --git a/src/temperature.h b/src/temperature.h
index e49e416..ac8e34b 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_temperature(char *, void **);
-unsigned int get_temperature(uint64_t *results, void *);
-void clean_temperature(void *);
-void label_temperature(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_temperature(char *, void **);
+unsigned int get_temperature(uint64_t *results, void *);
+void clean_temperature(void *);
+void label_temperature(char **labels, void *);
-- 
GitLab


From 01973a528ebefac91d183adc2919fd865f5591e4 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 16:39:09 +0100
Subject: [PATCH 020/229] add a dummy counter as an example

---
 doc/counter_ex.c | 23 +++++++++++++++++++++++
 doc/counter_ex.h |  7 +++++++
 2 files changed, 30 insertions(+)
 create mode 100644 doc/counter_ex.c
 create mode 100644 doc/counter_ex.h

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
new file mode 100644
index 0000000..3dda06d
--- /dev/null
+++ b/doc/counter_ex.c
@@ -0,0 +1,23 @@
+#include "counter_ex.h"
+
+static int acc;
+
+unsigned int
+init_acc(char *a, void **b)
+{
+	acc = 0;
+}
+
+unsigned int
+get_acc(uint64_t *results, void *none)
+{
+	UNUSED(none);
+	return a++;
+}
+
+void
+label_acc(char **labels, void *none)
+{
+	UNUSED(none);
+	labels[0] = "acc";
+}
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
new file mode 100644
index 0000000..d85573b
--- /dev/null
+++ b/doc/counter_ex.h
@@ -0,0 +1,7 @@
+/*
+ * Example of a basic counter: an accumulator
+**/
+
+unsigned int init_acc(char*, void**);
+unsigned int get_acc(uint64_t *results, void*);
+void label_counter(char **labels, void*);
-- 
GitLab


From ae671211dc1c30772861775cfb57d913e146757a Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 16:48:16 +0100
Subject: [PATCH 021/229] add a man page

---
 README.md     |  70 ++++++++++++++-------------------
 doc/mojitos.1 | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 137 insertions(+), 40 deletions(-)
 create mode 100644 doc/mojitos.1

diff --git a/README.md b/README.md
index 2cf04f1..a344fe0 100644
--- a/README.md
+++ b/README.md
@@ -1,29 +1,19 @@
 # MOJITO/S
 
 An Open Source System, Energy and Network Monitoring Tools at the O/S level
-
-## Documentation
-
 MojitO/S runs on GNU/Linux
-Usage
 
-```python
-Usage : ./mojitos [-t time] [-f freq] [-r] [-p perf_list] [-l]  \
+## Usage
+
+```bash
+Usage : mojitos [-Rsu] [-t time] [-f freq] [-p perf_list]  \
                   [-u] [-d network_device] [-o logfile] [-e command arguments...]
+        mojitos [-l]
 ```
 
-Timing
-- If time is 0 then mojitos loops infinitively
-- If -e is present, time and freq are not used
+For more information, see [mojitos(1)](doc/mojitos.1) under [doc/](doc).
 
-Configuration
-- -r activates RAPL (deprecated)
-- -R activates RAPL
-- -p activates performance counters. perf_list is coma separated list of performance counters without space.
-- -l lists the possible performance counters and quits
-- -d activates network monitoring
-- -u activates system-level load monitoring
-- -s activates statistics of overhead in nanoseconds
+## License
 
 MojitO/S is published under the GPL3 license and is part of the [Energumen Project](https://www.irit.fr/energumen/)
 
@@ -59,42 +49,42 @@ sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
 RAPL values during 2 seconds with a frequency of 2 Hz
 ```bash
 $ ./mojitos -t 2 -f 2 -r
-#timestamp package-00 core0 dram0 
-1036389.135659868 10986 2869 1526 
-1036389.500183551 1291440 255736 515562 
-1036390.000754048 1333553 228393 689513 
-1036390.500113978 1581967 267944 701536 
+#timestamp package-00 core0 dram0
+1036389.135659868 10986 2869 1526
+1036389.500183551 1291440 255736 515562
+1036390.000754048 1333553 228393 689513
+1036390.500113978 1581967 267944 701536
 ```
 Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
 
 ```bash
 $ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
-#timestamp cpu_cycles cache_ll page_faults 
-1036846.351749455 571199 1232 0 
-1036847.001098880 348173344 2451387 872 
-1036848.000166158 388112961 2509305 791 
-1036849.000191883 402255979 2625283 799 
+#timestamp cpu_cycles cache_ll page_faults
+1036846.351749455 571199 1232 0
+1036847.001098880 348173344 2451387 872
+1036848.000166158 388112961 2509305 791
+1036849.000191883 402255979 2625283 799
 ```
 
 Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
 ```bash
 $ ./mojitos -t 0 -f 1 -d enp0s25
-#timestamp rxp rxb txp txb 
-1036559.277376027 0 0 0 0 
-1036560.000161101 4 581 2 179 
-1036561.000083968 178 268675 55 4954 
-1036562.000076162 11 1010 5 510 
-1036563.000069724 17 1643 12 3602 
-1036564.000113394 990 1493008 369 27299 
+#timestamp rxp rxb txp txb
+1036559.277376027 0 0 0 0
+1036560.000161101 4 581 2 179
+1036561.000083968 178 268675 55 4954
+1036562.000076162 11 1010 5 510
+1036563.000069724 17 1643 12 3602
+1036564.000113394 990 1493008 369 27299
 ```
 
 Overhead of the monitoring for RAPL and cpu_cycle
 ```bash
 $ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
-#timestamp cpu_cycles package-00 core0 dram0 overhead 
-1036988.197227391 162214 19898 4944 1586 149612 
-1036989.000151326 332613664 2513116 379577 1115171 739573 
-1036990.000116433 482150700 3321341 587218 1380673 315719 
-1036991.000182835 525984292 3592582 691221 1385982 272182 
-1036992.000165117 397678789 2770561 444030 1375729 510379 
+#timestamp cpu_cycles package-00 core0 dram0 overhead
+1036988.197227391 162214 19898 4944 1586 149612
+1036989.000151326 332613664 2513116 379577 1115171 739573
+1036990.000116433 482150700 3321341 587218 1380673 315719
+1036991.000182835 525984292 3592582 691221 1385982 272182
+1036992.000165117 397678789 2770561 444030 1375729 510379
 ```
diff --git a/doc/mojitos.1 b/doc/mojitos.1
new file mode 100644
index 0000000..37e1876
--- /dev/null
+++ b/doc/mojitos.1
@@ -0,0 +1,107 @@
+.Dd January 9, 2023
+.Dt MOJITOS 1
+.Os
+.Sh NAME
+.Nm mojitos
+.Nd An open source system, energy and network monitoring tool.
+.Sh SYNOPSIS
+.Nm mojitos
+.Op Fl rsu
+.Op Fl t Ar time
+.Op Fl f Ar freq
+.Op Fl p Ar perf_list
+.Op Fl d Ar net_device
+.Op Fl o Ar logfile
+.Op Fl e Ar cmd ...
+.Nm mojitos
+.Op Fl l
+.Sh DESCRIPTION
+.Nm
+enables to monitor the system, its energy comsumption and the network activity, at the OS level.
+It runs on GNU/Linux.
+.Pp
+.Nm
+supports the following options:
+.Bl -tag -width Ds
+.It Fl s
+Enable overhead statistics (in nanoseconds).
+.It Fl u
+Enable system-level load monitoring.
+.It Fl r
+Enable RAPL.
+.It Fl p Ar perf_list
+Enable performance counters.
+The argument is a coma separated list of performance counters.
+.It Fl d Ar net_device
+Enable network monitoring.
+.It Fl l
+List the available performance counters and quit.
+.It Fl t Ar time
+Set duration value (in seconds). If 0, then loops indefinitely.
+.It Fl f Ar freq
+Set amount of measurements per second.
+.It Fl e Ar cmd ...
+Execute a command with optional arguments.
+If this option is used, any usage of -t or -f is ignored.
+.El
+.Sh EXIT STATUS
+.Ex
+.Sh EXAMPLES
+RAPL values during 2 seconds with a frequency of 2Hz:
+.Bd -literal -offset indent
+$ mojitos -t 2 -f 2 -r
+#timestamp package-00 core0 dram0
+1036389.135659868 10986 2869 1526
+1036389.500183551 1291440 255736 515562
+1036390.000754048 1333553 228393 689513
+1036390.500113978 1581967 267944 701536
+.Ed
+.Pp
+Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds
+with a frequency of 1Hz.
+In the context of cache performance counters (as with "cache_ll_r_a"),
+ _r and _w suffixes mean respectively read and write,
+while the _a, _m and _p ones mean respectively access, miss and pending.
+.Pp
+.Bd -literal -offset indent
+$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
+#timestamp cpu_cycles cache_ll page_faults
+1036846.351749455 571199 1232 0
+1036847.001098880 348173344 2451387 872
+1036848.000166158 388112961 2509305 791
+1036849.000191883 402255979 2625283 799
+.Ed
+.Pp
+Network values with no time limit with a frequency of 1Hz.
+rxp and txp are the number of received and sent packets, while rxb and txp are
+the number of received and sent bytes.
+.Pp
+.Bd -literal -offset indent
+$ ./mojitos -t 0 -f 1 -d enp0s25
+#timestamp rxp rxb txp txb
+1036559.277376027 0 0 0 0
+1036560.000161101 4 581 2 179
+1036561.000083968 178 268675 55 4954
+1036562.000076162 11 1010 5 510
+1036563.000069724 17 1643 12 3602
+1036564.000113394 990 1493008 369 27299
+.Ed
+.Pp
+overhead of the monitoring when using RAPL and the cpu_cycle performance counter:
+.Pp
+.Bd -literal -offset indent
+$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
+#timestamp cpu_cycles package-00 core0 dram0 overhead
+1036988.197227391 162214 19898 4944 1586 149612
+1036989.000151326 332613664 2513116 379577 1115171 739573
+1036990.000116433 482150700 3321341 587218 1380673 315719
+1036991.000182835 525984292 3592582 691221 1385982 272182
+1036992.000165117 397678789 2770561 444030 1375729 510379
+.Ed
+.Sh SEE ALSO
+.Xr perf 1 ,
+.Xr lscpu 1 ,
+.Xr sysfs 5 ,
+.Xr proc 5
+.Sh BUGS
+Yes.
-- 
GitLab


From 598d2f8e15d8b16bcf1e57efdef16933a793b783 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 9 Jan 2023 16:48:45 +0100
Subject: [PATCH 022/229] msc changes (mostly reformating)

---
 src/counters.c       |  40 +++++++-----
 src/counters_group.c | 143 +++++++++++++++++++++++++++++++++++++++++++
 src/frapl.c          |  14 +++--
 src/infiniband.c     |   6 +-
 src/load.c           |  16 ++---
 src/mojitos.c        |  10 +--
 src/network.c        |  32 ++++++----
 src/rapl.c           |  34 ++++++----
 src/temperature.c    |  20 +++---
 9 files changed, 249 insertions(+), 66 deletions(-)
 create mode 100644 src/counters_group.c

diff --git a/src/counters.c b/src/counters.c
index 5a24eed..244e60c 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -44,8 +44,10 @@ typedef struct _counter_t *counter_t;
 
 void show_all_counters()
 {
-    for(unsigned int i=0; i<nb_counter_option; i++)
-        printf("%s\n", perf_static_info[i].name);
+    for (unsigned int i = 0; i < nb_counter_option; i++)
+        {
+            printf("%s\n", perf_static_info[i].name);
+        }
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
@@ -134,16 +136,20 @@ void clean_counters(void *ptr)
 
 void start_counters(counter_t counters)
 {
-    for(int counter=0; counter<counters->nbperf; counter++)
-        for(int core=0; core<counters->nbcores; core++)
-            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
+    for (int counter = 0; counter < counters->nbperf; counter++)
+        for (int core = 0; core < counters->nbcores; core++)
+            {
+                ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
+            }
 }
 
 void reset_counters(counter_t counters)
 {
-    for(int counter=0; counter<counters->nbperf; counter++)
-        for(int core=0; core<counters->nbcores; core++)
-            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
+    for (int counter = 0; counter < counters->nbperf; counter++)
+        for (int core = 0; core < counters->nbcores; core++)
+            {
+                ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
+            }
 }
 
 void _get_counters(counter_t counters, uint64_t *values)
@@ -170,7 +176,7 @@ void _get_counters(counter_t counters, uint64_t *values)
 unsigned int init_counters(char *args, void **state)
 {
     int nb_perf;
-    int *perf_indexes=NULL;
+    int *perf_indexes = NULL;
 
     perf_event_list(args, &nb_perf, &perf_indexes);
 
@@ -182,8 +188,8 @@ unsigned int init_counters(char *args, void **state)
     free(perf_key);
 
     fd->perf_indexes = perf_indexes;
-    fd->counters_values = malloc(nb_perf*sizeof(uint64_t));
-    fd->tmp_counters_values = malloc(nb_perf*sizeof(uint64_t));
+    fd->counters_values = malloc(nb_perf * sizeof(uint64_t));
+    fd->tmp_counters_values = malloc(nb_perf * sizeof(uint64_t));
     start_counters(fd);
     _get_counters(fd, fd->counters_values);
     *state = (void *) fd;
@@ -196,8 +202,10 @@ unsigned int get_counters(uint64_t *results, void *ptr)
     counter_t state = (counter_t) ptr;
 
     _get_counters(state, state->tmp_counters_values);
-    for(int i=0; i<state->nbperf; i++)
-        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+    for (int i = 0; i < state->nbperf; i++)
+        {
+            results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+        }
 
     memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
     return state->nbperf;
@@ -206,7 +214,9 @@ unsigned int get_counters(uint64_t *results, void *ptr)
 void label_counters(char **labels, void *ptr)
 {
     counter_t state = (counter_t) ptr;
-    for(int i=0; i<state->nbperf; i++)
-        labels[i] = perf_static_info[state->perf_indexes[i]].name;
+    for (int i = 0; i < state->nbperf; i++)
+        {
+            labels[i] = perf_static_info[state->perf_indexes[i]].name;
+        }
 
 }
diff --git a/src/counters_group.c b/src/counters_group.c
new file mode 100644
index 0000000..8a4de79
--- /dev/null
+++ b/src/counters_group.c
@@ -0,0 +1,143 @@
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <linux/perf_event.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <asm/unistd.h>
+
+#include "counters.h"
+
+struct _counter_t
+{
+    int nbcores;
+    int nbperf;
+    int *counters;
+};
+
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                            int cpu, int group_fd, unsigned long flags)
+{
+    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+    if (res == -1)
+        {
+            perror("perf_event_open");
+            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+            exit(EXIT_FAILURE);
+        }
+    return res;
+}
+
+counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+{
+    struct perf_event_attr pe;
+    struct _counter_t *counters = malloc(sizeof(struct _counter_t));
+
+    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
+    counters->nbcores = nbcores;
+    counters->nbperf = nb_perf;
+    memset(&pe, 0, sizeof(struct perf_event_attr));
+    pe.size = sizeof(struct perf_event_attr);
+    pe.disabled = 1;
+
+    pe.read_format = PERF_FORMAT_GROUP;
+    counters->counters = malloc((nbcores + 1) * sizeof(int));
+
+    for (int core = 0; core < nbcores; core++)
+        {
+            counters->counters[core] = -1;
+            for (int idperf = 0; idperf < nb_perf; idperf ++)
+                {
+                    pe.type = types[idperf];
+                    pe.config = names[idperf];
+                    int res = perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
+                    if (counters->counters[core] == -1)
+                        {
+                            counters->counters[core] = res;
+                        }
+                }
+        }
+    return counters;
+}
+
+void clean_counters(counter_t counters)
+{
+    for (int core = 0; core < counters->nbcores; core++)
+        {
+            close(counters->counters[core]);
+        }
+    free(counters->counters);
+    free(counters);
+}
+
+void start_counters(counter_t counters)
+{
+    for (int core = 0; core < counters->nbcores; core++)
+        {
+            ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
+        }
+}
+void reset_counters(counter_t counters)
+{
+    for (int core = 0; core < counters->nbcores; core++)
+        {
+            ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
+        }
+}
+
+struct read_format
+{
+    uint64_t nr;
+    struct
+    {
+        uint64_t value;
+    } values[];
+};
+
+void get_counters(counter_t counters, long long *values)
+{
+    int nb_perf = counters->nbperf;
+    size_t buffer_size = sizeof(uint64_t) * (1 + nb_perf);
+    struct read_format *buffer = NULL;
+    if (buffer == NULL)
+        {
+            buffer = malloc(buffer_size);
+        }
+
+    memset(values, 0, nb_perf * sizeof(long long));
+
+    for (int core = 0; core < counters->nbcores; core++)
+        {
+            if (-1 == read(counters->counters[core], buffer, buffer_size))
+                {
+                    perror("PB Lecture resultat");
+                    exit(EXIT_FAILURE);
+                }
+            for (int idperf = 0; idperf <= nb_perf; idperf++)
+                {
+                    values[idperf] += buffer->values[idperf].value;
+                }
+        }
+    reset_counters(counters);
+}
diff --git a/src/frapl.c b/src/frapl.c
index 9874a12..ab17b14 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -40,7 +40,7 @@ char *get_frapl_string(const char *filename)
     char *result = malloc(MAX_HEADER);
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
-    result[nb-1] = 0;
+    result[nb - 1] = 0;
     return (result);
 }
 
@@ -49,7 +49,7 @@ void test_append(char *name, int i)
     //char last = name[strlen(name)-1];
     //if (last>='0' && last <= '9')
     //  return;
-    sprintf(name+strlen(name), "%d", i);
+    sprintf(name + strlen(name), "%d", i);
 }
 
 
@@ -70,8 +70,8 @@ void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
     rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
     rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
 
-    rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
-    strcpy(rapl->names[rapl->nb-1], name);
+    rapl->names[rapl->nb - 1] = malloc(strlen(name) + 1);
+    strcpy(rapl->names[rapl->nb - 1], name);
     //printf("%s\n", energy_uj);
 
     int fd = open(energy_uj, O_RDONLY);
@@ -154,8 +154,10 @@ unsigned int get_frapl(uint64_t *results, void *ptr)
 {
     _frapl_t *state = (_frapl_t *) ptr;
     _get_frapl(state->tmp_values, state);
-    for(unsigned int i=0; i<state->nb; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
+    for (unsigned int i = 0; i < state->nb; i++)
+        {
+            results[i] = state->tmp_values[i] - state->values[i];
+        }
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
     return state->nb;
diff --git a/src/infiniband.c b/src/infiniband.c
index 6621759..44d0b9e 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -39,8 +39,10 @@ unsigned int _get_network(uint64_t *results, int *sources);
 
 unsigned int init_infiniband(char *infi_path, void **ptr)
 {
-    if(infi_path==NULL)
-        return 0;
+    if (infi_path == NULL)
+        {
+            return 0;
+        }
 
     if(strcmp(infi_path,"X")==0) {
 
diff --git a/src/load.c b/src/load.c
index 4f11346..c40819c 100644
--- a/src/load.c
+++ b/src/load.c
@@ -28,9 +28,9 @@
 #define UNUSED(expr) do { (void)(expr); } while (0)
 char buffer[LOAD_BUFFER_SIZE];
 
-static int load_fid=-1;
-static uint64_t load_values[10]= {0,0,0,0,0,0,0,0,0,0};
-static uint64_t tmp_load_values[10]= {0,0,0,0,0,0,0,0,0,0};
+static int load_fid = -1;
+static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
@@ -68,8 +68,10 @@ unsigned int get_load(uint64_t *results, void *state)
 {
     UNUSED(state);
     _get_load(tmp_load_values);
-    for(int i=0; i<10; i++)
-        results[i] = tmp_load_values[i] - load_values[i];
+    for (int i = 0; i < 10; i++)
+        {
+            results[i] = tmp_load_values[i] - load_values[i];
+        }
 
     memcpy(load_values, tmp_load_values, sizeof(load_values));
     return 10;
@@ -81,8 +83,8 @@ void clean_load(void *state)
     close(load_fid);
 }
 
-char *_labels[10] = {"user","nice","system","idle","iowait","irq",
-                     "softirq","steal","guest","guest_nice"
+char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
+                     "softirq", "steal", "guest", "guest_nice"
                     };
 void label_load(char **labels, void *none)
 {
diff --git a/src/mojitos.c b/src/mojitos.c
index 3569d1b..3d61aa7 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -19,19 +19,19 @@
 
  *******************************************************/
 
-#include <stdlib.h>
+#include <inttypes.h>
+#include <signal.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <time.h>
-#include <signal.h>
-#include <inttypes.h>
 #include <unistd.h>
 
 #include "counters.h"
-#include "rapl.h"
 #include "frapl.h"
-#include "network.h"
 #include "infiniband.h"
 #include "load.h"
+#include "network.h"
+#include "rapl.h"
 #include "temperature.h"
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
diff --git a/src/network.c b/src/network.c
index 647b4b3..2cb95ba 100644
--- a/src/network.c
+++ b/src/network.c
@@ -36,8 +36,10 @@ struct network_t {
 
 unsigned int _get_network(uint64_t *results, int *sources)
 {
-    if(sources==NULL)
-        return 0;
+    if (sources == NULL)
+        {
+            return 0;
+        }
     char buffer[128];
     for(int i=0; i<NB_SENSOR; i++) {
         if (pread(sources[i], buffer, 127, 0) < 0) {
@@ -54,8 +56,10 @@ unsigned int _get_network(uint64_t *results, int *sources)
 
 unsigned int init_network(char *dev, void **ptr)
 {
-    if(dev==NULL)
-        return 0;
+    if (dev == NULL)
+        {
+            return 0;
+        }
 
     if(strcmp(dev,"X")==0) {
         int fd = open(route, O_RDONLY);
@@ -102,20 +106,26 @@ unsigned int get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
     _get_network(state->tmp_values, state->sources);
-    for(int i=0; i<NB_SENSOR; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
+    for (int i = 0; i < NB_SENSOR; i++)
+        {
+            results[i] = state->tmp_values[i] - state->values[i];
+        }
 
-    memcpy(state->values, state->tmp_values, NB_SENSOR*sizeof(uint64_t));
+    memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
     return NB_SENSOR;
 }
 
 void clean_network(void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
-    if(state==NULL)
-        return;
-    for(int i=0; i<NB_SENSOR; i++)
-        close(state->sources[i]);
+    if (state == NULL)
+        {
+            return;
+        }
+    for (int i = 0; i < NB_SENSOR; i++)
+        {
+            close(state->sources[i]);
+        }
     free(state);
 }
 
diff --git a/src/rapl.c b/src/rapl.c
index 30d38c1..103007a 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -70,7 +70,7 @@ unsigned int init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
     // get number of processor sockets
-    _rapl_t *rapl= malloc(sizeof(struct _rapl_t));
+    _rapl_t *rapl = malloc(sizeof(struct _rapl_t));
     rapl->nb = 0;
     rapl->packages = NULL;
     rapl->zones = NULL;
@@ -91,8 +91,8 @@ unsigned int init_rapl(char *none, void **ptr)
 
     rapl->names = NULL;
 
-    char _name[MAX_LEN_NAME+1];
-    char _name2[MAX_LEN_NAME+11];
+    char _name[MAX_LEN_NAME + 1];
+    char _name2[MAX_LEN_NAME + 11];
 
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
         for(unsigned int zone=0; zone < nb_zones; zone++) {
@@ -119,8 +119,10 @@ unsigned int init_rapl(char *none, void **ptr)
     }
 #ifdef DEBUG
     printf("Result of init\n");
-    for(unsigned int i=0; i<rapl->nb; i++)
-        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
+    for (unsigned int i = 0; i < rapl->nb; i++)
+        {
+            printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
+        }
 #endif
 
     rapl->values = calloc(sizeof(uint64_t), rapl->nb);
@@ -138,8 +140,10 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 {
     _rapl_t *state = (_rapl_t *) ptr;
     _get_rapl(state->tmp_values, state);
-    for(unsigned int i=0; i<state->nb; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
+    for (unsigned int i = 0; i < state->nb; i++)
+        {
+            results[i] = state->tmp_values[i] - state->values[i];
+        }
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
     return state->nb;
@@ -153,9 +157,13 @@ void clean_rapl(void *ptr)
     _rapl_t *rapl = (_rapl_t *) ptr;
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
         if (powercap_rapl_destroy(&rapl->pkgs[package]))
-            perror("powercap_rapl_destroy");
-    for (unsigned int elem=0; elem<rapl->nb; elem++)
-        free(rapl->names[elem]);
+            {
+                perror("powercap_rapl_destroy");
+            }
+    for (unsigned int elem = 0; elem < rapl->nb; elem++)
+        {
+            free(rapl->names[elem]);
+        }
 
     free(rapl->names);
     free(rapl->pkgs);
@@ -169,6 +177,8 @@ void clean_rapl(void *ptr)
 void label_rapl(char **labels, void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        labels[i] = rapl->names[i];
+    for (unsigned int i = 0; i < rapl->nb; i++)
+        {
+            labels[i] = rapl->names[i];
+        }
 }
diff --git a/src/temperature.c b/src/temperature.c
index cdef158..6331d20 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -37,8 +37,10 @@ int get_string(char *filename, char *buffer, int max_size)
 {
     int fid = open(filename, O_RDONLY);
     //printf("Tries to open : %s : %d\n", filename, fid);
-    if(fid == -1)
-        return -1;
+    if (fid == -1)
+        {
+            return -1;
+        }
 
     int nb = read(fid, buffer, max_size);
     if(nb == -1) {
@@ -46,7 +48,7 @@ int get_string(char *filename, char *buffer, int max_size)
         return -1;
     }
 
-    buffer[nb]=0;
+    buffer[nb] = 0;
     close(fid);
     return 0;
 }
@@ -54,15 +56,15 @@ int get_string(char *filename, char *buffer, int max_size)
 void add_to_list(char ***list_name, char *source, int nb_elem)
 {
     //printf("Adds: %s\n", source);
-    *list_name = realloc(*list_name, (nb_elem+1)*sizeof(char *));
-    (*list_name)[nb_elem] = malloc(strlen(source)+1);
+    *list_name = realloc(*list_name, (nb_elem + 1) * sizeof(char *));
+    (*list_name)[nb_elem] = malloc(strlen(source) + 1);
     strcpy((*list_name)[nb_elem], source);
 
 }
 
 void add_temperature_sensor(int id_rep, struct temperature_t *state)
 {
-    static int key=0;
+    static int key = 0;
     static char buffer_filename[512];
     static char buffer_label[512];
 
@@ -150,6 +152,8 @@ void clean_temperature(void *ptr)
 void label_temperature(char **labels, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
-    for(int i=0; i<state->nb_elem; i++)
-        labels[i] = state->label_list[i];
+    for (int i = 0; i < state->nb_elem; i++)
+        {
+            labels[i] = state->label_list[i];
+        }
 }
-- 
GitLab


From b369bde06c0d49538b72ef0cde1c8d320b1d24da Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 11:26:35 +0100
Subject: [PATCH 023/229] make the README file as complete as possible

---
 README.md     | 37 ++++++++++++++++++++++++++++++-------
 doc/mojitos.1 |  5 ++++-
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/README.md b/README.md
index a344fe0..6422ce0 100644
--- a/README.md
+++ b/README.md
@@ -6,18 +6,35 @@ MojitO/S runs on GNU/Linux
 ## Usage
 
 ```bash
-Usage : mojitos [-Rsu] [-t time] [-f freq] [-p perf_list]  \
-                  [-u] [-d network_device] [-o logfile] [-e command arguments...]
+Usage : mojitos [-rsu] [-t time] [-f freq] [-p perf_list]  \
+                [-d network_device] [-o logfile] [-e command arguments...]
         mojitos [-l]
-```
 
-For more information, see [mojitos(1)](doc/mojitos.1) under [doc/](doc).
+     -s      Enable overhead statistics (in nanoseconds).
 
-## License
+     -u      Enable system-level load monitoring.
 
-MojitO/S is published under the GPL3 license and is part of the [Energumen Project](https://www.irit.fr/energumen/)
+     -r      Enable RAPL.
 
-<img src="https://www.irit.fr/energumen/images/energumen.png" width="100">
+     -p perf_list
+             Enable performance counters.  The argument is a coma separated
+             list of performance counters.
+
+     -d net_device
+             Enable network monitoring.
+
+     -l      List the available performance counters and quit.
+
+     -t time
+             Set duration value (in seconds). If 0, then loops indefinitely.
+
+     -f freq
+             Set amount of measurements per second.
+
+     -e cmd ...
+             Execute a command with optional arguments.  If this option is
+             used, any usage of -t or -f is ignored.
+```
 
 ## Installation Instructions
 
@@ -88,3 +105,9 @@ $ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
 1036991.000182835 525984292 3592582 691221 1385982 272182
 1036992.000165117 397678789 2770561 444030 1375729 510379
 ```
+
+## License
+
+MojitO/S is published under the GPL3 license and is part of the [Energumen Project](https://www.irit.fr/energumen/)
+
+<img src="https://www.irit.fr/energumen/images/energumen.png" width="100">
diff --git a/doc/mojitos.1 b/doc/mojitos.1
index 37e1876..a7927e8 100644
--- a/doc/mojitos.1
+++ b/doc/mojitos.1
@@ -17,7 +17,7 @@
 .Op Fl l
 .Sh DESCRIPTION
 .Nm
-enables to monitor the system, its energy comsumption and the network activity, at the OS level.
+enables monitoring the system, its energy comsumption and the network activity, at the OS level.
 It runs on GNU/Linux.
 .Pp
 .Nm
@@ -103,5 +103,8 @@ $ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
 .Xr lscpu 1 ,
 .Xr sysfs 5 ,
 .Xr proc 5
+.Sh LICENSE
+MojitO/S is published under the GPL3 license and is part of the
+.Lk https://www.irit.fr/energumen/ [Energumen Project]
 .Sh BUGS
 Yes.
-- 
GitLab


From 3ac574c814e9eae8a76f9be2cb97f0e7beb3efdf Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 11:32:32 +0100
Subject: [PATCH 024/229] properly reformat using new style (kr)

---
 doc/counter_ex.c     |  10 ++--
 doc/counter_ex.h     |   6 +-
 src/counters.c       | 138 +++++++++++++++++++++++++------------------
 src/counters_group.c | 119 +++++++++++++++++++------------------
 src/frapl.c          |  63 +++++++++++++-------
 src/infiniband.c     |  26 ++++----
 src/load.c           |  51 ++++++++++------
 src/mojitos.c        |  39 +++++++-----
 src/network.c        |  76 ++++++++++++++----------
 src/rapl.c           |  79 ++++++++++++++-----------
 src/temperature.c    |  75 +++++++++++++++--------
 11 files changed, 405 insertions(+), 277 deletions(-)

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
index 3dda06d..5067003 100644
--- a/doc/counter_ex.c
+++ b/doc/counter_ex.c
@@ -5,19 +5,19 @@ static int acc;
 unsigned int
 init_acc(char *a, void **b)
 {
-	acc = 0;
+    acc = 0;
 }
 
 unsigned int
 get_acc(uint64_t *results, void *none)
 {
-	UNUSED(none);
-	return a++;
+    UNUSED(none);
+    return a++;
 }
 
 void
 label_acc(char **labels, void *none)
 {
-	UNUSED(none);
-	labels[0] = "acc";
+    UNUSED(none);
+    labels[0] = "acc";
 }
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index d85573b..49e185c 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -2,6 +2,6 @@
  * Example of a basic counter: an accumulator
 **/
 
-unsigned int init_acc(char*, void**);
-unsigned int get_acc(uint64_t *results, void*);
-void label_counter(char **labels, void*);
+unsigned int init_acc(char *, void **);
+unsigned int get_acc(uint64_t *results, void *);
+void label_counter(char **labels, void *);
diff --git a/src/counters.c b/src/counters.c
index 244e60c..7441a07 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -42,59 +42,69 @@ typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void show_all_counters()
+void
+show_all_counters()
 {
-    for (unsigned int i = 0; i < nb_counter_option; i++)
-        {
-            printf("%s\n", perf_static_info[i].name);
-        }
+    for (unsigned int i = 0; i < nb_counter_option; i++) {
+        printf("%s\n", perf_static_info[i].name);
+    }
 }
 
-void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
+void
+perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
 {
-    *perf_type = malloc(nb*sizeof(__u32));
-    *perf_key  = malloc(nb*sizeof(__u64));
-    for(int i=0; i<nb; i++) {
+    *perf_type = malloc(nb * sizeof(__u32));
+    *perf_key  = malloc(nb * sizeof(__u64));
+
+    for (int i = 0; i < nb; i++) {
         (*perf_key)[i]  = perf_static_info[indexes[i]].perf_key;
         (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
     }
 }
-void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
+void
+perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
 {
     char *token;
-    *nb_perf=0;
-    *perf_indexes=NULL;
-    while((token=strtok(perf_string, ",")) != NULL) {
+    *nb_perf = 0;
+    *perf_indexes = NULL;
+
+    while ((token = strtok(perf_string, ",")) != NULL) {
         perf_string = NULL;
         unsigned int i;
-        for(i=0; i<nb_counter_option; i++) {
-            if(strcmp(perf_static_info[i].name, token) == 0) {
+
+        for (i = 0; i < nb_counter_option; i++) {
+            if (strcmp(perf_static_info[i].name, token) == 0) {
                 (*nb_perf)++;
-                (*perf_indexes) = realloc(*perf_indexes, sizeof(int)*(*nb_perf));
-                (*perf_indexes)[*nb_perf-1]=i;
+                (*perf_indexes) = realloc(*perf_indexes, sizeof(int) * (*nb_perf));
+                (*perf_indexes)[*nb_perf - 1] = i;
                 break;
             }
         }
-        if(i == nb_counter_option) {
+
+        if (i == nb_counter_option) {
             fprintf(stderr, "Unknown performance counter: %s\n", token);
             exit(EXIT_FAILURE);
         }
     }
 }
 
-static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                            int cpu, int group_fd, unsigned long flags)
+static long
+perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
+
     if (res == -1) {
         perror("perf_event_open");
         fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
         exit(EXIT_FAILURE);
     }
+
     return res;
 }
 
-counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+counter_t
+_init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
@@ -104,28 +114,35 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
 
     counter_t counters = malloc(sizeof(struct _counter_t));
     counters->nbperf = nb_perf;
-    counters->nbcores=nbcores;
-    counters->counters=malloc(nb_perf*sizeof(int *));
-    for (int i=0; i<nb_perf; i++) {
+    counters->nbcores = nbcores;
+    counters->counters = malloc(nb_perf * sizeof(int *));
+
+    for (int i = 0; i < nb_perf; i++) {
         pe.type = types[i];
         pe.config = names[i];
-        counters->counters[i] = malloc(nbcores*sizeof(int));
+        counters->counters[i] = malloc(nbcores * sizeof(int));
 
-        for (unsigned int core=0; core<nbcores; core++) {
+        for (unsigned int core = 0; core < nbcores; core++) {
             counters->counters[i][core] = perf_event_open(&pe, -1, core, -1, PERF_FLAG_FD_CLOEXEC);
         }
     }
+
     return counters;
 }
 
-void clean_counters(void *ptr)
+void
+clean_counters(void *ptr)
 {
     counter_t counters = (counter_t) ptr;
-    for(int counter=0; counter<counters->nbperf; counter++) {
-        for(int core=0; core<counters->nbcores; core++)
+
+    for (int counter = 0; counter < counters->nbperf; counter++) {
+        for (int core = 0; core < counters->nbcores; core++) {
             close(counters->counters[counter][core]);
+        }
+
         free(counters->counters[counter]);
     }
+
     free(counters->counters);
     free(counters->counters_values);
     free(counters->tmp_counters_values);
@@ -134,36 +151,41 @@ void clean_counters(void *ptr)
     free(counters);
 }
 
-void start_counters(counter_t counters)
+void
+start_counters(counter_t counters)
 {
-    for (int counter = 0; counter < counters->nbperf; counter++)
-        for (int core = 0; core < counters->nbcores; core++)
-            {
-                ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
-            }
+    for (int counter = 0; counter < counters->nbperf; counter++) {
+        for (int core = 0; core < counters->nbcores; core++) {
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_ENABLE, 0);
+        }
+    }
 }
 
-void reset_counters(counter_t counters)
+void
+reset_counters(counter_t counters)
 {
-    for (int counter = 0; counter < counters->nbperf; counter++)
-        for (int core = 0; core < counters->nbcores; core++)
-            {
-                ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
-            }
+    for (int counter = 0; counter < counters->nbperf; counter++) {
+        for (int core = 0; core < counters->nbcores; core++) {
+            ioctl(counters->counters[counter][core], PERF_EVENT_IOC_RESET, 0);
+        }
+    }
 }
 
-void _get_counters(counter_t counters, uint64_t *values)
+void
+_get_counters(counter_t counters, uint64_t *values)
 {
-    for(int i=0; i<counters->nbperf; i++) {
-        uint64_t accu=0;
-        uint64_t count=0;
-        for (int core=0; core<counters->nbcores; core++) {
+    for (int i = 0; i < counters->nbperf; i++) {
+        uint64_t accu = 0;
+        uint64_t count = 0;
+
+        for (int core = 0; core < counters->nbcores; core++) {
             if (-1 == read(counters->counters[i][core], &count, sizeof(uint64_t))) {
                 fprintf(stderr, "Cannot read result");
                 exit(EXIT_FAILURE);
             }
             accu += count;
         }
+
         values[i] = accu;
     }
 }
@@ -173,7 +195,8 @@ void _get_counters(counter_t counters, uint64_t *values)
 
 
 
-unsigned int init_counters(char *args, void **state)
+unsigned int
+init_counters(char *args, void **state)
 {
     int nb_perf;
     int *perf_indexes = NULL;
@@ -197,26 +220,27 @@ unsigned int init_counters(char *args, void **state)
     return nb_perf;
 }
 
-unsigned int get_counters(uint64_t *results, void *ptr)
+unsigned int
+get_counters(uint64_t *results, void *ptr)
 {
     counter_t state = (counter_t) ptr;
 
     _get_counters(state, state->tmp_counters_values);
-    for (int i = 0; i < state->nbperf; i++)
-        {
-            results[i] = state->tmp_counters_values[i] - state->counters_values[i];
-        }
+
+    for (int i = 0; i < state->nbperf; i++) {
+        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+    }
 
     memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
     return state->nbperf;
 }
 
-void label_counters(char **labels, void *ptr)
+void
+label_counters(char **labels, void *ptr)
 {
     counter_t state = (counter_t) ptr;
-    for (int i = 0; i < state->nbperf; i++)
-        {
-            labels[i] = perf_static_info[state->perf_indexes[i]].name;
-        }
 
+    for (int i = 0; i < state->nbperf; i++) {
+        labels[i] = perf_static_info[state->perf_indexes[i]].name;
+    }
 }
diff --git a/src/counters_group.c b/src/counters_group.c
index 8a4de79..aa441d5 100644
--- a/src/counters_group.c
+++ b/src/counters_group.c
@@ -29,27 +29,29 @@
 
 #include "counters.h"
 
-struct _counter_t
-{
+struct _counter_t {
     int nbcores;
     int nbperf;
     int *counters;
 };
 
-static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                            int cpu, int group_fd, unsigned long flags)
+static long
+perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-    if (res == -1)
-        {
-            perror("perf_event_open");
-            fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-            exit(EXIT_FAILURE);
-        }
+
+    if (res == -1) {
+        perror("perf_event_open");
+        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
+        exit(EXIT_FAILURE);
+    }
+
     return res;
 }
 
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+counter_t
+init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     struct _counter_t *counters = malloc(sizeof(struct _counter_t));
@@ -64,80 +66,79 @@ counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *name
     pe.read_format = PERF_FORMAT_GROUP;
     counters->counters = malloc((nbcores + 1) * sizeof(int));
 
-    for (int core = 0; core < nbcores; core++)
-        {
-            counters->counters[core] = -1;
-            for (int idperf = 0; idperf < nb_perf; idperf ++)
-                {
-                    pe.type = types[idperf];
-                    pe.config = names[idperf];
-                    int res = perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-                    if (counters->counters[core] == -1)
-                        {
-                            counters->counters[core] = res;
-                        }
-                }
+    for (int core = 0; core < nbcores; core++) {
+        counters->counters[core] = -1;
+
+        for (int idperf = 0; idperf < nb_perf; idperf ++) {
+            pe.type = types[idperf];
+            pe.config = names[idperf];
+            int res = perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
+
+            if (counters->counters[core] == -1) {
+                counters->counters[core] = res;
+            }
         }
+    }
+
     return counters;
 }
 
-void clean_counters(counter_t counters)
+void
+clean_counters(counter_t counters)
 {
-    for (int core = 0; core < counters->nbcores; core++)
-        {
-            close(counters->counters[core]);
-        }
+    for (int core = 0; core < counters->nbcores; core++) {
+        close(counters->counters[core]);
+    }
+
     free(counters->counters);
     free(counters);
 }
 
-void start_counters(counter_t counters)
+void
+start_counters(counter_t counters)
 {
-    for (int core = 0; core < counters->nbcores; core++)
-        {
-            ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
-        }
+    for (int core = 0; core < counters->nbcores; core++) {
+        ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
+    }
 }
-void reset_counters(counter_t counters)
+void
+reset_counters(counter_t counters)
 {
-    for (int core = 0; core < counters->nbcores; core++)
-        {
-            ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
-        }
+    for (int core = 0; core < counters->nbcores; core++) {
+        ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
+    }
 }
 
-struct read_format
-{
+struct read_format {
     uint64_t nr;
-    struct
-    {
+    struct {
         uint64_t value;
     } values[];
 };
 
-void get_counters(counter_t counters, long long *values)
+void
+get_counters(counter_t counters, long long *values)
 {
     int nb_perf = counters->nbperf;
     size_t buffer_size = sizeof(uint64_t) * (1 + nb_perf);
     struct read_format *buffer = NULL;
-    if (buffer == NULL)
-        {
-            buffer = malloc(buffer_size);
-        }
+
+    if (buffer == NULL) {
+        buffer = malloc(buffer_size);
+    }
 
     memset(values, 0, nb_perf * sizeof(long long));
 
-    for (int core = 0; core < counters->nbcores; core++)
-        {
-            if (-1 == read(counters->counters[core], buffer, buffer_size))
-                {
-                    perror("PB Lecture resultat");
-                    exit(EXIT_FAILURE);
-                }
-            for (int idperf = 0; idperf <= nb_perf; idperf++)
-                {
-                    values[idperf] += buffer->values[idperf].value;
-                }
+    for (int core = 0; core < counters->nbcores; core++) {
+        if (-1 == read(counters->counters[core], buffer, buffer_size)) {
+            perror("PB Lecture resultat");
+            exit(EXIT_FAILURE);
+        }
+
+        for (int idperf = 0; idperf <= nb_perf; idperf++) {
+            values[idperf] += buffer->values[idperf].value;
         }
+    }
+
     reset_counters(counters);
 }
diff --git a/src/frapl.c b/src/frapl.c
index ab17b14..42842cf 100644
--- a/src/frapl.c
+++ b/src/frapl.c
@@ -31,12 +31,14 @@
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
 
-char *get_frapl_string(const char *filename)
+char *
+get_frapl_string(const char *filename)
 {
     int fd = open(filename, O_RDONLY);
-    if( fd == -1) {
+    if (fd == -1) {
         return NULL;
     }
+
     char *result = malloc(MAX_HEADER);
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
@@ -44,7 +46,8 @@ char *get_frapl_string(const char *filename)
     return (result);
 }
 
-void test_append(char *name, int i)
+void
+test_append(char *name, int i)
 {
     //char last = name[strlen(name)-1];
     //if (last>='0' && last <= '9')
@@ -64,7 +67,8 @@ struct _frapl_t {
 typedef struct _frapl_t _frapl_t;
 
 
-void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
+void
+add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
 {
     rapl->nb += 1;
     rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
@@ -81,11 +85,13 @@ void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
         perror("open");
         exit(1);
     }
-    rapl->fids[rapl->nb-1] = fd;
+
+    rapl->fids[rapl->nb - 1] = fd;
 }
 
 
-void _get_frapl(uint64_t *values, _frapl_t *rapl)
+void
+_get_frapl(uint64_t *values, _frapl_t *rapl)
 {
     static char buffer[512];
 
@@ -95,12 +101,14 @@ void _get_frapl(uint64_t *values, _frapl_t *rapl)
             perror("pread");
             exit(1);
         }
+
         values[i] = strtoull(buffer, NULL, 10);
     }
 }
 
 
-unsigned int init_frapl(char *none, void **ptr)
+unsigned int
+init_frapl(char *none, void **ptr)
 {
     UNUSED(none);
     _frapl_t *rapl = malloc(sizeof(_frapl_t));
@@ -112,10 +120,14 @@ unsigned int init_frapl(char *none, void **ptr)
     char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
     char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-    for (unsigned int i=0;; i++) {
+    for (unsigned int i = 0;; i++) {
         sprintf(buffer, name_base, i, "name");
         char *tmp = get_frapl_string(buffer);
-        if (tmp == NULL) break;
+
+        if (tmp == NULL) {
+            break;
+        }
+
         //printf("%s\n", tmp);
         test_append(tmp, i);
         //printf("%s -> %s\n", buffer, tmp);
@@ -124,10 +136,14 @@ unsigned int init_frapl(char *none, void **ptr)
         add_frapl_source(rapl, tmp, buffer);
         free(tmp);
 
-        for (unsigned int j=0;; j++) {
+        for (unsigned int j = 0;; j++) {
             sprintf(buffer, name_sub, i, i, j, "name");
             char *tmp_sub = get_frapl_string(buffer);
-            if (tmp_sub == NULL) break;
+
+            if (tmp_sub == NULL) {
+                break;
+            }
+
             //printf("%s\n", tmp_sub);
             test_append(tmp_sub, i);
             //printf("%s -> %s\n", buffer, tmp_sub);
@@ -150,26 +166,30 @@ unsigned int init_frapl(char *none, void **ptr)
 }
 
 
-unsigned int get_frapl(uint64_t *results, void *ptr)
+unsigned int
+get_frapl(uint64_t *results, void *ptr)
 {
     _frapl_t *state = (_frapl_t *) ptr;
     _get_frapl(state->tmp_values, state);
-    for (unsigned int i = 0; i < state->nb; i++)
-        {
-            results[i] = state->tmp_values[i] - state->values[i];
-        }
+
+    for (unsigned int i = 0; i < state->nb; i++) {
+        results[i] = state->tmp_values[i] - state->values[i];
+    }
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
     return state->nb;
 }
 
-void clean_frapl(void *ptr)
+void
+clean_frapl(void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++) {
+
+    for (unsigned int i = 0; i < rapl->nb; i++) {
         free(rapl->names[i]);
         close(rapl->fids[i]);
     }
+
     free(rapl->names);
     free(rapl->fids);
     free(rapl->values);
@@ -178,9 +198,12 @@ void clean_frapl(void *ptr)
 }
 
 
-void label_frapl(char **labels, void *ptr)
+void
+label_frapl(char **labels, void *ptr)
 {
     _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
+
+    for (unsigned int i = 0; i < rapl->nb; i++) {
         labels[i] = rapl->names[i];
+    }
 }
diff --git a/src/infiniband.c b/src/infiniband.c
index 44d0b9e..d5da4eb 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -37,20 +37,23 @@ struct network_t {
 unsigned int _get_network(uint64_t *results, int *sources);
 
 
-unsigned int init_infiniband(char *infi_path, void **ptr)
+unsigned int
+init_infiniband(char *infi_path, void **ptr)
 {
-    if (infi_path == NULL)
-        {
-            return 0;
-        }
+    if (infi_path == NULL) {
+        return 0;
+    }
 
-    if(strcmp(infi_path,"X")==0) {
+    if (strcmp(infi_path, "X") == 0) {
 
         glob_t res;
 
         glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
-        if(res.gl_pathc == 0)
+
+        if (res.gl_pathc == 0) {
             return 0;
+        }
+
         infi_path = res.gl_pathv[0];
     }
 
@@ -63,7 +66,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer[1024];
-    for(int i=0; i<NB_SENSOR; i++) {
+    for (int i = 0; i < NB_SENSOR; i++) {
         sprintf(buffer, filenames[i], infi_path);
         state->sources[i] = open(buffer, O_RDONLY);
     }
@@ -75,9 +78,12 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 }
 
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
-void label_infiniband(char **labels, void *none)
+void
+label_infiniband(char **labels, void *none)
 {
     UNUSED(none);
-    for(int i=0; i<NB_SENSOR; i++)
+
+    for (int i = 0; i < NB_SENSOR; i++) {
         labels[i] = _labels_infiniband[i];
+    }
 }
diff --git a/src/load.c b/src/load.c
index c40819c..c0013ab 100644
--- a/src/load.c
+++ b/src/load.c
@@ -33,51 +33,65 @@ static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
-void _get_load(uint64_t *results)
+void
+_get_load(uint64_t *results)
 {
-    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE-1, 0) < 0) {
+    if (pread(load_fid, buffer, LOAD_BUFFER_SIZE - 1, 0) < 0) {
         perror("pread");
         exit(1);
     }
-    int pos=0;
-    while(buffer[pos] > '9' || buffer[pos] < '0') pos++;
-    for(int i=0; i<10; i++) {
-        results[i] = strtoull(buffer+pos, NULL, 10);
-        while(buffer[pos] <= '9' && buffer[pos] >= '0') pos++;
+
+    int pos = 0;
+
+    while (buffer[pos] > '9' || buffer[pos] < '0') {
+        pos++;
+    }
+
+    for (int i = 0; i < 10; i++) {
+        results[i] = strtoull(buffer + pos, NULL, 10);
+
+        while (buffer[pos] <= '9' && buffer[pos] >= '0') {
+            pos++;
+        }
+
         pos++;
     }
 }
 
 // Public interface
 
-unsigned int init_load(char *argument, void **state)
+unsigned int
+init_load(char *argument, void **state)
 {
     UNUSED(argument);
     UNUSED(state);
     load_fid = open(stat, O_RDONLY);
     if (load_fid < 0) {
-        fprintf(stderr,"%s ",stat);
+        fprintf(stderr, "%s ", stat);
         perror("open");
         exit(1);
     }
+
     _get_load(load_values);
     return 10;
 }
 
-unsigned int get_load(uint64_t *results, void *state)
+unsigned int
+get_load(uint64_t *results, void *state)
 {
     UNUSED(state);
     _get_load(tmp_load_values);
-    for (int i = 0; i < 10; i++)
-        {
-            results[i] = tmp_load_values[i] - load_values[i];
-        }
+
+    for (int i = 0; i < 10; i++) {
+        results[i] = tmp_load_values[i] - load_values[i];
+    }
 
     memcpy(load_values, tmp_load_values, sizeof(load_values));
     return 10;
 }
 
-void clean_load(void *state)
+void
+clean_load(void *state)
 {
     UNUSED(state);
     close(load_fid);
@@ -86,9 +100,12 @@ void clean_load(void *state)
 char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
                      "softirq", "steal", "guest", "guest_nice"
                     };
-void label_load(char **labels, void *none)
+void
+label_load(char **labels, void *none)
 {
     UNUSED(none);
-    for(int i=0; i<10; i++)
+
+    for (int i = 0; i < 10; i++) {
         labels[i] = _labels[i];
+    }
 }
diff --git a/src/mojitos.c b/src/mojitos.c
index 3d61aa7..c0a5655 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -44,7 +44,8 @@
 	} while (0)
 
 
-void usage(char **argv)
+void
+usage(char **argv)
 {
     printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
            "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
@@ -64,19 +65,22 @@ void usage(char **argv)
     exit(EXIT_SUCCESS);
 }
 
-void sighandler(int none)
+void
+sighandler(int none)
 {
     UNUSED(none);
 }
 
-void flush(int none)
+void
+flush(int none)
 {
     UNUSED(none);
     exit(0);
 }
 
 FILE *output;
-void flushexit()
+void
+flushexit()
 {
     if (output != NULL) {
         fflush(output);
@@ -98,12 +102,14 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(initializer_t init, char *arg, labeler_t labeler,
-                getter_t get, cleaner_t clean)
+void
+add_source(initializer_t init, char *arg, labeler_t labeler,
+           getter_t get, cleaner_t clean)
 {
     nb_sources++;
     states = realloc(states, nb_sources * sizeof(void *));
     int nb = init(arg, &states[nb_sources - 1]);
+
     if (nb == 0) {
         nb_sources--;
         states = realloc(states, nb_sources * sizeof(void *));
@@ -122,7 +128,8 @@ void add_source(initializer_t init, char *arg, labeler_t labeler,
     nb_sensors += nb;
 }
 
-int main(int argc, char **argv)
+int
+main(int argc, char **argv)
 {
     int total_time = 1;
     int delta = 0;
@@ -141,7 +148,8 @@ int main(int argc, char **argv)
     signal(15, flush);
 
     int c;
-    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL)
+
+    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL) {
         switch (c) {
         case 'f':
             if (optind >= argc) PANIC(1,"-f, no frequency provided");
@@ -198,7 +206,7 @@ int main(int argc, char **argv)
         default:
             usage(argv);
         }
-
+    }
 
     setvbuf(output, NULL, _IONBF, BUFSIZ);
     struct timespec ts;
@@ -223,6 +231,7 @@ int main(int argc, char **argv)
 
         // Get Data
         unsigned int current = 0;
+
         for (unsigned int i = 0; i < nb_sources; i++) {
             current += getter[i](&values[current], states[i]);
         }
@@ -233,12 +242,14 @@ int main(int argc, char **argv)
                 execvp(application[0], application);
                 exit(0);
             }
+
             pause();
             clock_gettime(CLOCK_MONOTONIC, &ts);
+
             if (ts.tv_nsec >= ts_ref.tv_nsec) {
                 fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec), ts.tv_nsec - ts_ref.tv_nsec);
             } else {
-                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000000000 + ts.tv_nsec - ts_ref.tv_nsec);
+                fprintf(output, "%ld.%09ld ", (ts.tv_sec - ts_ref.tv_sec) - 1, 1000 * 1000 * 1000 + ts.tv_nsec - ts_ref.tv_nsec);
             }
         } else {
 #ifdef DEBUG
@@ -247,12 +258,14 @@ int main(int argc, char **argv)
             //Indiv: mean: 148 std: 31 % med: 141 std: 28 %
             //Group: mean: 309 std: 41 % med: 297 std: 39 %
 #endif
+
             if (stat_mode == 0) {
                 clock_gettime(CLOCK_MONOTONIC, &ts);
+
                 if (ts.tv_nsec >= ts_ref.tv_nsec) {
                     stat_data = ts.tv_nsec - ts_ref.tv_nsec;
                 } else {
-                    stat_data = 1000000000 + ts.tv_nsec - ts_ref.tv_nsec;
+                    stat_data = 1000 * 1000 * 1000 + ts.tv_nsec - ts_ref.tv_nsec;
                 }
             }
 
@@ -261,6 +274,7 @@ int main(int argc, char **argv)
         }
 
         for (unsigned int i = 0; i < nb_sensors; i++) {
+            /* "PRIu64" is a format specifier to print uint64_t values */
             fprintf(output, "%" PRIu64 " ", values[i]);
         }
 
@@ -291,6 +305,3 @@ int main(int argc, char **argv)
     }
 }
 
-
-
-
diff --git a/src/network.c b/src/network.c
index 2cb95ba..5b94151 100644
--- a/src/network.c
+++ b/src/network.c
@@ -34,14 +34,16 @@ struct network_t {
     int sources[NB_SENSOR];
 };
 
-unsigned int _get_network(uint64_t *results, int *sources)
+unsigned int
+_get_network(uint64_t *results, int *sources)
 {
-    if (sources == NULL)
-        {
-            return 0;
-        }
+    if (sources == NULL) {
+        return 0;
+    }
+
     char buffer[128];
-    for(int i=0; i<NB_SENSOR; i++) {
+
+    for (int i = 0; i < NB_SENSOR; i++) {
         if (pread(sources[i], buffer, 127, 0) < 0) {
             perror("pread");
             exit(1);
@@ -49,36 +51,39 @@ unsigned int _get_network(uint64_t *results, int *sources)
 
         results[i] = strtoull(buffer, NULL, 10);
     }
+
     return NB_SENSOR;
 }
 
 
 
-unsigned int init_network(char *dev, void **ptr)
+unsigned int
+init_network(char *dev, void **ptr)
 {
-    if (dev == NULL)
-        {
-            return 0;
-        }
+    if (dev == NULL) {
+        return 0;
+    }
 
-    if(strcmp(dev,"X")==0) {
+    if (strcmp(dev, "X") == 0) {
         int fd = open(route, O_RDONLY);
+
         if (fd < 0) {
             fprintf(stderr, "%s ", route);
             perror("open");
             exit(1);
         }
+
         char buffer[1000];
 
-        if ( read(fd, buffer, 999) < 0 ) {
+        if (read(fd, buffer, 999) < 0 ) {
             perror("read");
             close(fd);
             exit(1);
         }
 
-        char *start_of_dev = index(buffer, '\n')+1;
+        char *start_of_dev = index(buffer, '\n') + 1;
         char *end_of_dev = index(start_of_dev, '\t');
-        *end_of_dev='\0';
+        *end_of_dev = '\0';
         dev = start_of_dev;
         close(fd);
     }
@@ -92,47 +97,54 @@ unsigned int init_network(char *dev, void **ptr)
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer2[256];
-    for(int i=0; i<NB_SENSOR; i++) {
+    for (int i = 0; i < NB_SENSOR; i++) {
         sprintf(buffer2, filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
     }
+
     *ptr = (void *) state;
     _get_network(state->values, state->sources);
 
     return NB_SENSOR;
 }
 
-unsigned int get_network(uint64_t *results, void *ptr)
+unsigned int
+get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
     _get_network(state->tmp_values, state->sources);
-    for (int i = 0; i < NB_SENSOR; i++)
-        {
-            results[i] = state->tmp_values[i] - state->values[i];
-        }
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        results[i] = state->tmp_values[i] - state->values[i];
+    }
 
     memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
     return NB_SENSOR;
 }
 
-void clean_network(void *ptr)
+void
+clean_network(void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
-    if (state == NULL)
-        {
-            return;
-        }
-    for (int i = 0; i < NB_SENSOR; i++)
-        {
-            close(state->sources[i]);
-        }
+
+    if (state == NULL) {
+        return;
+    }
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        close(state->sources[i]);
+    }
+
     free(state);
 }
 
 char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void *none)
+void
+label_network(char **labels, void *none)
 {
     UNUSED(none);
-    for(int i=0; i<NB_SENSOR; i++)
+
+    for (int i = 0; i < NB_SENSOR; i++) {
         labels[i] = _labels_network[i];
+    }
 }
diff --git a/src/rapl.c b/src/rapl.c
index 103007a..0119a4f 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -51,7 +51,8 @@ const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_COR
 #define MAX_LEN_NAME 100
 
 // values [zone + package *nbzones] microjoules
-void _get_rapl(uint64_t *values, _rapl_t *rapl)
+void
+_get_rapl(uint64_t *values, _rapl_t *rapl)
 {
     for (unsigned int i = 0; i < rapl->nb; i++) {
 #ifdef DEBUG
@@ -66,7 +67,8 @@ void _get_rapl(uint64_t *values, _rapl_t *rapl)
     }
 }
 
-unsigned int init_rapl(char *none, void **ptr)
+unsigned int
+init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
     // get number of processor sockets
@@ -82,7 +84,9 @@ unsigned int init_rapl(char *none, void **ptr)
         perror("no packages found (maybe the kernel module isn't loaded?)");
         exit(-1);
     }
+
     rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
+
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
         if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
             perror("powercap_rapl_init, check access (root needed ?)");
@@ -95,34 +99,38 @@ unsigned int init_rapl(char *none, void **ptr)
     char _name2[MAX_LEN_NAME + 11];
 
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
-        for(unsigned int zone=0; zone < nb_zones; zone++) {
-            int length=powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-                                              _name, MAX_LEN_NAME);
-            if (length>0) {
+        for (unsigned int zone = 0; zone < nb_zones; zone++) {
+            int length = powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
+                                                _name, MAX_LEN_NAME);
+
+            if (length > 0) {
 
                 sprintf(_name2, "%s%u", _name, package);
 
                 rapl->nb++;
                 rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
-                rapl->names[rapl->nb-1] = malloc(sizeof(char) * (strlen(_name2)+1));
-                rapl->zones = realloc(rapl->zones, sizeof(uint32_t)*rapl->nb);
-                rapl->packages = realloc(rapl->packages, sizeof(uint32_t)*rapl->nb);
+                rapl->names[rapl->nb - 1] = malloc(sizeof(char) * (strlen(_name2) + 1));
+                rapl->zones = realloc(rapl->zones, sizeof(uint32_t) * rapl->nb);
+                rapl->packages = realloc(rapl->packages, sizeof(uint32_t) * rapl->nb);
 
-                strcpy(rapl->names[rapl->nb-1], _name2);
-                rapl->zones[rapl->nb-1] = rapl_zones[zone];
-                rapl->packages[rapl->nb-1] = package;
+                strcpy(rapl->names[rapl->nb - 1], _name2);
+                rapl->zones[rapl->nb - 1] = rapl_zones[zone];
+                rapl->packages[rapl->nb - 1] = package;
             }
+
 #ifdef DEBUG
             printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
 #endif
         }
     }
+
 #ifdef DEBUG
     printf("Result of init\n");
-    for (unsigned int i = 0; i < rapl->nb; i++)
-        {
-            printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
-        }
+
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
+    }
+
 #endif
 
     rapl->values = calloc(sizeof(uint64_t), rapl->nb);
@@ -136,14 +144,15 @@ unsigned int init_rapl(char *none, void **ptr)
 
 
 
-unsigned int get_rapl(uint64_t *results, void *ptr)
+unsigned int
+get_rapl(uint64_t *results, void *ptr)
 {
     _rapl_t *state = (_rapl_t *) ptr;
     _get_rapl(state->tmp_values, state);
-    for (unsigned int i = 0; i < state->nb; i++)
-        {
-            results[i] = state->tmp_values[i] - state->values[i];
-        }
+
+    for (unsigned int i = 0; i < state->nb; i++) {
+        results[i] = state->tmp_values[i] - state->values[i];
+    }
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
     return state->nb;
@@ -152,19 +161,20 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 
 
 
-void clean_rapl(void *ptr)
+void
+clean_rapl(void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
+
     for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_destroy(&rapl->pkgs[package]))
-            {
-                perror("powercap_rapl_destroy");
-            }
-    for (unsigned int elem = 0; elem < rapl->nb; elem++)
-        {
-            free(rapl->names[elem]);
+        if (powercap_rapl_destroy(&rapl->pkgs[package])) {
+            perror("powercap_rapl_destroy");
         }
 
+    for (unsigned int elem = 0; elem < rapl->nb; elem++) {
+        free(rapl->names[elem]);
+    }
+
     free(rapl->names);
     free(rapl->pkgs);
     free(rapl->zones);
@@ -174,11 +184,12 @@ void clean_rapl(void *ptr)
     free(rapl);
 }
 
-void label_rapl(char **labels, void *ptr)
+void
+label_rapl(char **labels, void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++)
-        {
-            labels[i] = rapl->names[i];
-        }
+
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+        labels[i] = rapl->names[i];
+    }
 }
diff --git a/src/temperature.c b/src/temperature.c
index 6331d20..d0d1e9e 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -33,17 +33,18 @@ struct temperature_t {
     int nb_elem;
 };
 
-int get_string(char *filename, char *buffer, int max_size)
+int
+get_string(char *filename, char *buffer, int max_size)
 {
     int fid = open(filename, O_RDONLY);
+
     //printf("Tries to open : %s : %d\n", filename, fid);
-    if (fid == -1)
-        {
-            return -1;
-        }
+    if (fid == -1) {
+        return -1;
+    }
 
     int nb = read(fid, buffer, max_size);
-    if(nb == -1) {
+    if (nb == -1) {
         close(fid);
         return -1;
     }
@@ -53,7 +54,8 @@ int get_string(char *filename, char *buffer, int max_size)
     return 0;
 }
 
-void add_to_list(char ***list_name, char *source, int nb_elem)
+void
+add_to_list(char ***list_name, char *source, int nb_elem)
 {
     //printf("Adds: %s\n", source);
     *list_name = realloc(*list_name, (nb_elem + 1) * sizeof(char *));
@@ -62,7 +64,8 @@ void add_to_list(char ***list_name, char *source, int nb_elem)
 
 }
 
-void add_temperature_sensor(int id_rep, struct temperature_t *state)
+void
+add_temperature_sensor(int id_rep, struct temperature_t *state)
 {
     static int key = 0;
     static char buffer_filename[512];
@@ -70,25 +73,35 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 
     int delta = sprintf(buffer_label, "Temp_%d_", key);
 
-    for(int i=1;; i++) {
+    for (int i = 1;; i++) {
         sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
-        if(get_string(buffer_filename, buffer_label+delta, 100) == -1)
+
+        if (get_string(buffer_filename, buffer_label + delta, 100) == -1) {
             break;
+        }
+
+        for (unsigned int pos = 0; pos < strlen(buffer_label); pos++) {
+            if (buffer_label[pos] == ' ') {
+                buffer_label[pos] = '_';
+            }
 
-        for(unsigned int pos = 0; pos < strlen(buffer_label); pos++) {
-            if (buffer_label[pos] == ' ')  buffer_label[pos] = '_';
-            if (buffer_label[pos] == '\n') buffer_label[pos] = '\0';
+            if (buffer_label[pos] == '\n') {
+                buffer_label[pos] = '\0';
+            }
         }
+
         add_to_list(&state->label_list, buffer_label, state->nb_elem);
 
         sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
-        state->fid_list = realloc(state->fid_list, (state->nb_elem+1)*sizeof(int));
+        state->fid_list = realloc(state->fid_list, (state->nb_elem + 1) * sizeof(int));
         int fd = open(buffer_filename, O_RDONLY);
+
         if (fd < 0) {
             fprintf(stderr, "%s ", buffer_filename);
             perror("open");
             exit(1);
         }
+
         state->fid_list[state->nb_elem] = fd;
         state->nb_elem++;
         // printf("%s : %s\n", buffer_label, buffer_filename);
@@ -97,7 +110,8 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
     key++;
 }
 
-unsigned int init_temperature(char *args, void **ptr)
+unsigned int
+init_temperature(char *args, void **ptr)
 {
     UNUSED(args);
     struct temperature_t *state = malloc(sizeof(struct temperature_t));
@@ -111,49 +125,58 @@ unsigned int init_temperature(char *args, void **ptr)
 
     int i = 0;
     sprintf(name, base_name, i);
-    while(get_string(name, buffer, 8) != -1) {
-        if (strcmp(buffer, "coretemp")==0)
+
+    while (get_string(name, buffer, 8) != -1) {
+        if (strcmp(buffer, "coretemp") == 0) {
             add_temperature_sensor(i, state);
+        }
 
         i++;
         sprintf(name, base_name, i);
     }
+
     *ptr = (void *) state;
     return state->nb_elem;
 }
 
-unsigned int get_temperature(uint64_t *results, void *ptr)
+unsigned int
+get_temperature(uint64_t *results, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
     static char buffer[512];
-    for(int i=0; i<state->nb_elem; i++) {
+
+    for (int i = 0; i < state->nb_elem; i++) {
         if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
             perror("pread");
             exit(1);
         }
         results[i] = strtoull(buffer, NULL, 10);
     }
+
     return state->nb_elem;
 }
 
-void clean_temperature(void *ptr)
+void
+clean_temperature(void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
 
-    for(int i=0; i<state->nb_elem; i++) {
+    for (int i = 0; i < state->nb_elem; i++) {
         free(state->label_list[i]);
         close(state->fid_list[i]);
     }
+
     free(state->label_list);
     free(state->fid_list);
     free(state);
 }
 
-void label_temperature(char **labels, void *ptr)
+void
+label_temperature(char **labels, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
-    for (int i = 0; i < state->nb_elem; i++)
-        {
-            labels[i] = state->label_list[i];
-        }
+
+    for (int i = 0; i < state->nb_elem; i++) {
+        labels[i] = state->label_list[i];
+    }
 }
-- 
GitLab


From 3d630bac4cd8f5e532cd20b30cdcc89b8b908a1a Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 14:29:19 +0100
Subject: [PATCH 025/229] remove deprecated "rapl" counter

and replace it with frapl

- rename "frapl" to "rapl"
- remove no longer used "-R" option
---
 makefile      |   2 +-
 src/frapl.c   | 209 --------------------------------------------------
 src/frapl.h   |  25 ------
 src/mojitos.c |   6 +-
 src/rapl.c    | 178 ++++++++++++++++++++++--------------------
 src/rapl.h    |   2 +-
 6 files changed, 99 insertions(+), 323 deletions(-)
 delete mode 100644 src/frapl.c
 delete mode 100644 src/frapl.h

diff --git a/makefile b/makefile
index ab8c2dc..5198055 100644
--- a/makefile
+++ b/makefile
@@ -4,7 +4,7 @@ SRC_DIR = src
 OBJ_DIR = obj
 BIN_DIR = bin
 
-OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o frapl.o network.o load.o infiniband.o temperature.o)
+OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o)
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
diff --git a/src/frapl.c b/src/frapl.c
deleted file mode 100644
index 42842cf..0000000
--- a/src/frapl.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-
-
-#define MAX_HEADER 128
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-
-char *
-get_frapl_string(const char *filename)
-{
-    int fd = open(filename, O_RDONLY);
-    if (fd == -1) {
-        return NULL;
-    }
-
-    char *result = malloc(MAX_HEADER);
-    int nb = read(fd, result, MAX_HEADER);
-    close(fd);
-    result[nb - 1] = 0;
-    return (result);
-}
-
-void
-test_append(char *name, int i)
-{
-    //char last = name[strlen(name)-1];
-    //if (last>='0' && last <= '9')
-    //  return;
-    sprintf(name + strlen(name), "%d", i);
-}
-
-
-struct _frapl_t {
-    unsigned int nb;
-    char **names;
-    int *fids;
-    uint64_t *values;
-    uint64_t *tmp_values;
-
-};
-typedef struct _frapl_t _frapl_t;
-
-
-void
-add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
-{
-    rapl->nb += 1;
-    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
-    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
-
-    rapl->names[rapl->nb - 1] = malloc(strlen(name) + 1);
-    strcpy(rapl->names[rapl->nb - 1], name);
-    //printf("%s\n", energy_uj);
-
-    int fd = open(energy_uj, O_RDONLY);
-
-    if (fd < 0) {
-        fprintf(stderr, "%s ", energy_uj);
-        perror("open");
-        exit(1);
-    }
-
-    rapl->fids[rapl->nb - 1] = fd;
-}
-
-
-void
-_get_frapl(uint64_t *values, _frapl_t *rapl)
-{
-    static char buffer[512];
-
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-
-        if (pread(rapl->fids[i], buffer, 100, 0) < 0) {
-            perror("pread");
-            exit(1);
-        }
-
-        values[i] = strtoull(buffer, NULL, 10);
-    }
-}
-
-
-unsigned int
-init_frapl(char *none, void **ptr)
-{
-    UNUSED(none);
-    _frapl_t *rapl = malloc(sizeof(_frapl_t));
-    rapl->nb = 0;
-    rapl->names = NULL;
-    rapl->fids = NULL;
-
-    char buffer[1024];
-    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
-    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
-
-    for (unsigned int i = 0;; i++) {
-        sprintf(buffer, name_base, i, "name");
-        char *tmp = get_frapl_string(buffer);
-
-        if (tmp == NULL) {
-            break;
-        }
-
-        //printf("%s\n", tmp);
-        test_append(tmp, i);
-        //printf("%s -> %s\n", buffer, tmp);
-
-        sprintf(buffer, name_base, i, "energy_uj");
-        add_frapl_source(rapl, tmp, buffer);
-        free(tmp);
-
-        for (unsigned int j = 0;; j++) {
-            sprintf(buffer, name_sub, i, i, j, "name");
-            char *tmp_sub = get_frapl_string(buffer);
-
-            if (tmp_sub == NULL) {
-                break;
-            }
-
-            //printf("%s\n", tmp_sub);
-            test_append(tmp_sub, i);
-            //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-            sprintf(buffer, name_sub, i, i, j, "energy_uj");
-            add_frapl_source(rapl, tmp_sub, buffer);
-
-            free(tmp_sub);
-        }
-    }
-
-    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
-
-    _get_frapl(rapl->values, rapl);
-
-    *ptr = (void *)rapl;
-    return rapl->nb;
-}
-
-
-unsigned int
-get_frapl(uint64_t *results, void *ptr)
-{
-    _frapl_t *state = (_frapl_t *) ptr;
-    _get_frapl(state->tmp_values, state);
-
-    for (unsigned int i = 0; i < state->nb; i++) {
-        results[i] = state->tmp_values[i] - state->values[i];
-    }
-
-    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-    return state->nb;
-}
-
-void
-clean_frapl(void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        free(rapl->names[i]);
-        close(rapl->fids[i]);
-    }
-
-    free(rapl->names);
-    free(rapl->fids);
-    free(rapl->values);
-    free(rapl->tmp_values);
-    free(rapl);
-}
-
-
-void
-label_frapl(char **labels, void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        labels[i] = rapl->names[i];
-    }
-}
diff --git a/src/frapl.h b/src/frapl.h
deleted file mode 100644
index 937108e..0000000
--- a/src/frapl.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_frapl(char *, void **);
-unsigned int get_frapl(uint64_t *results, void *);
-void clean_frapl(void *);
-void label_frapl(char **labels, void *);
-
diff --git a/src/mojitos.c b/src/mojitos.c
index c0a5655..74e6e9a 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -27,11 +27,10 @@
 #include <unistd.h>
 
 #include "counters.h"
-#include "frapl.h"
+#include "rapl.h"
 #include "infiniband.h"
 #include "load.h"
 #include "network.h"
-#include "rapl.h"
 #include "temperature.h"
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
@@ -188,9 +187,6 @@ main(int argc, char **argv)
         case 'r':
             add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
             break;
-        case 'R':
-            add_source(init_frapl, NULL, label_frapl, get_frapl, clean_frapl);
-            break;
         case 'u':
             add_source(init_load, NULL, label_load, get_load, clean_load);
             break;
diff --git a/src/rapl.c b/src/rapl.c
index 0119a4f..90dc838 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
@@ -21,118 +21,141 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <errno.h>
 
-#include <powercap/powercap-rapl.h>
 
+#define MAX_HEADER 128
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
+
+char *
+get_rapl_string(const char *filename)
+{
+    int fd = open(filename, O_RDONLY);
+    if (fd == -1) {
+        return NULL;
+    }
+
+    char *result = malloc(MAX_HEADER);
+    int nb = read(fd, result, MAX_HEADER);
+    close(fd);
+    result[nb - 1] = 0;
+    return (result);
+}
+
+void
+test_append(char *name, int i)
+{
+    //char last = name[strlen(name)-1];
+    //if (last>='0' && last <= '9')
+    //  return;
+    sprintf(name + strlen(name), "%d", i);
+}
+
+
 struct _rapl_t {
-    powercap_rapl_pkg *pkgs;
-    uint32_t nb_pkgs;
-    uint32_t nb;
+    unsigned int nb;
     char **names;
-    uint32_t *zones;
-    uint32_t *packages;
+    int *fids;
     uint64_t *values;
     uint64_t *tmp_values;
-};
 
+};
 typedef struct _rapl_t _rapl_t;
 
 
+void
+add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
+{
+    rapl->nb += 1;
+    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
+    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
 
+    rapl->names[rapl->nb - 1] = malloc(strlen(name) + 1);
+    strcpy(rapl->names[rapl->nb - 1], name);
+    //printf("%s\n", energy_uj);
 
+    int fd = open(energy_uj, O_RDONLY);
 
+    if (fd < 0) {
+        fprintf(stderr, "%s ", energy_uj);
+        perror("open");
+        exit(1);
+    }
 
-const int nb_zones = 3;
-const int rapl_zones[3] = { POWERCAP_RAPL_ZONE_PACKAGE,   POWERCAP_RAPL_ZONE_CORE,   POWERCAP_RAPL_ZONE_DRAM};
-
+    rapl->fids[rapl->nb - 1] = fd;
+}
 
-#define MAX_LEN_NAME 100
 
-// values [zone + package *nbzones] microjoules
 void
 _get_rapl(uint64_t *values, _rapl_t *rapl)
 {
+    static char buffer[512];
+
     for (unsigned int i = 0; i < rapl->nb; i++) {
-#ifdef DEBUG
-        int ret =
-#endif
-            powercap_rapl_get_energy_uj(&rapl->pkgs[rapl->packages[i]],
-                                        rapl->zones[i],
-                                        &values[i]);
-#ifdef DEBUG
-        printf("GETRAPL: package %d, zone %d, name %s, ret: %d\n", rapl->packages[i], rapl->zones[i], rapl->names[i], ret);
-#endif
+
+        if (pread(rapl->fids[i], buffer, 100, 0) < 0) {
+            perror("pread");
+            exit(1);
+        }
+
+        values[i] = strtoull(buffer, NULL, 10);
     }
 }
 
+
 unsigned int
 init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    // get number of processor sockets
-    _rapl_t *rapl = malloc(sizeof(struct _rapl_t));
+    _rapl_t *rapl = malloc(sizeof(_rapl_t));
     rapl->nb = 0;
-    rapl->packages = NULL;
-    rapl->zones = NULL;
-
-    rapl->nb_pkgs = powercap_rapl_get_num_instances();
-    //rapl->nb_pkgs = powercap_rapl_get_num_packages();
+    rapl->names = NULL;
+    rapl->fids = NULL;
 
-    if (rapl->nb_pkgs == 0) {
-        perror("no packages found (maybe the kernel module isn't loaded?)");
-        exit(-1);
-    }
+    char buffer[1024];
+    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
+    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
-    rapl->pkgs = malloc(rapl->nb_pkgs * sizeof(powercap_rapl_pkg));
+    for (unsigned int i = 0;; i++) {
+        sprintf(buffer, name_base, i, "name");
+        char *tmp = get_rapl_string(buffer);
 
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_init(package, &rapl->pkgs[package], 0)) {
-            perror("powercap_rapl_init, check access (root needed ?)");
-            exit(-1);
+        if (tmp == NULL) {
+            break;
         }
 
-    rapl->names = NULL;
+        //printf("%s\n", tmp);
+        test_append(tmp, i);
+        //printf("%s -> %s\n", buffer, tmp);
 
-    char _name[MAX_LEN_NAME + 1];
-    char _name2[MAX_LEN_NAME + 11];
+        sprintf(buffer, name_base, i, "energy_uj");
+        add_rapl_source(rapl, tmp, buffer);
+        free(tmp);
 
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++) {
-        for (unsigned int zone = 0; zone < nb_zones; zone++) {
-            int length = powercap_rapl_get_name(&rapl->pkgs[package], rapl_zones[zone],
-                                                _name, MAX_LEN_NAME);
+        for (unsigned int j = 0;; j++) {
+            sprintf(buffer, name_sub, i, i, j, "name");
+            char *tmp_sub = get_rapl_string(buffer);
 
-            if (length > 0) {
+            if (tmp_sub == NULL) {
+                break;
+            }
 
-                sprintf(_name2, "%s%u", _name, package);
+            //printf("%s\n", tmp_sub);
+            test_append(tmp_sub, i);
+            //printf("%s -> %s\n", buffer, tmp_sub);
 
-                rapl->nb++;
-                rapl->names = realloc(rapl->names, sizeof(char *)*rapl->nb);
-                rapl->names[rapl->nb - 1] = malloc(sizeof(char) * (strlen(_name2) + 1));
-                rapl->zones = realloc(rapl->zones, sizeof(uint32_t) * rapl->nb);
-                rapl->packages = realloc(rapl->packages, sizeof(uint32_t) * rapl->nb);
 
-                strcpy(rapl->names[rapl->nb - 1], _name2);
-                rapl->zones[rapl->nb - 1] = rapl_zones[zone];
-                rapl->packages[rapl->nb - 1] = package;
-            }
+            sprintf(buffer, name_sub, i, i, j, "energy_uj");
+            add_rapl_source(rapl, tmp_sub, buffer);
 
-#ifdef DEBUG
-            printf("%d %d %d %d %s\n\n", length, package, zone, rapl_zones[zone], _name2);
-#endif
+            free(tmp_sub);
         }
     }
 
-#ifdef DEBUG
-    printf("Result of init\n");
-
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        printf("package %d, zone %d, name %s\n", rapl->packages[i], rapl->zones[i], rapl->names[i]);
-    }
-
-#endif
-
     rapl->values = calloc(sizeof(uint64_t), rapl->nb);
     rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
 
@@ -143,7 +166,6 @@ init_rapl(char *none, void **ptr)
 }
 
 
-
 unsigned int
 get_rapl(uint64_t *results, void *ptr)
 {
@@ -158,32 +180,24 @@ get_rapl(uint64_t *results, void *ptr)
     return state->nb;
 }
 
-
-
-
 void
 clean_rapl(void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
 
-    for (unsigned int package = 0; package < rapl->nb_pkgs; package++)
-        if (powercap_rapl_destroy(&rapl->pkgs[package])) {
-            perror("powercap_rapl_destroy");
-        }
-
-    for (unsigned int elem = 0; elem < rapl->nb; elem++) {
-        free(rapl->names[elem]);
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+        free(rapl->names[i]);
+        close(rapl->fids[i]);
     }
 
     free(rapl->names);
-    free(rapl->pkgs);
-    free(rapl->zones);
-    free(rapl->packages);
+    free(rapl->fids);
     free(rapl->values);
     free(rapl->tmp_values);
     free(rapl);
 }
 
+
 void
 label_rapl(char **labels, void *ptr)
 {
diff --git a/src/rapl.h b/src/rapl.h
index 74cc515..ddce4cc 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
-- 
GitLab


From fdd08d9a4376a284cf06c0a13ed5d422d39125a7 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 15:01:44 +0100
Subject: [PATCH 026/229] properly reformat this time..

---
 src/counters.c       | 38 +++++++++++++-------------------------
 src/counters_group.c | 20 +++++++-------------
 src/infiniband.c     |  6 ++----
 src/load.c           | 15 +++++----------
 src/mojitos.c        | 20 +++++++-------------
 src/network.c        | 15 +++++----------
 src/rapl.c           | 24 ++++++++----------------
 src/temperature.c    | 21 +++++++--------------
 8 files changed, 54 insertions(+), 105 deletions(-)

diff --git a/src/counters.c b/src/counters.c
index 7441a07..de00d62 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -42,16 +42,14 @@ typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void
-show_all_counters()
+void show_all_counters()
 {
     for (unsigned int i = 0; i < nb_counter_option; i++) {
         printf("%s\n", perf_static_info[i].name);
     }
 }
 
-void
-perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
+void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
 {
     *perf_type = malloc(nb * sizeof(__u32));
     *perf_key  = malloc(nb * sizeof(__u64));
@@ -61,8 +59,7 @@ perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
         (*perf_type)[i] = perf_static_info[indexes[i]].perf_type;
     }
 }
-void
-perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
+void perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
 {
     char *token;
     *nb_perf = 0;
@@ -88,9 +85,8 @@ perf_event_list(char *perf_string, int *nb_perf, int **perf_indexes)
     }
 }
 
-static long
-perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                int cpu, int group_fd, unsigned long flags)
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                            int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
 
@@ -103,8 +99,7 @@ perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
     return res;
 }
 
-counter_t
-_init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
@@ -130,8 +125,7 @@ _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
     return counters;
 }
 
-void
-clean_counters(void *ptr)
+void clean_counters(void *ptr)
 {
     counter_t counters = (counter_t) ptr;
 
@@ -151,8 +145,7 @@ clean_counters(void *ptr)
     free(counters);
 }
 
-void
-start_counters(counter_t counters)
+void start_counters(counter_t counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -161,8 +154,7 @@ start_counters(counter_t counters)
     }
 }
 
-void
-reset_counters(counter_t counters)
+void reset_counters(counter_t counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -171,8 +163,7 @@ reset_counters(counter_t counters)
     }
 }
 
-void
-_get_counters(counter_t counters, uint64_t *values)
+void _get_counters(counter_t counters, uint64_t *values)
 {
     for (int i = 0; i < counters->nbperf; i++) {
         uint64_t accu = 0;
@@ -195,8 +186,7 @@ _get_counters(counter_t counters, uint64_t *values)
 
 
 
-unsigned int
-init_counters(char *args, void **state)
+unsigned int init_counters(char *args, void **state)
 {
     int nb_perf;
     int *perf_indexes = NULL;
@@ -220,8 +210,7 @@ init_counters(char *args, void **state)
     return nb_perf;
 }
 
-unsigned int
-get_counters(uint64_t *results, void *ptr)
+unsigned int get_counters(uint64_t *results, void *ptr)
 {
     counter_t state = (counter_t) ptr;
 
@@ -235,8 +224,7 @@ get_counters(uint64_t *results, void *ptr)
     return state->nbperf;
 }
 
-void
-label_counters(char **labels, void *ptr)
+void label_counters(char **labels, void *ptr)
 {
     counter_t state = (counter_t) ptr;
 
diff --git a/src/counters_group.c b/src/counters_group.c
index aa441d5..66eba2c 100644
--- a/src/counters_group.c
+++ b/src/counters_group.c
@@ -35,9 +35,8 @@ struct _counter_t {
     int *counters;
 };
 
-static long
-perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                int cpu, int group_fd, unsigned long flags)
+static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
+                            int cpu, int group_fd, unsigned long flags)
 {
     long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
 
@@ -50,8 +49,7 @@ perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
     return res;
 }
 
-counter_t
-init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     struct _counter_t *counters = malloc(sizeof(struct _counter_t));
@@ -83,8 +81,7 @@ init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
     return counters;
 }
 
-void
-clean_counters(counter_t counters)
+void clean_counters(counter_t counters)
 {
     for (int core = 0; core < counters->nbcores; core++) {
         close(counters->counters[core]);
@@ -94,15 +91,13 @@ clean_counters(counter_t counters)
     free(counters);
 }
 
-void
-start_counters(counter_t counters)
+void start_counters(counter_t counters)
 {
     for (int core = 0; core < counters->nbcores; core++) {
         ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
     }
 }
-void
-reset_counters(counter_t counters)
+void reset_counters(counter_t counters)
 {
     for (int core = 0; core < counters->nbcores; core++) {
         ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
@@ -116,8 +111,7 @@ struct read_format {
     } values[];
 };
 
-void
-get_counters(counter_t counters, long long *values)
+void get_counters(counter_t counters, long long *values)
 {
     int nb_perf = counters->nbperf;
     size_t buffer_size = sizeof(uint64_t) * (1 + nb_perf);
diff --git a/src/infiniband.c b/src/infiniband.c
index d5da4eb..6f47ab2 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -37,8 +37,7 @@ struct network_t {
 unsigned int _get_network(uint64_t *results, int *sources);
 
 
-unsigned int
-init_infiniband(char *infi_path, void **ptr)
+unsigned int init_infiniband(char *infi_path, void **ptr)
 {
     if (infi_path == NULL) {
         return 0;
@@ -78,8 +77,7 @@ init_infiniband(char *infi_path, void **ptr)
 }
 
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
-void
-label_infiniband(char **labels, void *none)
+void label_infiniband(char **labels, void *none)
 {
     UNUSED(none);
 
diff --git a/src/load.c b/src/load.c
index c0013ab..96d08b8 100644
--- a/src/load.c
+++ b/src/load.c
@@ -33,8 +33,7 @@ static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
-void
-_get_load(uint64_t *results)
+void _get_load(uint64_t *results)
 {
     if (pread(load_fid, buffer, LOAD_BUFFER_SIZE - 1, 0) < 0) {
         perror("pread");
@@ -60,8 +59,7 @@ _get_load(uint64_t *results)
 
 // Public interface
 
-unsigned int
-init_load(char *argument, void **state)
+unsigned int init_load(char *argument, void **state)
 {
     UNUSED(argument);
     UNUSED(state);
@@ -76,8 +74,7 @@ init_load(char *argument, void **state)
     return 10;
 }
 
-unsigned int
-get_load(uint64_t *results, void *state)
+unsigned int get_load(uint64_t *results, void *state)
 {
     UNUSED(state);
     _get_load(tmp_load_values);
@@ -90,8 +87,7 @@ get_load(uint64_t *results, void *state)
     return 10;
 }
 
-void
-clean_load(void *state)
+void clean_load(void *state)
 {
     UNUSED(state);
     close(load_fid);
@@ -100,8 +96,7 @@ clean_load(void *state)
 char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
                      "softirq", "steal", "guest", "guest_nice"
                     };
-void
-label_load(char **labels, void *none)
+void label_load(char **labels, void *none)
 {
     UNUSED(none);
 
diff --git a/src/mojitos.c b/src/mojitos.c
index 74e6e9a..b6c057f 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -43,8 +43,7 @@
 	} while (0)
 
 
-void
-usage(char **argv)
+void usage(char **argv)
 {
     printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
            "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
@@ -64,22 +63,19 @@ usage(char **argv)
     exit(EXIT_SUCCESS);
 }
 
-void
-sighandler(int none)
+void sighandler(int none)
 {
     UNUSED(none);
 }
 
-void
-flush(int none)
+void flush(int none)
 {
     UNUSED(none);
     exit(0);
 }
 
 FILE *output;
-void
-flushexit()
+void flushexit()
 {
     if (output != NULL) {
         fflush(output);
@@ -101,9 +97,8 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void
-add_source(initializer_t init, char *arg, labeler_t labeler,
-           getter_t get, cleaner_t clean)
+void add_source(initializer_t init, char *arg, labeler_t labeler,
+                getter_t get, cleaner_t clean)
 {
     nb_sources++;
     states = realloc(states, nb_sources * sizeof(void *));
@@ -127,8 +122,7 @@ add_source(initializer_t init, char *arg, labeler_t labeler,
     nb_sensors += nb;
 }
 
-int
-main(int argc, char **argv)
+int main(int argc, char **argv)
 {
     int total_time = 1;
     int delta = 0;
diff --git a/src/network.c b/src/network.c
index 5b94151..f57a383 100644
--- a/src/network.c
+++ b/src/network.c
@@ -34,8 +34,7 @@ struct network_t {
     int sources[NB_SENSOR];
 };
 
-unsigned int
-_get_network(uint64_t *results, int *sources)
+unsigned int _get_network(uint64_t *results, int *sources)
 {
     if (sources == NULL) {
         return 0;
@@ -57,8 +56,7 @@ _get_network(uint64_t *results, int *sources)
 
 
 
-unsigned int
-init_network(char *dev, void **ptr)
+unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
         return 0;
@@ -108,8 +106,7 @@ init_network(char *dev, void **ptr)
     return NB_SENSOR;
 }
 
-unsigned int
-get_network(uint64_t *results, void *ptr)
+unsigned int get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
     _get_network(state->tmp_values, state->sources);
@@ -122,8 +119,7 @@ get_network(uint64_t *results, void *ptr)
     return NB_SENSOR;
 }
 
-void
-clean_network(void *ptr)
+void clean_network(void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
 
@@ -139,8 +135,7 @@ clean_network(void *ptr)
 }
 
 char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void
-label_network(char **labels, void *none)
+void label_network(char **labels, void *none)
 {
     UNUSED(none);
 
diff --git a/src/rapl.c b/src/rapl.c
index 90dc838..cd558d2 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -31,8 +31,7 @@
 #define UNUSED(expr) do { (void)(expr); } while (0)
 
 
-char *
-get_rapl_string(const char *filename)
+char *get_rapl_string(const char *filename)
 {
     int fd = open(filename, O_RDONLY);
     if (fd == -1) {
@@ -46,8 +45,7 @@ get_rapl_string(const char *filename)
     return (result);
 }
 
-void
-test_append(char *name, int i)
+void test_append(char *name, int i)
 {
     //char last = name[strlen(name)-1];
     //if (last>='0' && last <= '9')
@@ -67,8 +65,7 @@ struct _rapl_t {
 typedef struct _rapl_t _rapl_t;
 
 
-void
-add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
+void add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
 {
     rapl->nb += 1;
     rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
@@ -90,8 +87,7 @@ add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
 }
 
 
-void
-_get_rapl(uint64_t *values, _rapl_t *rapl)
+void _get_rapl(uint64_t *values, _rapl_t *rapl)
 {
     static char buffer[512];
 
@@ -107,8 +103,7 @@ _get_rapl(uint64_t *values, _rapl_t *rapl)
 }
 
 
-unsigned int
-init_rapl(char *none, void **ptr)
+unsigned int init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
     _rapl_t *rapl = malloc(sizeof(_rapl_t));
@@ -166,8 +161,7 @@ init_rapl(char *none, void **ptr)
 }
 
 
-unsigned int
-get_rapl(uint64_t *results, void *ptr)
+unsigned int get_rapl(uint64_t *results, void *ptr)
 {
     _rapl_t *state = (_rapl_t *) ptr;
     _get_rapl(state->tmp_values, state);
@@ -180,8 +174,7 @@ get_rapl(uint64_t *results, void *ptr)
     return state->nb;
 }
 
-void
-clean_rapl(void *ptr)
+void clean_rapl(void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
 
@@ -198,8 +191,7 @@ clean_rapl(void *ptr)
 }
 
 
-void
-label_rapl(char **labels, void *ptr)
+void label_rapl(char **labels, void *ptr)
 {
     _rapl_t *rapl = (_rapl_t *) ptr;
 
diff --git a/src/temperature.c b/src/temperature.c
index d0d1e9e..049ade7 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -33,8 +33,7 @@ struct temperature_t {
     int nb_elem;
 };
 
-int
-get_string(char *filename, char *buffer, int max_size)
+int get_string(char *filename, char *buffer, int max_size)
 {
     int fid = open(filename, O_RDONLY);
 
@@ -54,8 +53,7 @@ get_string(char *filename, char *buffer, int max_size)
     return 0;
 }
 
-void
-add_to_list(char ***list_name, char *source, int nb_elem)
+void add_to_list(char ***list_name, char *source, int nb_elem)
 {
     //printf("Adds: %s\n", source);
     *list_name = realloc(*list_name, (nb_elem + 1) * sizeof(char *));
@@ -64,8 +62,7 @@ add_to_list(char ***list_name, char *source, int nb_elem)
 
 }
 
-void
-add_temperature_sensor(int id_rep, struct temperature_t *state)
+void add_temperature_sensor(int id_rep, struct temperature_t *state)
 {
     static int key = 0;
     static char buffer_filename[512];
@@ -110,8 +107,7 @@ add_temperature_sensor(int id_rep, struct temperature_t *state)
     key++;
 }
 
-unsigned int
-init_temperature(char *args, void **ptr)
+unsigned int init_temperature(char *args, void **ptr)
 {
     UNUSED(args);
     struct temperature_t *state = malloc(sizeof(struct temperature_t));
@@ -139,8 +135,7 @@ init_temperature(char *args, void **ptr)
     return state->nb_elem;
 }
 
-unsigned int
-get_temperature(uint64_t *results, void *ptr)
+unsigned int get_temperature(uint64_t *results, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
     static char buffer[512];
@@ -156,8 +151,7 @@ get_temperature(uint64_t *results, void *ptr)
     return state->nb_elem;
 }
 
-void
-clean_temperature(void *ptr)
+void clean_temperature(void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
 
@@ -171,8 +165,7 @@ clean_temperature(void *ptr)
     free(state);
 }
 
-void
-label_temperature(char **labels, void *ptr)
+void label_temperature(char **labels, void *ptr)
 {
     struct temperature_t *state = (struct temperature_t *)ptr;
 
-- 
GitLab


From d2075487da6b1e50e265c4f1d2761b0ae1315fea Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 15:32:04 +0100
Subject: [PATCH 027/229] cleanup, corrections

---
 makefile             |   4 +-
 src/counters_group.c | 138 -------------------------------
 src/frapl.c          | 192 -------------------------------------------
 3 files changed, 2 insertions(+), 332 deletions(-)
 delete mode 100644 src/counters_group.c
 delete mode 100644 src/frapl.c

diff --git a/makefile b/makefile
index bc3dd53..66a376c 100644
--- a/makefile
+++ b/makefile
@@ -19,10 +19,10 @@ all: mojitos
 mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
 	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
 
-$(OBJ_DIR)/counters_%.o: $(SRC_DIR)/counters_%.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
+$(OBJ_DIR)/counters.o: $(SRC_DIR)/counters.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.py
+$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
 	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
 
 $(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
diff --git a/src/counters_group.c b/src/counters_group.c
deleted file mode 100644
index 66eba2c..0000000
--- a/src/counters_group.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <linux/perf_event.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/ioctl.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <asm/unistd.h>
-
-#include "counters.h"
-
-struct _counter_t {
-    int nbcores;
-    int nbperf;
-    int *counters;
-};
-
-static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
-                            int cpu, int group_fd, unsigned long flags)
-{
-    long res = syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd, flags);
-
-    if (res == -1) {
-        perror("perf_event_open");
-        fprintf(stderr, "Error opening leader %llx\n", hw_event->config);
-        exit(EXIT_FAILURE);
-    }
-
-    return res;
-}
-
-counter_t init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
-{
-    struct perf_event_attr pe;
-    struct _counter_t *counters = malloc(sizeof(struct _counter_t));
-
-    unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
-    counters->nbcores = nbcores;
-    counters->nbperf = nb_perf;
-    memset(&pe, 0, sizeof(struct perf_event_attr));
-    pe.size = sizeof(struct perf_event_attr);
-    pe.disabled = 1;
-
-    pe.read_format = PERF_FORMAT_GROUP;
-    counters->counters = malloc((nbcores + 1) * sizeof(int));
-
-    for (int core = 0; core < nbcores; core++) {
-        counters->counters[core] = -1;
-
-        for (int idperf = 0; idperf < nb_perf; idperf ++) {
-            pe.type = types[idperf];
-            pe.config = names[idperf];
-            int res = perf_event_open(&pe, -1, core, counters->counters[core], PERF_FLAG_FD_CLOEXEC);
-
-            if (counters->counters[core] == -1) {
-                counters->counters[core] = res;
-            }
-        }
-    }
-
-    return counters;
-}
-
-void clean_counters(counter_t counters)
-{
-    for (int core = 0; core < counters->nbcores; core++) {
-        close(counters->counters[core]);
-    }
-
-    free(counters->counters);
-    free(counters);
-}
-
-void start_counters(counter_t counters)
-{
-    for (int core = 0; core < counters->nbcores; core++) {
-        ioctl(counters->counters[core], PERF_EVENT_IOC_ENABLE, PERF_IOC_FLAG_GROUP);
-    }
-}
-void reset_counters(counter_t counters)
-{
-    for (int core = 0; core < counters->nbcores; core++) {
-        ioctl(counters->counters[core], PERF_EVENT_IOC_RESET, PERF_IOC_FLAG_GROUP);
-    }
-}
-
-struct read_format {
-    uint64_t nr;
-    struct {
-        uint64_t value;
-    } values[];
-};
-
-void get_counters(counter_t counters, long long *values)
-{
-    int nb_perf = counters->nbperf;
-    size_t buffer_size = sizeof(uint64_t) * (1 + nb_perf);
-    struct read_format *buffer = NULL;
-
-    if (buffer == NULL) {
-        buffer = malloc(buffer_size);
-    }
-
-    memset(values, 0, nb_perf * sizeof(long long));
-
-    for (int core = 0; core < counters->nbcores; core++) {
-        if (-1 == read(counters->counters[core], buffer, buffer_size)) {
-            perror("PB Lecture resultat");
-            exit(EXIT_FAILURE);
-        }
-
-        for (int idperf = 0; idperf <= nb_perf; idperf++) {
-            values[idperf] += buffer->values[idperf].value;
-        }
-    }
-
-    reset_counters(counters);
-}
diff --git a/src/frapl.c b/src/frapl.c
deleted file mode 100644
index 6048e1d..0000000
--- a/src/frapl.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <inttypes.h>
-#include <errno.h>
-
-
-#define MAX_HEADER 128
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
-
-char *get_frapl_string(const char *filename)
-{
-    int fd = open(filename, O_RDONLY);
-    if( fd == -1)
-        {
-            return NULL;
-        }
-    char *result = malloc(MAX_HEADER);
-    int nb = read(fd, result, MAX_HEADER);
-    close(fd);
-    result[nb-1] = 0;
-    return (result);
-}
-
-void test_append(char *name, int i)
-{
-    //char last = name[strlen(name)-1];
-    //if (last>='0' && last <= '9')
-    //  return;
-    sprintf(name+strlen(name), "%d", i);
-}
-
-
-struct _frapl_t
-{
-    unsigned int nb;
-    char **names;
-    int *fids;
-    uint64_t *values;
-    uint64_t *tmp_values;
-
-};
-typedef struct _frapl_t _frapl_t;
-
-
-void add_frapl_source(_frapl_t *rapl, char *name, char *energy_uj)
-{
-    rapl->nb += 1;
-    rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
-    rapl->fids = realloc(rapl->fids, sizeof(int *)*rapl->nb);
-
-    rapl->names[rapl->nb-1] = malloc(strlen(name)+1);
-    strcpy(rapl->names[rapl->nb-1], name);
-    //printf("%s\n", energy_uj);
-
-    int fd = open(energy_uj, O_RDONLY);
-
-    if (fd < 0)
-        {
-            fprintf(stderr, "%s ", energy_uj);
-            perror("open");
-            exit(1);
-        }
-    rapl->fids[rapl->nb-1] = fd;
-}
-
-
-void _get_frapl(uint64_t *values, _frapl_t *rapl)
-{
-    static char buffer[512];
-
-    for (unsigned int i = 0; i < rapl->nb; i++)
-        {
-
-            if (pread(rapl->fids[i], buffer, 100, 0) < 0)
-                {
-                    perror("pread");
-                    exit(1);
-                }
-            values[i] = strtoull(buffer, NULL, 10);
-        }
-}
-
-
-unsigned int init_frapl(char *none, void **ptr)
-{
-    UNUSED(none);
-    _frapl_t *rapl = malloc(sizeof(_frapl_t));
-    rapl->nb = 0;
-    rapl->names = NULL;
-    rapl->fids = NULL;
-
-    char buffer[1024];
-    char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
-    char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
-
-    for (unsigned int i=0;; i++)
-        {
-            sprintf(buffer, name_base, i, "name");
-            char *tmp = get_frapl_string(buffer);
-            if (tmp == NULL) break;
-            //printf("%s\n", tmp);
-            test_append(tmp, i);
-            //printf("%s -> %s\n", buffer, tmp);
-
-            sprintf(buffer, name_base, i, "energy_uj");
-            add_frapl_source(rapl, tmp, buffer);
-            free(tmp);
-
-            for (unsigned int j=0;; j++)
-                {
-                    sprintf(buffer, name_sub, i, i, j, "name");
-                    char *tmp_sub = get_frapl_string(buffer);
-                    if (tmp_sub == NULL) break;
-                    //printf("%s\n", tmp_sub);
-                    test_append(tmp_sub, i);
-                    //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-                    sprintf(buffer, name_sub, i, i, j, "energy_uj");
-                    add_frapl_source(rapl, tmp_sub, buffer);
-
-                    free(tmp_sub);
-                }
-        }
-
-    rapl->values = calloc(sizeof(uint64_t), rapl->nb);
-    rapl->tmp_values = calloc(sizeof(uint64_t), rapl->nb);
-
-    _get_frapl(rapl->values, rapl);
-
-    *ptr = (void *)rapl;
-    return rapl->nb;
-}
-
-
-unsigned int get_frapl(uint64_t *results, void *ptr)
-{
-    _frapl_t *state = (_frapl_t *) ptr;
-    _get_frapl(state->tmp_values, state);
-    for(unsigned int i=0; i<state->nb; i++)
-        results[i] = state->tmp_values[i] - state->values[i];
-
-    memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
-    return state->nb;
-}
-
-void clean_frapl(void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        {
-            free(rapl->names[i]);
-            close(rapl->fids[i]);
-        }
-    free(rapl->names);
-    free(rapl->fids);
-    free(rapl->values);
-    free(rapl->tmp_values);
-    free(rapl);
-}
-
-
-void label_frapl(char **labels, void *ptr)
-{
-    _frapl_t *rapl = (_frapl_t *) ptr;
-    for(unsigned int i=0; i<rapl->nb; i++)
-        labels[i] = rapl->names[i];
-}
-- 
GitLab


From 8ff09885f804be8bfd04b4d7c7510d91c7ee4bd9 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 17:56:00 +0100
Subject: [PATCH 028/229] small changes on makefile

- .POSIX rule
- BIN macro
- add LDFLAGS
- some other changes..
---
 makefile | 38 ++++++++++++++++++++++++--------------
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/makefile b/makefile
index 66a376c..4d3fa12 100644
--- a/makefile
+++ b/makefile
@@ -1,36 +1,44 @@
-.PHONY: all clean mojitos mojitos_group debug format
+.POSIX:
 
 SRC_DIR = src
 OBJ_DIR = obj
 BIN_DIR = bin
 
-OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o)
-OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
+BIN = mojitos
+
+OBJ = $(addprefix $(OBJ_DIR)/,  \
+	counters.o \
+	rapl.o \
+	network.o \
+	load.o \
+	infiniband.o \
+	temperature.o \
+)
 
 CC = gcc
 CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
+LDFLAGS = -lpowercap
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-# depending on the context it may need to be changed to all: mojitos mojitos_group
-all: mojitos
-
-mojitos: $(OBJ_DIR) $(BIN_DIR) $(OBJECTS)
-	$(CC) $(CFLAGS) -o $(BIN_DIR)/mojitos $(OBJECTS) -lpowercap
+all: $(BIN)
 
-$(OBJ_DIR)/counters.o: $(SRC_DIR)/counters.c $(SRC_DIR)/counters.h $(SRC_DIR)/counters_option.h
-	$(CC) $(CFLAGS) -c $< -o $@
+$(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
+	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
 
-$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
-	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
+$(OBJ): $(OBJ_DIR)
+$(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
 
-$(OBJ_DIR)/mojitos.o: $(SRC_DIR)/mojitos.c $(SRC_DIR)/counters_option.h
+$(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(OBJ_DIR)/%.o : $(SRC_DIR)/%.c $(SRC_DIR)/%.h
+$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
+$(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
+	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
+
 $(OBJ_DIR):
 	mkdir -p $(OBJ_DIR)
 
@@ -46,3 +54,5 @@ format:
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
 	\rm -f $(SRC_DIR)/counters_option.h
+
+.PHONY: all clean mojitos debug format
-- 
GitLab


From 471ccfd974c5b8d1f2316d57fade66fc24dc06fc Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 19:52:23 +0100
Subject: [PATCH 029/229] replace getop with "optparse"

plus usage fix
and makefile fix

add long options
---
 makefile      |  2 +-
 src/mojitos.c | 55 +++++++++++++++++++++++++++++++++------------------
 2 files changed, 37 insertions(+), 20 deletions(-)

diff --git a/makefile b/makefile
index 4d3fa12..488f39c 100644
--- a/makefile
+++ b/makefile
@@ -16,7 +16,7 @@ OBJ = $(addprefix $(OBJ_DIR)/,  \
 )
 
 CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
+CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
 LDFLAGS = -lpowercap
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
diff --git a/src/mojitos.c b/src/mojitos.c
index b6c057f..cd8fcad 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -33,6 +33,10 @@
 #include "network.h"
 #include "temperature.h"
 
+#define OPTPARSE_IMPLEMENTATION
+#define OPTPARSE_API static
+#include "optparse.h"
+
 #define UNUSED(expr) do { (void)(expr); } while (0)
 #define PANIC(code, fmt, ...)  				 \
 	do {									 \
@@ -45,12 +49,11 @@
 
 void usage(char **argv)
 {
-    printf("Usage : %s [-rRluc] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
+    printf("Usage : %s [-rlucs] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
            "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
            "if time==0 then loops infinitively\n"
            "if -e is present, time and freq are not used\n"
            "-r activates RAPL\n"
-           "-R activates the file version of RAPL\n"
            "-p activates performance counters\n"
            "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
            "-l lists the possible performance counters and quits\n"
@@ -60,7 +63,7 @@ void usage(char **argv)
            "-u activates report of system load\n"
            "-c activates report of processor temperature\n"
            , argv[0]);
-    exit(EXIT_SUCCESS);
+    exit(EXIT_FAILURE);
 }
 
 void sighandler(int none)
@@ -140,17 +143,32 @@ int main(int argc, char **argv)
     atexit(flushexit);
     signal(15, flush);
 
-    int c;
-
-    while ((c = getopt (argc, argv, "ilhcftdeoprRsu")) != -1 && application == NULL) {
-        switch (c) {
+    int opt;
+    struct optparse options;
+    options.permute = 0;
+    struct optparse_long longopts[] = {
+        {"monitor-infiniband", 'i', OPTPARSE_REQUIRED},
+        {"freq", 'f', OPTPARSE_REQUIRED},
+        {"time", 't', OPTPARSE_REQUIRED},
+        {"net-dev", 'd', OPTPARSE_REQUIRED},
+        {"exec", 'e', OPTPARSE_REQUIRED},
+        {"logfile", 'o', OPTPARSE_REQUIRED},
+        {"perf-list", 'p', OPTPARSE_REQUIRED},
+        {"cpu-temp", 'c', OPTPARSE_NONE},
+        {"rapl", 'r', OPTPARSE_NONE},
+        {"overhead-stats", 's', OPTPARSE_NONE},
+        {"sysload", 'u', OPTPARSE_NONE},
+        {"list", 'l', OPTPARSE_NONE},
+    };
+
+    optparse_init(&options, argv);
+    while ((opt = optparse_long(&options, longopts, NULL)) != -1 && application == NULL) {
+        switch (opt) {
         case 'f':
-            if (optind >= argc) PANIC(1,"-f, no frequency provided");
-            frequency = atoi(argv[optind]);
+            frequency = atoi(options.optarg);
             break;
         case 't':
-            if (optind >= argc) PANIC(1,"-t, no time provided");
-            total_time = atoi(argv[optind]);
+            total_time = atoi(options.optarg);
             delta = 1;
             if (total_time == 0) {
                 total_time = 1;
@@ -158,25 +176,23 @@ int main(int argc, char **argv)
             }
             break;
         case 'd':
-            add_source(init_network, argv[optind], label_network, get_network, clean_network);
+            add_source(init_network, options.optarg, label_network, get_network, clean_network);
             break;
         case 'i':
-            add_source(init_infiniband, argv[optind], label_infiniband, get_network, clean_network);
+            add_source(init_infiniband, options.optarg, label_infiniband, get_network, clean_network);
             break;
         case 'o':
-            if (optind >= argc) PANIC(1,"-o, no logfile provided");
-            if ((output = fopen(argv[optind], "wb")) == NULL) {
+            if ((output = fopen(options.optarg, "wb")) == NULL) {
                 perror("fopen");
-                PANIC(1, "-o %s", argv[optind]);
+                PANIC(1, "-o %s", options.optarg);
             }
             break;
         case 'e':
-            application = &argv[optind];
+            application = options.argv;
             signal(17, sighandler);
             break;
         case 'p':
-            if (optind >= argc) PANIC(1,"-p, no counter provided");
-            add_source(init_counters, argv[optind], label_counters, get_counters, clean_counters);
+            add_source(init_counters, options.optarg, label_counters, get_counters, clean_counters);
             break;
         case 'r':
             add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
@@ -194,6 +210,7 @@ int main(int argc, char **argv)
             show_all_counters();
             exit(EXIT_SUCCESS);
         default:
+            fprintf(stderr, "%s: %s\n", argv[0], options.errmsg);
             usage(argv);
         }
     }
-- 
GitLab


From f38c9908a426c73f06dfb37d05fd2951064256cb Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 16 Jan 2023 19:54:47 +0100
Subject: [PATCH 030/229] add -Wno-unused-function to CFLAGS in makefile

---
 makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/makefile b/makefile
index 5198055..6a709b2 100644
--- a/makefile
+++ b/makefile
@@ -8,7 +8,7 @@ OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic
+CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-- 
GitLab


From 0fc68415b1b1a773e227cf5406f02629b88d3a6f Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Tue, 17 Jan 2023 19:54:15 +0100
Subject: [PATCH 031/229] utils file

---
 .gitignore             |    8 +-
 LICENSE                | 1348 ++++++++++++++++++++--------------------
 makefile               |    2 +-
 src/counters.h         |   52 +-
 src/counters_option.py |  124 ++--
 src/infiniband.h       |   44 +-
 src/load.h             |   48 +-
 src/network.h          |   50 +-
 src/temperature.h      |   48 +-
 src/util.c             |    6 +
 src/util.h             |    5 +
 11 files changed, 873 insertions(+), 862 deletions(-)
 create mode 100644 src/util.c
 create mode 100644 src/util.h

diff --git a/.gitignore b/.gitignore
index f5893ce..5a8f74f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,4 @@
-*.o
-src/counters_option.h
-bin
-obj
+*.o
+src/counters_option.h
+bin
+obj
diff --git a/LICENSE b/LICENSE
index f288702..3877ae0 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,674 +1,674 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<https://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<https://www.gnu.org/licenses/why-not-lgpl.html>.
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
diff --git a/makefile b/makefile
index 6a709b2..9988f8a 100644
--- a/makefile
+++ b/makefile
@@ -4,7 +4,7 @@ SRC_DIR = src
 OBJ_DIR = obj
 BIN_DIR = bin
 
-OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o)
+OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o util.o)
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
diff --git a/src/counters.h b/src/counters.h
index af20717..bd2d0a5 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,26 +1,26 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_counters(char *, void **);
-unsigned int get_counters(uint64_t *results, void *);
-void clean_counters(void *);
-void label_counters(char **labels, void *);
-
-void show_all_counters();
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_counters(char *, void **);
+unsigned int get_counters(uint64_t *results, void *);
+void clean_counters(void *);
+void label_counters(char **labels, void *);
+
+void show_all_counters();
diff --git a/src/counters_option.py b/src/counters_option.py
index 877a33a..d853e41 100755
--- a/src/counters_option.py
+++ b/src/counters_option.py
@@ -1,62 +1,62 @@
-#! /usr/bin/python3
-
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-linux_include = '/usr/include/linux/perf_event.h'
-
-string = """#include <linux/perf_event.h>
-
-typedef struct counter_option {
-  char *name;
-  __u32 perf_type;
-  __u64 perf_key;
-} counter_option;
-
-static counter_option perf_static_info[] = {"""
-print(string)
-
-nb = 0
-
-black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
-              'cache_l1i', 'cache_op_write', 'cache_result_miss']
-
-with open(linux_include, 'r') as infile:
-    mode = ''
-    for line in infile:
-        if 'perf_hw_id' in line:
-            mode = 'PERF_TYPE_HARDWARE'
-        elif 'perf_hw_cache_' in line:
-            mode = 'PERF_TYPE_HW_CACHE'
-        elif 'perf_sw_id' in line:
-            mode = 'PERF_TYPE_SOFTWARE'
-        elif 'PERF_COUNT_' in line and '=' in line:
-            perf_name = line.split()[0]
-            short_perf = perf_name[14:].lower()
-            if short_perf in black_list:
-                continue
-            if mode == 'PERF_TYPE_HW_CACHE':
-                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
-                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
-                    for result_id, result_id_str in enumerate(['a', 'm']):
-                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
-
-                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
-                            short_perf, op_id_str, result_id_str,
-                            mode,
-                            perf_name,
-                            op_id_names[op_id],
-                            result_id_names[result_id])
-                                                                                     
-                        print(res)
-                        nb += 1
-
-            else:
-                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
-                print(res)
-                nb += 1
-
-
-print('};')
-
-print('static unsigned int nb_counter_option =',nb,';')
+#! /usr/bin/python3
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+linux_include = '/usr/include/linux/perf_event.h'
+
+string = """#include <linux/perf_event.h>
+
+typedef struct counter_option {
+  char *name;
+  __u32 perf_type;
+  __u64 perf_key;
+} counter_option;
+
+static counter_option perf_static_info[] = {"""
+print(string)
+
+nb = 0
+
+black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
+              'cache_l1i', 'cache_op_write', 'cache_result_miss']
+
+with open(linux_include, 'r') as infile:
+    mode = ''
+    for line in infile:
+        if 'perf_hw_id' in line:
+            mode = 'PERF_TYPE_HARDWARE'
+        elif 'perf_hw_cache_' in line:
+            mode = 'PERF_TYPE_HW_CACHE'
+        elif 'perf_sw_id' in line:
+            mode = 'PERF_TYPE_SOFTWARE'
+        elif 'PERF_COUNT_' in line and '=' in line:
+            perf_name = line.split()[0]
+            short_perf = perf_name[14:].lower()
+            if short_perf in black_list:
+                continue
+            if mode == 'PERF_TYPE_HW_CACHE':
+                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
+                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
+                    for result_id, result_id_str in enumerate(['a', 'm']):
+                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
+
+                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
+                            short_perf, op_id_str, result_id_str,
+                            mode,
+                            perf_name,
+                            op_id_names[op_id],
+                            result_id_names[result_id])
+                                                                                     
+                        print(res)
+                        nb += 1
+
+            else:
+                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
+                print(res)
+                nb += 1
+
+
+print('};')
+
+print('static unsigned int nb_counter_option =',nb,';')
diff --git a/src/infiniband.h b/src/infiniband.h
index 1f6aaf9..4234964 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -1,22 +1,22 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_infiniband(char *infi_path, void **ptr);
-void label_infiniband(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_infiniband(char *infi_path, void **ptr);
+void label_infiniband(char **labels, void *);
diff --git a/src/load.h b/src/load.h
index 299fa3e..78c1b40 100644
--- a/src/load.h
+++ b/src/load.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_load(char *, void **);
-unsigned int get_load(uint64_t *results, void *);
-void clean_load(void *);
-void label_load(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_load(char *, void **);
+unsigned int get_load(uint64_t *results, void *);
+void clean_load(void *);
+void label_load(char **labels, void *);
diff --git a/src/network.h b/src/network.h
index 3ba9ae5..b770560 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,25 +1,25 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_network(char *, void **);
-unsigned int get_network(uint64_t *results, void *);
-void clean_network(void *);
-void label_network(char **labels, void *);
-
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_network(char *, void **);
+unsigned int get_network(uint64_t *results, void *);
+void clean_network(void *);
+void label_network(char **labels, void *);
+
diff --git a/src/temperature.h b/src/temperature.h
index e49e416..ac8e34b 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_temperature(char *, void **);
-unsigned int get_temperature(uint64_t *results, void *);
-void clean_temperature(void *);
-void label_temperature(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_temperature(char *, void **);
+unsigned int get_temperature(uint64_t *results, void *);
+void clean_temperature(void *);
+void label_temperature(char **labels, void *);
diff --git a/src/util.c b/src/util.c
new file mode 100644
index 0000000..5ff3acd
--- /dev/null
+++ b/src/util.c
@@ -0,0 +1,6 @@
+#include "util.h"
+
+inline uint64_t substractAcc(const uint64_t l, const uint64_t r)
+{
+    return (l < r) ? UINT64_MAX + (l - r) : l - r;
+}
\ No newline at end of file
diff --git a/src/util.h b/src/util.h
new file mode 100644
index 0000000..83129d8
--- /dev/null
+++ b/src/util.h
@@ -0,0 +1,5 @@
+#pragma once
+
+#include <stdint.h>
+
+inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
\ No newline at end of file
-- 
GitLab


From a5bf8b3f3599f47005acb29b467ff050813b44c6 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 17 Jan 2023 21:25:18 +0100
Subject: [PATCH 032/229] build system (v0), add long options

- mojitos now supports long options, via "optparse.h", written by
  wellons@nullprogram.com and released into the public domain
- one can choose which captor to include or exclude in the final binary
  with `configure.sh`.
- makefile is now POSIX compliant (or at least, should be).
- one now have to fill in the "struct optparse_long" and
  "struct captor" structs when adding a new captor.
- defined a hard limit to the numbers of fixed options (10), and to the
  amount of captors (20). These can be changed by modifying NB_MAX_OPTS
  and NB_MAX_CAPTORS, respectively.
- mojitos now includes "captors.h", generated by the `configure.sh` script
- changed the signature of `add_source()` to:
  void add_source(struct captor*, char*)
- `main()` now must call the `init_captors()` function.
---
 .gitignore        |   1 +
 configure.sh      |  65 ++++++++
 makefile          |  22 +--
 src/counters.h    |  12 ++
 src/infiniband.h  |  10 ++
 src/load.h        |  10 ++
 src/mojitos.c     | 143 +++++++++--------
 src/network.h     |  10 ++
 src/optparse.h    | 389 ++++++++++++++++++++++++++++++++++++++++++++++
 src/rapl.h        |  10 ++
 src/temperature.h |  10 ++
 11 files changed, 606 insertions(+), 76 deletions(-)
 create mode 100755 configure.sh
 create mode 100644 src/optparse.h

diff --git a/.gitignore b/.gitignore
index f5893ce..16bccfb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 *.o
 src/counters_option.h
+src/captors.h
 bin
 obj
diff --git a/configure.sh b/configure.sh
new file mode 100755
index 0000000..746f129
--- /dev/null
+++ b/configure.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+try() { "$@" || die "cannot $*"; }
+die() { yell "$*"; exit 111; }
+yell() { echo "$0: $*" >&2; }
+echo() { printf '%s\n' "$*"; }
+
+target=src/captors.h
+hdr_blacklist='counters_option|optparse|captors'
+
+usage() {
+	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>]\n' "$(basename "$0")" >&2
+	printf -- '-e | --exclude      :   exclude captor, can be called multiple times\n' >&2
+	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
+	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
+	exit 1
+}
+
+ls_captors() {
+	try cd src
+	ls *.h | grep -vE "($hdr_blacklist)" | sed 's/\.h$//'
+}
+
+gen_captors_h() {
+	captors=$(ls_captors)
+
+	[ -n "$captors" ] || return
+
+	# gen includes
+	for captor in $captors; do
+		printf '#include "%s.h"\n' "$captor"
+	done
+	printf '\n'
+
+	# gen `init_captors()`
+	printf 'void init_captors()\n{\n'
+	for captor in $captors; do
+		printf '    longopts[NB_MAX_OPTS + nb_defined_captors] = %s_opt;\n' "$captor"
+		printf '    captors[nb_defined_captors++] = %s;\n' "$captor"
+	done
+	printf '}\n'
+}
+
+while [ "$1" ]; do
+	case $1 in
+	--include|-i)
+		# no-op for now
+		:
+		;;
+	--exclude|-e)
+		shift; [ "$1" ] || usage
+		hdr_blacklist="${hdr_blacklist}|${1}"
+		;;
+	--list-captors|-l)
+		ls_captors
+		exit 0
+		;;
+	--help|-h)
+		usage
+		;;
+	esac
+	shift
+done
+
+gen_captors_h > "$target"
diff --git a/makefile b/makefile
index 488f39c..fe9035a 100644
--- a/makefile
+++ b/makefile
@@ -6,17 +6,17 @@ BIN_DIR = bin
 
 BIN = mojitos
 
-OBJ = $(addprefix $(OBJ_DIR)/,  \
-	counters.o \
-	rapl.o \
-	network.o \
-	load.o \
-	infiniband.o \
-	temperature.o \
-)
+OBJ =  \
+	$(OBJ_DIR)/counters.o \
+	$(OBJ_DIR)/rapl.o \
+	$(OBJ_DIR)/network.o \
+	$(OBJ_DIR)/load.o \
+	$(OBJ_DIR)/infiniband.o \
+	$(OBJ_DIR)/temperature.o
 
 CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
+CFLAGS = $(CPPFLAGS) -O3
 LDFLAGS = -lpowercap
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
@@ -45,11 +45,11 @@ $(OBJ_DIR):
 $(BIN_DIR):
 	mkdir -p $(BIN_DIR)
 
-debug: CFLAGS += -DDEBUG -g
+debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
 debug: all
 
 format:
-	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
+	$(ASTYLE) $(SRC_DIR)/*.[ch]
 
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
diff --git a/src/counters.h b/src/counters.h
index af20717..313feeb 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -23,4 +23,16 @@ unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
 
+struct optparse_long counters_opt = {"perf-list", 'p', OPTPARSE_REQUIRED};
+struct captor counters = {
+    .usage_arg = "<perf_list>",
+    .usage_msg = "performance counters\n"
+    "\tperf_list is a coma separated list of performance counters.\n"
+    "\tEx: instructions,cache_misses",
+    .init = init_counters,
+    .get = get_counters,
+    .clean = clean_counters,
+    .label = label_counters,
+};
+
 void show_all_counters();
diff --git a/src/infiniband.h b/src/infiniband.h
index 1f6aaf9..0f1ad11 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -20,3 +20,13 @@
 
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
+
+struct optparse_long infiniband_opt = {"monitor-infiniband", 'i', OPTPARSE_REQUIRED};
+struct captor infiniband = {
+    .usage_arg = "<infiniband_path>",
+    .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+    .init = init_infiniband,
+    .get = NULL,
+    .clean = NULL,
+    .label = label_infiniband,
+};
diff --git a/src/load.h b/src/load.h
index 299fa3e..366e448 100644
--- a/src/load.h
+++ b/src/load.h
@@ -22,3 +22,13 @@ unsigned int init_load(char *, void **);
 unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
+
+struct optparse_long load_opt = {"sysload", 'u', OPTPARSE_NONE};
+struct captor load = {
+    .usage_arg = NULL,
+    .usage_msg = "system load",
+    .init = init_load,
+    .get = get_load,
+    .clean = clean_load,
+    .label = label_load,
+};
diff --git a/src/mojitos.c b/src/mojitos.c
index cd8fcad..55af9f5 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -26,12 +26,8 @@
 #include <time.h>
 #include <unistd.h>
 
-#include "counters.h"
-#include "rapl.h"
-#include "infiniband.h"
-#include "load.h"
-#include "network.h"
-#include "temperature.h"
+#define NB_MAX_OPTS 10
+#define NB_MAX_CAPTORS 20
 
 #define OPTPARSE_IMPLEMENTATION
 #define OPTPARSE_API static
@@ -46,23 +42,62 @@
 		exit(code); 						 \
 	} while (0)
 
+typedef unsigned int (*initializer_t)(char *, void **);
+typedef void (*labeler_t)(char **, void *);
+typedef unsigned int (*getter_t)(uint64_t *, void *);
+typedef void (*cleaner_t)(void *);
+
+struct captor {
+    char *usage_arg;
+    char *usage_msg;
+    initializer_t init;
+    getter_t get;
+    cleaner_t clean;
+    labeler_t label;
+};
+
+struct captor captors[NB_MAX_CAPTORS];
+
+struct optparse_long longopts[NB_MAX_OPTS + NB_MAX_CAPTORS] = {
+    {"overhead-stats", 's', OPTPARSE_NONE},
+    {"list", 'l', OPTPARSE_NONE},
+    {"freq", 'f', OPTPARSE_REQUIRED},
+    {"time", 't', OPTPARSE_REQUIRED},
+    {"exec", 'e', OPTPARSE_REQUIRED},
+    {"logfile", 'o', OPTPARSE_REQUIRED},
+};
+
+int nb_defined_captors = 0;
+
+#include "captors.h"
 
 void usage(char **argv)
 {
-    printf("Usage : %s [-rlucs] [-t time] [-f freq] [-p perf_list] [-d network_device]\n"
-           "                    [-i infiniband_path] [-o logfile] [-e command arguments...]\n"
+    printf("Usage : %s [OPTIONS] [CAPTOR ...] [-o logfile] [-e cmd ...]\n"
+           "\nOPTIONS:\n"
+           "-t <time>\n"
+           "-f <freq>\n"
+           "-l\t\tlist the possible performance counters and quit\n"
+           "-s\t\tenable overhead statistics in nanoseconds\n"
            "if time==0 then loops infinitively\n"
            "if -e is present, time and freq are not used\n"
-           "-r activates RAPL\n"
-           "-p activates performance counters\n"
-           "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
-           "-l lists the possible performance counters and quits\n"
-           "-d activates network monitoring (if network_device is X, tries to detect it automatically)\n"
-           "-i activates infiniband monitoring (if infiniband_path is X, tries to detect it automatically)\n"
-           "-s activates statistics of overhead in nanoseconds\n"
-           "-u activates report of system load\n"
-           "-c activates report of processor temperature\n"
            , argv[0]);
+
+    if (nb_defined_captors == 0) {
+        // no captor to show
+        exit(EXIT_FAILURE);
+    }
+
+    printf("\nCAPTORS:\n");
+
+    for (int i = 0; i < nb_defined_captors; i++) {
+        printf("-%c", longopts[NB_MAX_OPTS + i].shortname);
+        if (captors[i].usage_arg != NULL) {
+            printf(" %s", captors[i].usage_arg);
+        }
+        printf("\n\t%s\n", captors[i].usage_msg);
+    }
+
     exit(EXIT_FAILURE);
 }
 
@@ -86,11 +121,6 @@ void flushexit()
     }
 }
 
-typedef unsigned int (initializer_t)(char *, void **);
-typedef void (labeler_t)(char **, void *);
-typedef unsigned int (*getter_t)(uint64_t *, void *);
-typedef void (*cleaner_t)(void *);
-
 unsigned int nb_sources = 0;
 void **states = NULL;
 getter_t *getter = NULL;
@@ -100,10 +130,14 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(initializer_t init, char *arg, labeler_t labeler,
-                getter_t get, cleaner_t clean)
+void add_source(struct captor *cpt, char *arg)
 {
     nb_sources++;
+    initializer_t init = cpt->init;
+    labeler_t labeler = cpt->label;
+    getter_t get = cpt->get;
+    cleaner_t clean = cpt->clean;
+
     states = realloc(states, nb_sources * sizeof(void *));
     int nb = init(arg, &states[nb_sources - 1]);
 
@@ -131,9 +165,10 @@ int main(int argc, char **argv)
     int delta = 0;
     int frequency = 1;
     char **application = NULL;
-
     int stat_mode = -1;
 
+    init_captors();
+
     if (argc == 1) {
         usage(argv);
     }
@@ -146,20 +181,6 @@ int main(int argc, char **argv)
     int opt;
     struct optparse options;
     options.permute = 0;
-    struct optparse_long longopts[] = {
-        {"monitor-infiniband", 'i', OPTPARSE_REQUIRED},
-        {"freq", 'f', OPTPARSE_REQUIRED},
-        {"time", 't', OPTPARSE_REQUIRED},
-        {"net-dev", 'd', OPTPARSE_REQUIRED},
-        {"exec", 'e', OPTPARSE_REQUIRED},
-        {"logfile", 'o', OPTPARSE_REQUIRED},
-        {"perf-list", 'p', OPTPARSE_REQUIRED},
-        {"cpu-temp", 'c', OPTPARSE_NONE},
-        {"rapl", 'r', OPTPARSE_NONE},
-        {"overhead-stats", 's', OPTPARSE_NONE},
-        {"sysload", 'u', OPTPARSE_NONE},
-        {"list", 'l', OPTPARSE_NONE},
-    };
 
     optparse_init(&options, argv);
     while ((opt = optparse_long(&options, longopts, NULL)) != -1 && application == NULL) {
@@ -175,12 +196,12 @@ int main(int argc, char **argv)
                 delta = 0;
             }
             break;
-        case 'd':
-            add_source(init_network, options.optarg, label_network, get_network, clean_network);
-            break;
-        case 'i':
-            add_source(init_infiniband, options.optarg, label_infiniband, get_network, clean_network);
+        case 's':
+            stat_mode = 0;
             break;
+        case 'l':
+            show_all_counters();
+            exit(EXIT_SUCCESS);
         case 'o':
             if ((output = fopen(options.optarg, "wb")) == NULL) {
                 perror("fopen");
@@ -191,27 +212,19 @@ int main(int argc, char **argv)
             application = options.argv;
             signal(17, sighandler);
             break;
-        case 'p':
-            add_source(init_counters, options.optarg, label_counters, get_counters, clean_counters);
-            break;
-        case 'r':
-            add_source(init_rapl, NULL, label_rapl, get_rapl, clean_rapl);
-            break;
-        case 'u':
-            add_source(init_load, NULL, label_load, get_load, clean_load);
-            break;
-        case 'c':
-            add_source(init_temperature, NULL, label_temperature, get_temperature, clean_temperature);
-            break;
-        case 's':
-            stat_mode = 0;
-            break;
-        case 'l':
-            show_all_counters();
-            exit(EXIT_SUCCESS);
-        default:
-            fprintf(stderr, "%s: %s\n", argv[0], options.errmsg);
-            usage(argv);
+        default: {
+            int ismatch = 0;
+            for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
+                if (opt == longopts[NB_MAX_OPTS + i].shortname) {
+                    ismatch = 1;
+                    add_source(&captors[i], options.optarg);
+                }
+            }
+            if (!ismatch) {
+                fprintf(stderr, "%s: %s\n", argv[0], options.errmsg);
+                usage(argv);
+            }
+        }
         }
     }
 
diff --git a/src/network.h b/src/network.h
index 3ba9ae5..3182587 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,3 +23,13 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
+struct optparse_long network_opt = {"net-dev", 'd', OPTPARSE_REQUIRED};
+struct captor network = {
+    .usage_arg = "<net_dev>",
+    .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+    .init = init_network,
+    .get = get_network,
+    .clean = clean_network,
+    .label = label_network,
+};
+
diff --git a/src/optparse.h b/src/optparse.h
new file mode 100644
index 0000000..04e60f6
--- /dev/null
+++ b/src/optparse.h
@@ -0,0 +1,389 @@
+/* Optparse --- portable, reentrant, embeddable, getopt-like option parser
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * To get the implementation, define OPTPARSE_IMPLEMENTATION.
+ * Optionally define OPTPARSE_API to control the API's visibility
+ * and/or linkage (static, __attribute__, __declspec).
+ *
+ * The POSIX getopt() option parser has three fatal flaws. These flaws
+ * are solved by Optparse.
+ *
+ * 1) Parser state is stored entirely in global variables, some of
+ * which are static and inaccessible. This means only one thread can
+ * use getopt(). It also means it's not possible to recursively parse
+ * nested sub-arguments while in the middle of argument parsing.
+ * Optparse fixes this by storing all state on a local struct.
+ *
+ * 2) The POSIX standard provides no way to properly reset the parser.
+ * This means for portable code that getopt() is only good for one
+ * run, over one argv with one option string. It also means subcommand
+ * options cannot be processed with getopt(). Most implementations
+ * provide a method to reset the parser, but it's not portable.
+ * Optparse provides an optparse_arg() function for stepping over
+ * subcommands and continuing parsing of options with another option
+ * string. The Optparse struct itself can be passed around to
+ * subcommand handlers for additional subcommand option parsing. A
+ * full reset can be achieved by with an additional optparse_init().
+ *
+ * 3) Error messages are printed to stderr. This can be disabled with
+ * opterr, but the messages themselves are still inaccessible.
+ * Optparse solves this by writing an error message in its errmsg
+ * field. The downside to Optparse is that this error message will
+ * always be in English rather than the current locale.
+ *
+ * Optparse should be familiar with anyone accustomed to getopt(), and
+ * it could be a nearly drop-in replacement. The option string is the
+ * same and the fields have the same names as the getopt() global
+ * variables (optarg, optind, optopt).
+ *
+ * Optparse also supports GNU-style long options with optparse_long().
+ * The interface is slightly different and simpler than getopt_long().
+ *
+ * By default, argv is permuted as it is parsed, moving non-option
+ * arguments to the end. This can be disabled by setting the `permute`
+ * field to 0 after initialization.
+ */
+#ifndef OPTPARSE_H
+#define OPTPARSE_H
+
+#ifndef OPTPARSE_API
+#  define OPTPARSE_API
+#endif
+
+struct optparse {
+    char **argv;
+    int permute;
+    int optind;
+    int optopt;
+    char *optarg;
+    char errmsg[64];
+    int subopt;
+};
+
+enum optparse_argtype {
+    OPTPARSE_NONE,
+    OPTPARSE_REQUIRED,
+    OPTPARSE_OPTIONAL
+};
+
+struct optparse_long {
+    const char *longname;
+    int shortname;
+    enum optparse_argtype argtype;
+};
+
+/**
+ * Initializes the parser state.
+ */
+OPTPARSE_API
+void optparse_init(struct optparse *options, char **argv);
+
+/**
+ * Read the next option in the argv array.
+ * @param optstring a getopt()-formatted option string.
+ * @return the next option character, -1 for done, or '?' for error
+ *
+ * Just like getopt(), a character followed by no colons means no
+ * argument. One colon means the option has a required argument. Two
+ * colons means the option takes an optional argument.
+ */
+OPTPARSE_API
+int optparse(struct optparse *options, const char *optstring);
+
+/**
+ * Handles GNU-style long options in addition to getopt() options.
+ * This works a lot like GNU's getopt_long(). The last option in
+ * longopts must be all zeros, marking the end of the array. The
+ * longindex argument may be NULL.
+ */
+OPTPARSE_API
+int optparse_long(struct optparse *options,
+                  const struct optparse_long *longopts,
+                  int *longindex);
+
+/**
+ * Used for stepping over non-option arguments.
+ * @return the next non-option argument, or NULL for no more arguments
+ *
+ * Argument parsing can continue with optparse() after using this
+ * function. That would be used to parse the options for the
+ * subcommand returned by optparse_arg(). This function allows you to
+ * ignore the value of optind.
+ */
+OPTPARSE_API
+char *optparse_arg(struct optparse *options);
+
+/* Implementation */
+#ifdef OPTPARSE_IMPLEMENTATION
+
+#define OPTPARSE_MSG_INVALID "invalid option"
+#define OPTPARSE_MSG_MISSING "option requires an argument"
+#define OPTPARSE_MSG_TOOMANY "option takes no arguments"
+
+static int optparse_error(struct optparse *options, const char *msg, const char *data)
+{
+    unsigned p = 0;
+    const char *sep = " -- '";
+    while (*msg)
+        options->errmsg[p++] = *msg++;
+    while (*sep)
+        options->errmsg[p++] = *sep++;
+    while (p < sizeof(options->errmsg) - 2 && *data)
+        options->errmsg[p++] = *data++;
+    options->errmsg[p++] = '\'';
+    options->errmsg[p++] = '\0';
+    return '?';
+}
+
+OPTPARSE_API
+void optparse_init(struct optparse *options, char **argv)
+{
+    options->argv = argv;
+    options->permute = 1;
+    options->optind = argv[0] != 0;
+    options->subopt = 0;
+    options->optarg = 0;
+    options->errmsg[0] = '\0';
+}
+
+static int optparse_is_dashdash(const char *arg)
+{
+    return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] == '\0';
+}
+
+static int optparse_is_shortopt(const char *arg)
+{
+    return arg != 0 && arg[0] == '-' && arg[1] != '-' && arg[1] != '\0';
+}
+
+static int optparse_is_longopt(const char *arg)
+{
+    return arg != 0 && arg[0] == '-' && arg[1] == '-' && arg[2] != '\0';
+}
+
+static void optparse_permute(struct optparse *options, int index)
+{
+    char *nonoption = options->argv[index];
+    int i;
+    for (i = index; i < options->optind - 1; i++)
+        options->argv[i] = options->argv[i + 1];
+    options->argv[options->optind - 1] = nonoption;
+}
+
+static int optparse_argtype(const char *optstring, char c)
+{
+    int count = OPTPARSE_NONE;
+    if (c == ':')
+        return -1;
+    for (; *optstring && c != *optstring; optstring++);
+    if (!*optstring)
+        return -1;
+    if (optstring[1] == ':')
+        count += optstring[2] == ':' ? 2 : 1;
+    return count;
+}
+
+OPTPARSE_API
+int optparse(struct optparse *options, const char *optstring)
+{
+    int type;
+    char *next;
+    char *option = options->argv[options->optind];
+    options->errmsg[0] = '\0';
+    options->optopt = 0;
+    options->optarg = 0;
+    if (option == 0) {
+        return -1;
+    } else if (optparse_is_dashdash(option)) {
+        options->optind++; /* consume "--" */
+        return -1;
+    } else if (!optparse_is_shortopt(option)) {
+        if (options->permute) {
+            int index = options->optind++;
+            int r = optparse(options, optstring);
+            optparse_permute(options, index);
+            options->optind--;
+            return r;
+        } else {
+            return -1;
+        }
+    }
+    option += options->subopt + 1;
+    options->optopt = option[0];
+    type = optparse_argtype(optstring, option[0]);
+    next = options->argv[options->optind + 1];
+    switch (type) {
+    case -1: {
+        char str[2] = {0, 0};
+        str[0] = option[0];
+        options->optind++;
+        return optparse_error(options, OPTPARSE_MSG_INVALID, str);
+    }
+    case OPTPARSE_NONE:
+        if (option[1]) {
+            options->subopt++;
+        } else {
+            options->subopt = 0;
+            options->optind++;
+        }
+        return option[0];
+    case OPTPARSE_REQUIRED:
+        options->subopt = 0;
+        options->optind++;
+        if (option[1]) {
+            options->optarg = option + 1;
+        } else if (next != 0) {
+            options->optarg = next;
+            options->optind++;
+        } else {
+            char str[2] = {0, 0};
+            str[0] = option[0];
+            options->optarg = 0;
+            return optparse_error(options, OPTPARSE_MSG_MISSING, str);
+        }
+        return option[0];
+    case OPTPARSE_OPTIONAL:
+        options->subopt = 0;
+        options->optind++;
+        if (option[1])
+            options->optarg = option + 1;
+        else
+            options->optarg = 0;
+        return option[0];
+    }
+    return 0;
+}
+
+OPTPARSE_API
+char *optparse_arg(struct optparse *options)
+{
+    char *option = options->argv[options->optind];
+    options->subopt = 0;
+    if (option != 0)
+        options->optind++;
+    return option;
+}
+
+static int optparse_longopts_end(const struct optparse_long *longopts, int i)
+{
+    return !longopts[i].longname && !longopts[i].shortname;
+}
+
+static void optparse_from_long(const struct optparse_long *longopts, char *optstring)
+{
+    char *p = optstring;
+    int i;
+    for (i = 0; !optparse_longopts_end(longopts, i); i++) {
+        if (longopts[i].shortname && longopts[i].shortname < 127) {
+            int a;
+            *p++ = longopts[i].shortname;
+            for (a = 0; a < (int)longopts[i].argtype; a++)
+                *p++ = ':';
+        }
+    }
+    *p = '\0';
+}
+
+/* Unlike strcmp(), handles options containing "=". */
+static int optparse_longopts_match(const char *longname, const char *option)
+{
+    const char *a = option, *n = longname;
+    if (longname == 0)
+        return 0;
+    for (; *a && *n && *a != '='; a++, n++)
+        if (*a != *n)
+            return 0;
+    return *n == '\0' && (*a == '\0' || *a == '=');
+}
+
+/* Return the part after "=", or NULL. */
+static char *optparse_longopts_arg(char *option)
+{
+    for (; *option && *option != '='; option++);
+    if (*option == '=')
+        return option + 1;
+    else
+        return 0;
+}
+
+static int optparse_long_fallback(struct optparse *options,
+                                  const struct optparse_long *longopts,
+                                  int *longindex)
+{
+    int result;
+    char optstring[96 * 3 + 1]; /* 96 ASCII printable characters */
+    optparse_from_long(longopts, optstring);
+    result = optparse(options, optstring);
+    if (longindex != 0) {
+        *longindex = -1;
+        if (result != -1) {
+            int i;
+            for (i = 0; !optparse_longopts_end(longopts, i); i++)
+                if (longopts[i].shortname == options->optopt)
+                    *longindex = i;
+        }
+    }
+    return result;
+}
+
+OPTPARSE_API
+int optparse_long(struct optparse *options,
+                  const struct optparse_long *longopts,
+                  int *longindex)
+{
+    int i;
+    char *option = options->argv[options->optind];
+    if (option == 0) {
+        return -1;
+    } else if (optparse_is_dashdash(option)) {
+        options->optind++; /* consume "--" */
+        return -1;
+    } else if (optparse_is_shortopt(option)) {
+        return optparse_long_fallback(options, longopts, longindex);
+    } else if (!optparse_is_longopt(option)) {
+        if (options->permute) {
+            int index = options->optind++;
+            int r = optparse_long(options, longopts, longindex);
+            optparse_permute(options, index);
+            options->optind--;
+            return r;
+        } else {
+            return -1;
+        }
+    }
+
+    /* Parse as long option. */
+    options->errmsg[0] = '\0';
+    options->optopt = 0;
+    options->optarg = 0;
+    option += 2; /* skip "--" */
+    options->optind++;
+    for (i = 0; !optparse_longopts_end(longopts, i); i++) {
+        const char *name = longopts[i].longname;
+        if (optparse_longopts_match(name, option)) {
+            char *arg;
+            if (longindex)
+                *longindex = i;
+            options->optopt = longopts[i].shortname;
+            arg = optparse_longopts_arg(option);
+            if (longopts[i].argtype == OPTPARSE_NONE && arg != 0) {
+                return optparse_error(options, OPTPARSE_MSG_TOOMANY, name);
+            }
+            if (arg != 0) {
+                options->optarg = arg;
+            } else if (longopts[i].argtype == OPTPARSE_REQUIRED) {
+                options->optarg = options->argv[options->optind];
+                if (options->optarg == 0)
+                    return optparse_error(options, OPTPARSE_MSG_MISSING, name);
+                else
+                    options->optind++;
+            }
+            return options->optopt;
+        }
+    }
+    return optparse_error(options, OPTPARSE_MSG_INVALID, option);
+}
+
+#endif /* OPTPARSE_IMPLEMENTATION */
+#endif /* OPTPARSE_H */
diff --git a/src/rapl.h b/src/rapl.h
index ddce4cc..b8dc9a2 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,3 +23,13 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
+struct optparse_long rapl_opt = {"rapl", 'r', OPTPARSE_NONE};
+struct captor rapl = {
+    .usage_arg = NULL,
+    .usage_msg = "RAPL",
+    .init = init_rapl,
+    .get = get_rapl,
+    .clean = clean_rapl,
+    .label = label_rapl,
+};
+
diff --git a/src/temperature.h b/src/temperature.h
index e49e416..5e8046e 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -22,3 +22,13 @@ unsigned int init_temperature(char *, void **);
 unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
+
+struct optparse_long temperature_opt = {"cpu-temp", 'c', OPTPARSE_NONE};
+struct captor temperature = {
+    .usage_arg = NULL,
+    .usage_msg = "processor temperature",
+    .init = init_temperature,
+    .get = get_temperature,
+    .clean = clean_temperature,
+    .label = label_temperature,
+};
-- 
GitLab


From e46c8918d197e361cb02453280eb5dbaf33d0e64 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 18 Jan 2023 09:57:04 +0000
Subject: [PATCH 033/229] remove Werror in debug mode

---
 makefile | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/makefile b/makefile
index fe9035a..7024207 100644
--- a/makefile
+++ b/makefile
@@ -15,8 +15,8 @@ OBJ =  \
 	$(OBJ_DIR)/temperature.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
-CFLAGS = $(CPPFLAGS) -O3
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
+CFLAGS = $(CPPFLAGS) -O3 -Werror
 LDFLAGS = -lpowercap
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
-- 
GitLab


From bd90c66a14e041843d0ebdd8d265b48a994f69b1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 21 Jan 2023 12:53:44 +0000
Subject: [PATCH 034/229] fix: dos2unix

---
 src/counters.h         |  52 ++++++++---------
 src/counters_option.py | 124 ++++++++++++++++++++---------------------
 src/infiniband.h       |  44 +++++++--------
 src/load.h             |  48 ++++++++--------
 src/network.h          |  50 ++++++++---------
 src/temperature.h      |  48 ++++++++--------
 src/util.h             |   8 +--
 7 files changed, 187 insertions(+), 187 deletions(-)

diff --git a/src/counters.h b/src/counters.h
index bd2d0a5..af20717 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,26 +1,26 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_counters(char *, void **);
-unsigned int get_counters(uint64_t *results, void *);
-void clean_counters(void *);
-void label_counters(char **labels, void *);
-
-void show_all_counters();
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_counters(char *, void **);
+unsigned int get_counters(uint64_t *results, void *);
+void clean_counters(void *);
+void label_counters(char **labels, void *);
+
+void show_all_counters();
diff --git a/src/counters_option.py b/src/counters_option.py
index d853e41..877a33a 100755
--- a/src/counters_option.py
+++ b/src/counters_option.py
@@ -1,62 +1,62 @@
-#! /usr/bin/python3
-
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-linux_include = '/usr/include/linux/perf_event.h'
-
-string = """#include <linux/perf_event.h>
-
-typedef struct counter_option {
-  char *name;
-  __u32 perf_type;
-  __u64 perf_key;
-} counter_option;
-
-static counter_option perf_static_info[] = {"""
-print(string)
-
-nb = 0
-
-black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
-              'cache_l1i', 'cache_op_write', 'cache_result_miss']
-
-with open(linux_include, 'r') as infile:
-    mode = ''
-    for line in infile:
-        if 'perf_hw_id' in line:
-            mode = 'PERF_TYPE_HARDWARE'
-        elif 'perf_hw_cache_' in line:
-            mode = 'PERF_TYPE_HW_CACHE'
-        elif 'perf_sw_id' in line:
-            mode = 'PERF_TYPE_SOFTWARE'
-        elif 'PERF_COUNT_' in line and '=' in line:
-            perf_name = line.split()[0]
-            short_perf = perf_name[14:].lower()
-            if short_perf in black_list:
-                continue
-            if mode == 'PERF_TYPE_HW_CACHE':
-                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
-                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
-                    for result_id, result_id_str in enumerate(['a', 'm']):
-                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
-
-                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
-                            short_perf, op_id_str, result_id_str,
-                            mode,
-                            perf_name,
-                            op_id_names[op_id],
-                            result_id_names[result_id])
-                                                                                     
-                        print(res)
-                        nb += 1
-
-            else:
-                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
-                print(res)
-                nb += 1
-
-
-print('};')
-
-print('static unsigned int nb_counter_option =',nb,';')
+#! /usr/bin/python3
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+linux_include = '/usr/include/linux/perf_event.h'
+
+string = """#include <linux/perf_event.h>
+
+typedef struct counter_option {
+  char *name;
+  __u32 perf_type;
+  __u64 perf_key;
+} counter_option;
+
+static counter_option perf_static_info[] = {"""
+print(string)
+
+nb = 0
+
+black_list = ['stalled_cycles_frontend','stalled_cycles_backend',
+              'cache_l1i', 'cache_op_write', 'cache_result_miss']
+
+with open(linux_include, 'r') as infile:
+    mode = ''
+    for line in infile:
+        if 'perf_hw_id' in line:
+            mode = 'PERF_TYPE_HARDWARE'
+        elif 'perf_hw_cache_' in line:
+            mode = 'PERF_TYPE_HW_CACHE'
+        elif 'perf_sw_id' in line:
+            mode = 'PERF_TYPE_SOFTWARE'
+        elif 'PERF_COUNT_' in line and '=' in line:
+            perf_name = line.split()[0]
+            short_perf = perf_name[14:].lower()
+            if short_perf in black_list:
+                continue
+            if mode == 'PERF_TYPE_HW_CACHE':
+                for op_id, op_id_str in enumerate(['r', 'w', 'p']):
+                    op_id_names = ['PERF_COUNT_HW_CACHE_OP_READ', 'PERF_COUNT_HW_CACHE_OP_WRITE', 'PERF_COUNT_HW_CACHE_OP_PREFETCH']
+                    for result_id, result_id_str in enumerate(['a', 'm']):
+                        result_id_names = ['PERF_COUNT_HW_CACHE_RESULT_ACCESS', 'PERF_COUNT_HW_CACHE_RESULT_MISS']
+
+                        res = '{ .name = "%s_%s_%s", .perf_type = %s, .perf_key = %s | (%s >> 8) | (%s >> 16) },' % (
+                            short_perf, op_id_str, result_id_str,
+                            mode,
+                            perf_name,
+                            op_id_names[op_id],
+                            result_id_names[result_id])
+                                                                                     
+                        print(res)
+                        nb += 1
+
+            else:
+                res = '{ .name = "'+short_perf+'", .perf_type = '+mode+', .perf_key = '+perf_name+'},'
+                print(res)
+                nb += 1
+
+
+print('};')
+
+print('static unsigned int nb_counter_option =',nb,';')
diff --git a/src/infiniband.h b/src/infiniband.h
index 4234964..1f6aaf9 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -1,22 +1,22 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_infiniband(char *infi_path, void **ptr);
-void label_infiniband(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_infiniband(char *infi_path, void **ptr);
+void label_infiniband(char **labels, void *);
diff --git a/src/load.h b/src/load.h
index 78c1b40..299fa3e 100644
--- a/src/load.h
+++ b/src/load.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_load(char *, void **);
-unsigned int get_load(uint64_t *results, void *);
-void clean_load(void *);
-void label_load(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_load(char *, void **);
+unsigned int get_load(uint64_t *results, void *);
+void clean_load(void *);
+void label_load(char **labels, void *);
diff --git a/src/network.h b/src/network.h
index b770560..3ba9ae5 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,25 +1,25 @@
-/*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_network(char *, void **);
-unsigned int get_network(uint64_t *results, void *);
-void clean_network(void *);
-void label_network(char **labels, void *);
-
+/*******************************************************
+ Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_network(char *, void **);
+unsigned int get_network(uint64_t *results, void *);
+void clean_network(void *);
+void label_network(char **labels, void *);
+
diff --git a/src/temperature.h b/src/temperature.h
index ac8e34b..e49e416 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -1,24 +1,24 @@
-/*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
-
-    This file is part of Mojitos.
-
-    Mojitos is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    Mojitos is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
-
- *******************************************************/
-
-unsigned int init_temperature(char *, void **);
-unsigned int get_temperature(uint64_t *results, void *);
-void clean_temperature(void *);
-void label_temperature(char **labels, void *);
+/*******************************************************
+ Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_temperature(char *, void **);
+unsigned int get_temperature(uint64_t *results, void *);
+void clean_temperature(void *);
+void label_temperature(char **labels, void *);
diff --git a/src/util.h b/src/util.h
index 83129d8..9a4067d 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,5 +1,5 @@
-#pragma once
-
-#include <stdint.h>
-
+#pragma once
+
+#include <stdint.h>
+
 inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
\ No newline at end of file
-- 
GitLab


From 652c34e2124544136be39c1bcc2f0940ef37cc41 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 21 Jan 2023 13:02:50 +0000
Subject: [PATCH 035/229] fix: std once style

---
 src/util.h | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/util.h b/src/util.h
index 9a4067d..1fff9af 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,5 +1,10 @@
-#pragma once
+#ifndef _UTIL_H
+#define _UTIL_H
+
+//#warning "TODO: Add licence"
 
 #include <stdint.h>
 
-inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
\ No newline at end of file
+inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
+
+#endif
-- 
GitLab


From ac422f8cf06164f6ad861863e153ddfd13975597 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 21 Jan 2023 13:11:28 +0000
Subject: [PATCH 036/229] fix: Usage mojitos.c -R was deleted.

---
 src/mojitos.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/mojitos.c b/src/mojitos.c
index b6c057f..ccde606 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -50,7 +50,6 @@ void usage(char **argv)
            "if time==0 then loops infinitively\n"
            "if -e is present, time and freq are not used\n"
            "-r activates RAPL\n"
-           "-R activates the file version of RAPL\n"
            "-p activates performance counters\n"
            "   perf_list is coma separated list of performance counters without space. Ex: instructions,cache_misses\n"
            "-l lists the possible performance counters and quits\n"
-- 
GitLab


From 6e6aa01c6a4af52722905c6e7237f96027981114 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 21 Jan 2023 16:26:44 +0000
Subject: [PATCH 037/229] test reader

---
 src/info_reader.c |  73 +++++++++++++++++++++++++++++
 src/info_reader.h | 114 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 187 insertions(+)
 create mode 100644 src/info_reader.c
 create mode 100644 src/info_reader.h

diff --git a/src/info_reader.c b/src/info_reader.c
new file mode 100644
index 0000000..d33654b
--- /dev/null
+++ b/src/info_reader.c
@@ -0,0 +1,73 @@
+#include "info_reader.h"
+
+#define MAX_PROCS 128
+
+typedef struct {
+  int processor;
+  char *vendor_id;
+  int family;
+  int core_id;
+  int physical_id;
+  char *model_name;
+} Cpu;
+
+int int_allocator(char *s) {
+  int value = atoi(s);
+  return value;
+}
+
+char *string_allocator(char *s) {
+  char *value = malloc(strlen(s) + 1);
+  strcpy(value, s);
+  return value;
+}
+
+void set_processor(Cpu *cpu, int data) { cpu->processor = (int)data; }
+
+void set_vendor_id(Cpu *cpu, char *data) { cpu->vendor_id = data; }
+
+void set_family(Cpu *cpu, int data) { cpu->family = (int)data; }
+
+void set_core_id(Cpu *cpu, int data) { cpu->core_id = (int)data; }
+
+void set_physical_id(Cpu *cpu, int data) { cpu->physical_id = (int)data; }
+
+void set_model_name(Cpu *cpu, char *data) { cpu->model_name = data; }
+
+int main(int argc, char const *argv[]) {
+  Cpu cpus[MAX_PROCS];
+
+  KeyFinder keys[] = {
+      {"processor", (CopyAllocator *)int_allocator, (Setter *)set_processor},
+      {"vendor_id", (CopyAllocator *)string_allocator, (Setter *)set_vendor_id},
+      {"cpu family", (CopyAllocator *)int_allocator, (Setter *)set_family},
+      {"core id", (CopyAllocator *)int_allocator, (Setter *)set_core_id},
+      {"physical id", (CopyAllocator *)int_allocator,
+       (Setter *)set_physical_id},
+      {"model name", (CopyAllocator *)string_allocator,
+       (Setter *)set_model_name}};
+
+  Parser parser = {.storage = (void **)cpus,
+                   .capacity = MAX_PROCS,
+                   .storage_struct_size = sizeof(Cpu),
+                   .keys = keys,
+                   .nb_keys = 6,
+                   .file = fopen("/proc/cpuinfo", "r")};
+
+  parse(&parser);
+
+  for (unsigned int i = 0; i < parser.nb_stored; ++i) {
+    printf("========== PROC[%d] ==========\n", i);
+    printf("Processor: %d\n", cpus[i].processor);
+    printf("Vendor ID: %s\n", cpus[i].vendor_id);
+    printf("Family: %d\n", cpus[i].family);
+    printf("Core ID: %d\n", cpus[i].core_id);
+    printf("Physical ID: %d\n", cpus[i].physical_id);
+    printf("Model Name: %s\n", cpus[i].model_name);
+    printf("==============================\n");
+    free(cpus[i].vendor_id);
+    free(cpus[i].model_name);
+  }
+  return 0;
+}
+
diff --git a/src/info_reader.h b/src/info_reader.h
new file mode 100644
index 0000000..e0f230b
--- /dev/null
+++ b/src/info_reader.h
@@ -0,0 +1,114 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _INFO_READER_H
+#define _INFO_READER_H
+
+typedef struct Parser Parser;
+typedef struct KeyFinder KeyFinder;
+
+// Transforme the string in the expected format
+typedef void *(CopyAllocator)(char *string);
+// Set the value into the memory
+typedef void(Setter)(void *storage, void *value);
+
+struct KeyFinder {
+  char *key;
+  // Functions
+  CopyAllocator *copy;
+  Setter *set;
+};
+
+struct Parser {
+  void *storage;
+  unsigned int nb_stored;
+  unsigned int capacity;
+  size_t storage_struct_size;
+
+  KeyFinder *keys;
+  unsigned int nb_keys;
+
+  FILE *file;
+};
+
+char *get_string_value(char *line) {
+  char *start = line;
+  while (*start != '\0') {
+    if (*start == ':' && *(start + 1) == ' ') {
+      return (start + 2);
+    }
+    ++start;
+  }
+  return NULL;
+}
+
+void replace_first(char *string, char find, char replace) {
+  char *found = strchr(string, find);
+  if (found) {
+    *found = replace;
+  }
+}
+
+unsigned int start_with(const char *prefix, const char *string) {
+  size_t prefix_len = strlen(prefix);
+  size_t string_len = strlen(string);
+  return string_len < prefix_len ? false
+                                 : memcmp(prefix, string, prefix_len) == 0;
+}
+
+int match(Parser *parser, char *line) {
+  for (size_t i = 0; i < parser->nb_keys; i++) {
+    KeyFinder *key_finder = &parser->keys[i];
+
+    if (start_with(key_finder->key, line)) {
+      char *string_value = get_string_value(line);
+      if (get_string_value == NULL) {
+        fprintf(stderr, "Error : invalid format for line : %s\n", line);
+        exit(EXIT_FAILURE);
+      }
+      replace_first(string_value, '\n', '\0');
+      void *value = key_finder->copy(string_value);
+
+      key_finder->set(
+          (parser->storage + (parser->storage_struct_size * parser->nb_stored)),
+          value);
+
+      return 1;
+    }
+  }
+  return 0;
+}
+
+void parse(Parser *parser) {
+  char *line = NULL;
+  size_t len = 0;
+  ssize_t read;
+
+  unsigned int key_assigned = 0;
+
+  while ((read = getline(&line, &len, parser->file)) != -1) {
+    if (key_assigned == parser->nb_keys && read > 1) {
+      continue;
+    }
+    if (read == 1) {
+      parser->nb_stored++;
+      if (parser->nb_stored == parser->capacity) {
+        fprintf(stderr, "Error : too much cpus to read.\n");
+        exit(EXIT_FAILURE);
+      }
+
+      key_assigned = 0;
+    }
+    key_assigned += match(parser, line);
+  }
+
+  if (key_assigned > 0) {
+    parser->nb_stored++;
+  }
+
+  free(line);
+}
+
+#endif
-- 
GitLab


From 597829bb05779d7153fe1a102b2c1a5a055529f8 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 08:24:24 +0000
Subject: [PATCH 038/229] working library

---
 src/info_reader.c |  88 ++++----
 src/info_reader.h | 536 ++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 518 insertions(+), 106 deletions(-)

diff --git a/src/info_reader.c b/src/info_reader.c
index d33654b..110d060 100644
--- a/src/info_reader.c
+++ b/src/info_reader.c
@@ -1,53 +1,68 @@
 #include "info_reader.h"
 
-#define MAX_PROCS 128
+#ifdef DEBUG										
+	#warning "PTR_TO_TPTR hide a cast warning"aa	
+#endif												
 
+#define MAX_PROCS 128
 typedef struct {
-  int processor;
+  size_t processor;
   char *vendor_id;
-  int family;
-  int core_id;
-  int physical_id;
+  size_t family;
+  size_t core_id;
+  size_t physical_id;
   char *model_name;
 } Cpu;
 
-int int_allocator(char *s) {
-  int value = atoi(s);
-  return value;
+GenericPointer int_allocator(char *s) {
+  size_t value = atoi(s);
+  return (GenericPointer) value;
 }
 
-char *string_allocator(char *s) {
+GenericPointer string_allocator(char *s) {
   char *value = malloc(strlen(s) + 1);
   strcpy(value, s);
-  return value;
+  return (GenericPointer) value;
 }
 
-void set_processor(Cpu *cpu, int data) { cpu->processor = (int)data; }
-
-void set_vendor_id(Cpu *cpu, char *data) { cpu->vendor_id = data; }
-
-void set_family(Cpu *cpu, int data) { cpu->family = (int)data; }
-
-void set_core_id(Cpu *cpu, int data) { cpu->core_id = (int)data; }
-
-void set_physical_id(Cpu *cpu, int data) { cpu->physical_id = (int)data; }
-
-void set_model_name(Cpu *cpu, char *data) { cpu->model_name = data; }
+void set_processor(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->processor = data; 
+}
+void set_vendor_id(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->vendor_id = (char*) data; 
+}
+void set_family(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->family = data; 
+}
+void set_core_id(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->core_id = data; 
+}
+void set_physical_id(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->physical_id = data; 
+}
+void set_model_name(GenericPointer storage, GenericPointer data) {
+	Cpu* cpu = (Cpu*) storage;
+	cpu->model_name = (char*) data; 
+}
 
 int main(int argc, char const *argv[]) {
   Cpu cpus[MAX_PROCS];
-
   KeyFinder keys[] = {
-      {"processor", (CopyAllocator *)int_allocator, (Setter *)set_processor},
-      {"vendor_id", (CopyAllocator *)string_allocator, (Setter *)set_vendor_id},
-      {"cpu family", (CopyAllocator *)int_allocator, (Setter *)set_family},
-      {"core id", (CopyAllocator *)int_allocator, (Setter *)set_core_id},
-      {"physical id", (CopyAllocator *)int_allocator,
-       (Setter *)set_physical_id},
-      {"model name", (CopyAllocator *)string_allocator,
-       (Setter *)set_model_name}};
-
-  Parser parser = {.storage = (void **)cpus,
+	  {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
+	  {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
+	  {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
+	  {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
+	  {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
+	  {"model name", ": ", (CopyAllocator *) string_allocator,
+		  (Setter *)set_model_name}
+  };
+
+  Parser parser = {.storage = (GenericPointer) cpus,
                    .capacity = MAX_PROCS,
                    .storage_struct_size = sizeof(Cpu),
                    .keys = keys,
@@ -58,16 +73,17 @@ int main(int argc, char const *argv[]) {
 
   for (unsigned int i = 0; i < parser.nb_stored; ++i) {
     printf("========== PROC[%d] ==========\n", i);
-    printf("Processor: %d\n", cpus[i].processor);
+    printf("Processor: %ld\n", cpus[i].processor);
     printf("Vendor ID: %s\n", cpus[i].vendor_id);
-    printf("Family: %d\n", cpus[i].family);
-    printf("Core ID: %d\n", cpus[i].core_id);
-    printf("Physical ID: %d\n", cpus[i].physical_id);
+    printf("Family: %ld\n", cpus[i].family);
+    printf("Core ID: %ld\n", cpus[i].core_id);
+    printf("Physical ID: %ld\n", cpus[i].physical_id);
     printf("Model Name: %s\n", cpus[i].model_name);
     printf("==============================\n");
     free(cpus[i].vendor_id);
     free(cpus[i].model_name);
   }
+
   return 0;
 }
 
diff --git a/src/info_reader.h b/src/info_reader.h
index e0f230b..030ea52 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -1,28 +1,104 @@
+#include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-
-#ifndef _INFO_READER_H
-#define _INFO_READER_H
 
+/**
+ * @struct Parser
+ * @brief The parser struct
+ * The struct containing all the necessary informations and functions to parse a file
+ *
+ * @var storage : void* : pointer to the storage where the parsed data will be stored
+ * @var nb_stored : unsigned int : the number of struct stored
+ * @var capacity : unsigned int : the maximum number of struct that can be stored
+ * @var storage_struct_size : size_t : the size of the struct stored in the storage
+ * @var keys : KeyFinder* : pointer to an array of KeyFinder containing the possible keys
+ * @var nb_keys : unsigned int : number of key finders
+ * @var file : FILE* : pointer to the file that will be parsed
+*/
 typedef struct Parser Parser;
+
+/**
+ * @struct KeyFinder
+ * @brief The key finder struct
+ * The struct containing all the necessary informations and functions to find a key in a line of text
+ * 
+ * @var key : char* : the key to be found
+ * @var delimiter : char* : the delimiter between the key and the value
+ * @var copy : CopyAllocator*: the function to use to make a copy of the value
+ * @var set : Setter*: the function to use to store the value in the storage
+*/
 typedef struct KeyFinder KeyFinder;
 
-// Transforme the string in the expected format
-typedef void *(CopyAllocator)(char *string);
-// Set the value into the memory
-typedef void(Setter)(void *storage, void *value);
+/**
+ * @brief Split a string into a key and value based on a specified delimiter.
+ *
+ * The function takes a string and splits it into two parts: a key and a value.
+ * The parts are determined by a specified delimiter.
+ * The key and value are returned through output parameters.
+ * If the delimiter is not found in the input string, the key and value pointers
+ * will be set to NULL.
+ *
+ * @param[in] string The input string to be split, the string is modified.
+ * @param[in] delimiter The delimiter string.
+ * @param[out] key A pointer to a char pointer where the key will be stored.
+ * @param[out] value A pointer to a char pointer where the value will be stored.
+ * @return None.
+ */
+static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value);
+
+/**
+ * @brief Replace the first occurrence of a character in a string with another character.
+ *
+ * The function takes a string and two characters as input, and replaces the first
+ * occurrence of the first character in the string with the second character.
+ *
+ * @param[in,out] string The input string where the replacement should take place.
+ * @param[in] from The character to be replaced.
+ * @param[in] to The character to replace with.
+ * @return None.
+ */
+static void replace_first(char* string, char from, char to);
+
+/**
+ * @brief Check if a string starts with a prefix.
+ * 
+ * @param[in] prefix The prefix to check.
+ * @param[in] string The string to check.
+ * @return true The string starts with the prefix.
+ * @return false The string does not start with the prefix or one of the input pointers is NULL.
+ */
+static bool start_with(const char* prefix, const char* string);
+
+/**
+ * @brief Matches a line of text to a key in the parser's list of keys.
+ *
+ * @param parser Pointer to the Parser struct.
+ * @param line Line of text to match.
+ * @param key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
+ * @param raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
+ *
+ * @return Returns 1 if a key is matched, 0 otherwise.
+ */
+static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value);
+
+
+
+
+typedef size_t GenericPointer;
+typedef GenericPointer (CopyAllocator) (char *string);
+typedef void (Setter) (GenericPointer storage, GenericPointer value);
 
 struct KeyFinder {
   char *key;
-  // Functions
+  char *delimiter;
+
   CopyAllocator *copy;
   Setter *set;
 };
 
 struct Parser {
-  void *storage;
+  GenericPointer storage;
   unsigned int nb_stored;
   unsigned int capacity;
   size_t storage_struct_size;
@@ -33,82 +109,402 @@ struct Parser {
   FILE *file;
 };
 
-char *get_string_value(char *line) {
-  char *start = line;
-  while (*start != '\0') {
-    if (*start == ':' && *(start + 1) == ' ') {
-      return (start + 2);
+static void set_value(Parser *parser, KeyFinder *key_finder, char* raw_value) {
+	GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored);
+	GenericPointer value = key_finder->copy(raw_value);
+	key_finder->set(address, value);
+} 
+
+// static void storage_zero(Parser *parser) {
+// 	static const int zero = 0;
+// 	GenericPointer storage = parser->storage;
+// 	size_t capacity = parser->capacity;
+// 	size_t struct_size = parser->storage_struct_size;
+// 	memset(storage, zero, struct_size * capacity);
+// }
+
+static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value) {
+	for (unsigned int i = 0; i < parser->nb_keys; i++) {
+		KeyFinder *finder = &parser->keys[i];
+
+		if (start_with(finder->key, line)) {
+			char* value = NULL;
+			char* key = NULL;
+
+			split_on_delimiter(line, finder->delimiter, &key, &value);
+			if ( key == NULL || value == NULL) {
+				return 0;
+			}
+			*key_finder = finder;
+			*raw_value = value;
+			return 1;
+		}
+	}
+	return 0;
+}
+
+static unsigned int move_to_next(Parser *parser) {
+	parser->nb_stored += 1;
+	if (parser->nb_stored >= parser->capacity) {
+		return 0;
+	}
+	return 1;
+}
+
+static unsigned int parse(Parser *parser) {
+	char *line = NULL;
+	size_t len = 0;
+	ssize_t read;
+	unsigned int key_assigned = 0;
+
+	while ((read = getline(&line, &len, parser->file)) != -1) {
+		if (key_assigned == parser->nb_keys && read > 1) {
+			continue;
+		} else if (read == 1) {
+			if (!move_to_next(parser)) {
+				return 0;
+			}
+			key_assigned = 0;
+		} else {
+			KeyFinder *key_finder = NULL;
+			char *raw_value = NULL;
+			replace_first(line, '\n', '\0');
+			if (match(parser, line, &key_finder, &raw_value)) {
+				set_value(parser, key_finder, raw_value);
+				++key_assigned;
+			}
+		}
+	}
+	if (key_assigned > 0) {
+		parser->nb_stored++;
+	}
+	free(line);
+	return 1;
+}
+
+
+
+static void replace_first(char* string, char from, char to) {
+    for (int i = 0; string[i] != '\0'; i++) {
+        if (string[i] == from) {
+            string[i] = to;
+            break;
+        }
     }
-    ++start;
-  }
-  return NULL;
 }
 
-void replace_first(char *string, char find, char replace) {
-  char *found = strchr(string, find);
-  if (found) {
-    *found = replace;
-  }
+static void split_on_delimiter(char *string, const char* delimiter, char **key, char **value) {
+	*key = NULL;
+	*value = NULL;
+	size_t delimiter_len = strlen(delimiter);
+	char* start_delimiter = strstr(string, delimiter);
+	if (start_delimiter != NULL) {
+		*start_delimiter = '\0';
+		*key = string;
+		*value = start_delimiter + delimiter_len;
+	}
 }
 
-unsigned int start_with(const char *prefix, const char *string) {
-  size_t prefix_len = strlen(prefix);
-  size_t string_len = strlen(string);
-  return string_len < prefix_len ? false
-                                 : memcmp(prefix, string, prefix_len) == 0;
+static bool start_with(const char *prefix, const char *string) {
+	if (prefix == NULL || string == NULL) {
+		return false;
+	}
+
+	size_t prefix_len = strlen(prefix);
+	size_t string_len = strlen(string);
+
+	if (string_len < prefix_len) {
+		return false;
+	} else {
+		return  memcmp(prefix, string, prefix_len) == 0;
+	}
 }
 
-int match(Parser *parser, char *line) {
-  for (size_t i = 0; i < parser->nb_keys; i++) {
-    KeyFinder *key_finder = &parser->keys[i];
 
-    if (start_with(key_finder->key, line)) {
-      char *string_value = get_string_value(line);
-      if (get_string_value == NULL) {
-        fprintf(stderr, "Error : invalid format for line : %s\n", line);
-        exit(EXIT_FAILURE);
-      }
-      replace_first(string_value, '\n', '\0');
-      void *value = key_finder->copy(string_value);
+#ifdef __TESTING__
 
-      key_finder->set(
-          (parser->storage + (parser->storage_struct_size * parser->nb_stored)),
-          value);
+#define FMT_NULL(string) \
+	string = string ? string : "NULL"
 
-      return 1;
-    }
-  }
-  return 0;
+#define TEST_STR(result, expected) \
+	test_str(__FILE__, __LINE__, result, expected)
+
+#define TEST_BOOLEAN(result, expected) \
+	test_boolean(__FILE__, __LINE__, result, expected)
+
+#define TEST_PTR(result, expected) \
+	test_ptr(__FILE__, __LINE__, result, expected)
+
+typedef int (Comparator) (void*, void*);
+typedef char* (Formatter) (char*, void*);
+
+int string_compare(char* string1, char* string2) {
+	if (string1 == NULL && string2 == NULL) {
+		return 1;
+	} else if (string1 == NULL || string2 == NULL) {
+		return 0;
+	} else {
+		return (strcmp(string1, string2) == 0);
+	}
 }
 
-void parse(Parser *parser) {
-  char *line = NULL;
-  size_t len = 0;
-  ssize_t read;
+char* string_format(__attribute__((unused)) char* buffer, char* string) {
+	return FMT_NULL(string);
+}
 
-  unsigned int key_assigned = 0;
 
-  while ((read = getline(&line, &len, parser->file)) != -1) {
-    if (key_assigned == parser->nb_keys && read > 1) {
-      continue;
-    }
-    if (read == 1) {
-      parser->nb_stored++;
-      if (parser->nb_stored == parser->capacity) {
-        fprintf(stderr, "Error : too much cpus to read.\n");
-        exit(EXIT_FAILURE);
-      }
-
-      key_assigned = 0;
-    }
-    key_assigned += match(parser, line);
-  }
+int boolean_compare(bool* boolean1, bool* boolean2) {
+	return *boolean1 == *boolean2;
+}
+
+char* boolean_format(__attribute__((unused)) char* buffer, bool* boolean) {
+	return *boolean ? "True" : "False";
+}
+
+int ptr_compare(void* ptr1, void* ptr2) {
+	return ptr1 == ptr2;	
+}
 
-  if (key_assigned > 0) {
-    parser->nb_stored++;
-  }
+char* ptr_format(char* buffer, void* ptr) {
+	sprintf(buffer, "%p", ptr);
+	return buffer;
+}
+
+void test(char* file, int line, void* result, void* expected, Comparator* compare, Formatter* format){
+	static char buffer_result[1000];
+	static char buffer_expected[1000];
+	if (compare(result, expected) == 0){
+		printf("Test %s:%d failed: expected %s, got %s\n",
+				file,
+				line,
+				format(buffer_result, expected),
+				format(buffer_expected, result)
+			  );
+	} else {
+		printf("Test %s:%d passed\n", file, line);
+	}
+}
+
+void test_str(char* file, int line, char* result, char* expected) {
+	Comparator* compare = (Comparator*) string_compare;
+	Formatter* format = (Formatter*) string_format;
+
+	test(file, line, result, expected, compare, format);
+}
+
+void test_boolean(char* file, int line, bool* result, bool* expected) {
+	Comparator* compare = (Comparator*) boolean_compare;
+	Formatter* format = (Formatter*) boolean_format;
+
+	test(file, line, (void*) result, (void*) expected, compare, format);
+}
+
+void test_ptr(char* file, int line, void* result, void* expected) {
+	Comparator* compare = (Comparator*) ptr_compare;
+	Formatter* format = (Formatter*) ptr_format;
+
+	test(file, line, result, expected, compare, format);
+}
+
+void test_replace_first() {
+	printf("==== TEST replace_first() ====\n");
+	char test1[] = "This is my string";
+	replace_first(test1, 'i', 'I');
+	TEST_STR(test1, "ThIs is my string");
+
+	char test2[] = "This is my string";
+	replace_first(test2, 'x', 'X');
+	TEST_STR(test2, "This is my string");
+
+
+	char test3[] = "This is my string";
+	replace_first(test3, ' ', '_');
+	TEST_STR(test3, "This_is my string");
+}
+
+void test_split_on_delimiter() {
+	printf("==== TEST split_on_delimite() ====\n");
+	char test4[] = "key:value";
+	char* key;
+	char* value;
+	split_on_delimiter(test4, ":", &key, &value);
+	TEST_STR(key, "key");
+	TEST_STR(value, "value");
+
+	char test5[] = "key: value";
+	split_on_delimiter(test5, ":", &key, &value);
+	TEST_STR(key, "key");
+	TEST_STR(value, " value");
+
+	char test6[] = "key:value";
+	replace_first(test6, ':', ' ');
+	split_on_delimiter(test6, " ", &key, &value);
+	TEST_STR(key, "key");
+	TEST_STR(value, "value");
+
+	char test7[] = "";
+	split_on_delimiter(test7, ":", &key, &value);
+	TEST_STR(key, NULL);
+	TEST_STR(value, NULL);
+
+	char test9[] = "key:value:extra";
+	split_on_delimiter(test9, ":", &key, &value);
+	TEST_STR(key, "key");
+	TEST_STR(value, "value:extra");
+
+	char test10[] = "key: value :extra";
+	split_on_delimiter(test10, ":", &key, &value);
+	TEST_STR(key, "key");
+	TEST_STR(value, " value :extra");
+}
+
+void test_start_with() {
+	printf("==== TEST start_with() ====\n");
+	char* prefix = NULL;
+	char* string = NULL;
+	bool result = false;
+	bool _true = true;
+	bool _false = false;
+
+	prefix = "Hello";
+	string = "Hello World";
+	result = start_with(prefix, string);
+	TEST_BOOLEAN(&result, &_true);
+
+	prefix = "Goodbye";
+	string = "Hello World";
+	result = start_with(prefix, string);
+	TEST_BOOLEAN(&result, &_false);
+
+	prefix = "Hello World";
+	string = "Hello";
+	result = start_with(prefix, string);
+	TEST_BOOLEAN(&result, &_false);
+
+	prefix = "Hello";
+	string = "Hello";
+	result = start_with(prefix, string);
+	TEST_BOOLEAN(&result, &_true);
+
+	prefix = NULL;
+	string = "Hello World";
+	result = start_with(prefix, string);
+	TEST_BOOLEAN(&result, &_false);
+}
+
+#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
+	do { 											\
+		key_finder = (KeyFinder) {					\
+			key,									\
+			delimiter,								\
+			NULL,									\
+			NULL									\
+		}; 											\
+	} while (0);
+
+#define DUMB_PARSER(parser, keys, nb_keys)  \
+	do {									\
+		parser = (Parser) {					\
+			NULL,		   					\
+			0,			   					\
+			0,			   					\
+			0,  							\
+			keys,			   				\
+			nb_keys, 		   				\
+			NULL							\
+		};							   		\
+	} while (0);
+
+
+void test_match() {
+	printf("==== TEST match() ====\n");
+	// usefull variable :
+	bool _true = true;
+	bool _false = false;
+	KeyFinder keys[10];
+	char line[100];
+	Parser parser;
+	bool result;
+	KeyFinder* found_key_finder = NULL;
+	char* raw_value = NULL;
+	
+	// Test 1:
+	// -- Setup
+	DUMB_KEYFINDER(keys[0], "key", ": ");
+	DUMB_PARSER(parser, keys, 1);
+	strcpy(line, "key: value");
+	found_key_finder = NULL;
+	raw_value = NULL;
+	// -- Run
+	result = match(&parser, line, &found_key_finder, &raw_value);
+	// -- Verification
+	TEST_BOOLEAN(&result, &_true);
+	TEST_PTR(found_key_finder, &keys[0]);
+	TEST_STR(raw_value, "value"); 
+
+	// Test 2:
+	// -- Setup
+	DUMB_KEYFINDER(keys[0], "key", ": ");
+	DUMB_PARSER(parser, keys, 1)
+	strcpy(line, "not a key: value");
+	found_key_finder = NULL;
+	raw_value = NULL;
+	// -- Run
+	result = match(&parser, line, &found_key_finder, &raw_value);
+	// -- Verification
+	TEST_BOOLEAN(&result, &_false);
+	TEST_PTR(found_key_finder, NULL);
+	TEST_STR(raw_value, NULL); 
+
+	// Test 3:
+	// -- Setup
+	DUMB_KEYFINDER(keys[0],"key", ": ");
+	DUMB_PARSER(parser, keys, 1);
+	strcpy(line, "key:value");
+	found_key_finder = NULL;
+	raw_value = NULL;
+	// -- Run
+	result = match(&parser, line, &found_key_finder, &raw_value);
+	// -- Verification	
+	TEST_BOOLEAN(&result, &_false);
+	TEST_PTR(found_key_finder, NULL);
+	TEST_STR(raw_value, NULL); 
+
+	// Test 4:
+	// -- Setup
+	DUMB_KEYFINDER(keys[0], "key", ": ");
+	DUMB_KEYFINDER(keys[1], "second_key", ": ");
+	DUMB_PARSER(parser, keys, 2);
+	strcpy(line, "second_key: value");
+	found_key_finder = NULL;
+	raw_value = NULL;
+	// -- Run
+	result = match(&parser, line, &found_key_finder, &raw_value);
+	// -- Verification
+	TEST_BOOLEAN(&result, &_true);
+	TEST_PTR(found_key_finder, &keys[1]);
+	TEST_STR(raw_value, "value"); 
+
+	// Test 5:
+	// -- Setup
+	DUMB_KEYFINDER(keys[0], "key", ": ");
+	DUMB_PARSER(parser, keys, 1);
+	strcpy(line, "");
+	found_key_finder = NULL;
+	raw_value = NULL;
+	// -- Run
+	result = match(&parser, line, &found_key_finder, &raw_value);
+	TEST_BOOLEAN(&result, &_false);
+	TEST_PTR(found_key_finder, NULL);
+	TEST_STR(raw_value, NULL); 
+}
 
-  free(line);
+int main() {
+	test_replace_first();
+	test_split_on_delimiter();
+	test_start_with();
+	test_match();
+	return 0;
 }
 
 #endif
-- 
GitLab


From ad8b9217a2d9a275e9373a5cdf0ca65e4bb698b0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 08:38:51 +0000
Subject: [PATCH 039/229] format: dos2linux LICENSE

---
 LICENSE | 1348 +++++++++++++++++++++++++++----------------------------
 1 file changed, 674 insertions(+), 674 deletions(-)

diff --git a/LICENSE b/LICENSE
index 3877ae0..f288702 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,674 +1,674 @@
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The GNU General Public License is a free, copyleft license for
-software and other kinds of works.
-
-  The licenses for most software and other practical works are designed
-to take away your freedom to share and change the works.  By contrast,
-the GNU General Public License is intended to guarantee your freedom to
-share and change all versions of a program--to make sure it remains free
-software for all its users.  We, the Free Software Foundation, use the
-GNU General Public License for most of our software; it applies also to
-any other work released this way by its authors.  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-them if you wish), that you receive source code or can get it if you
-want it, that you can change the software or use pieces of it in new
-free programs, and that you know you can do these things.
-
-  To protect your rights, we need to prevent others from denying you
-these rights or asking you to surrender the rights.  Therefore, you have
-certain responsibilities if you distribute copies of the software, or if
-you modify it: responsibilities to respect the freedom of others.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must pass on to the recipients the same
-freedoms that you received.  You must make sure that they, too, receive
-or can get the source code.  And you must show them these terms so they
-know their rights.
-
-  Developers that use the GNU GPL protect your rights with two steps:
-(1) assert copyright on the software, and (2) offer you this License
-giving you legal permission to copy, distribute and/or modify it.
-
-  For the developers' and authors' protection, the GPL clearly explains
-that there is no warranty for this free software.  For both users' and
-authors' sake, the GPL requires that modified versions be marked as
-changed, so that their problems will not be attributed erroneously to
-authors of previous versions.
-
-  Some devices are designed to deny users access to install or run
-modified versions of the software inside them, although the manufacturer
-can do so.  This is fundamentally incompatible with the aim of
-protecting users' freedom to change the software.  The systematic
-pattern of such abuse occurs in the area of products for individuals to
-use, which is precisely where it is most unacceptable.  Therefore, we
-have designed this version of the GPL to prohibit the practice for those
-products.  If such problems arise substantially in other domains, we
-stand ready to extend this provision to those domains in future versions
-of the GPL, as needed to protect the freedom of users.
-
-  Finally, every program is threatened constantly by software patents.
-States should not allow patents to restrict development and use of
-software on general-purpose computers, but in those that do, we wish to
-avoid the special danger that patents applied to a free program could
-make it effectively proprietary.  To prevent this, the GPL assures that
-patents cannot be used to render the program non-free.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                       TERMS AND CONDITIONS
-
-  0. Definitions.
-
-  "This License" refers to version 3 of the GNU General Public License.
-
-  "Copyright" also means copyright-like laws that apply to other kinds of
-works, such as semiconductor masks.
-
-  "The Program" refers to any copyrightable work licensed under this
-License.  Each licensee is addressed as "you".  "Licensees" and
-"recipients" may be individuals or organizations.
-
-  To "modify" a work means to copy from or adapt all or part of the work
-in a fashion requiring copyright permission, other than the making of an
-exact copy.  The resulting work is called a "modified version" of the
-earlier work or a work "based on" the earlier work.
-
-  A "covered work" means either the unmodified Program or a work based
-on the Program.
-
-  To "propagate" a work means to do anything with it that, without
-permission, would make you directly or secondarily liable for
-infringement under applicable copyright law, except executing it on a
-computer or modifying a private copy.  Propagation includes copying,
-distribution (with or without modification), making available to the
-public, and in some countries other activities as well.
-
-  To "convey" a work means any kind of propagation that enables other
-parties to make or receive copies.  Mere interaction with a user through
-a computer network, with no transfer of a copy, is not conveying.
-
-  An interactive user interface displays "Appropriate Legal Notices"
-to the extent that it includes a convenient and prominently visible
-feature that (1) displays an appropriate copyright notice, and (2)
-tells the user that there is no warranty for the work (except to the
-extent that warranties are provided), that licensees may convey the
-work under this License, and how to view a copy of this License.  If
-the interface presents a list of user commands or options, such as a
-menu, a prominent item in the list meets this criterion.
-
-  1. Source Code.
-
-  The "source code" for a work means the preferred form of the work
-for making modifications to it.  "Object code" means any non-source
-form of a work.
-
-  A "Standard Interface" means an interface that either is an official
-standard defined by a recognized standards body, or, in the case of
-interfaces specified for a particular programming language, one that
-is widely used among developers working in that language.
-
-  The "System Libraries" of an executable work include anything, other
-than the work as a whole, that (a) is included in the normal form of
-packaging a Major Component, but which is not part of that Major
-Component, and (b) serves only to enable use of the work with that
-Major Component, or to implement a Standard Interface for which an
-implementation is available to the public in source code form.  A
-"Major Component", in this context, means a major essential component
-(kernel, window system, and so on) of the specific operating system
-(if any) on which the executable work runs, or a compiler used to
-produce the work, or an object code interpreter used to run it.
-
-  The "Corresponding Source" for a work in object code form means all
-the source code needed to generate, install, and (for an executable
-work) run the object code and to modify the work, including scripts to
-control those activities.  However, it does not include the work's
-System Libraries, or general-purpose tools or generally available free
-programs which are used unmodified in performing those activities but
-which are not part of the work.  For example, Corresponding Source
-includes interface definition files associated with source files for
-the work, and the source code for shared libraries and dynamically
-linked subprograms that the work is specifically designed to require,
-such as by intimate data communication or control flow between those
-subprograms and other parts of the work.
-
-  The Corresponding Source need not include anything that users
-can regenerate automatically from other parts of the Corresponding
-Source.
-
-  The Corresponding Source for a work in source code form is that
-same work.
-
-  2. Basic Permissions.
-
-  All rights granted under this License are granted for the term of
-copyright on the Program, and are irrevocable provided the stated
-conditions are met.  This License explicitly affirms your unlimited
-permission to run the unmodified Program.  The output from running a
-covered work is covered by this License only if the output, given its
-content, constitutes a covered work.  This License acknowledges your
-rights of fair use or other equivalent, as provided by copyright law.
-
-  You may make, run and propagate covered works that you do not
-convey, without conditions so long as your license otherwise remains
-in force.  You may convey covered works to others for the sole purpose
-of having them make modifications exclusively for you, or provide you
-with facilities for running those works, provided that you comply with
-the terms of this License in conveying all material for which you do
-not control copyright.  Those thus making or running the covered works
-for you must do so exclusively on your behalf, under your direction
-and control, on terms that prohibit them from making any copies of
-your copyrighted material outside their relationship with you.
-
-  Conveying under any other circumstances is permitted solely under
-the conditions stated below.  Sublicensing is not allowed; section 10
-makes it unnecessary.
-
-  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
-
-  No covered work shall be deemed part of an effective technological
-measure under any applicable law fulfilling obligations under article
-11 of the WIPO copyright treaty adopted on 20 December 1996, or
-similar laws prohibiting or restricting circumvention of such
-measures.
-
-  When you convey a covered work, you waive any legal power to forbid
-circumvention of technological measures to the extent such circumvention
-is effected by exercising rights under this License with respect to
-the covered work, and you disclaim any intention to limit operation or
-modification of the work as a means of enforcing, against the work's
-users, your or third parties' legal rights to forbid circumvention of
-technological measures.
-
-  4. Conveying Verbatim Copies.
-
-  You may convey verbatim copies of the Program's source code as you
-receive it, in any medium, provided that you conspicuously and
-appropriately publish on each copy an appropriate copyright notice;
-keep intact all notices stating that this License and any
-non-permissive terms added in accord with section 7 apply to the code;
-keep intact all notices of the absence of any warranty; and give all
-recipients a copy of this License along with the Program.
-
-  You may charge any price or no price for each copy that you convey,
-and you may offer support or warranty protection for a fee.
-
-  5. Conveying Modified Source Versions.
-
-  You may convey a work based on the Program, or the modifications to
-produce it from the Program, in the form of source code under the
-terms of section 4, provided that you also meet all of these conditions:
-
-    a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
-
-    b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under section
-    7.  This requirement modifies the requirement in section 4 to
-    "keep intact all notices".
-
-    c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy.  This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged.  This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
-
-    d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
-
-  A compilation of a covered work with other separate and independent
-works, which are not by their nature extensions of the covered work,
-and which are not combined with it such as to form a larger program,
-in or on a volume of a storage or distribution medium, is called an
-"aggregate" if the compilation and its resulting copyright are not
-used to limit the access or legal rights of the compilation's users
-beyond what the individual works permit.  Inclusion of a covered work
-in an aggregate does not cause this License to apply to the other
-parts of the aggregate.
-
-  6. Conveying Non-Source Forms.
-
-  You may convey a covered work in object code form under the terms
-of sections 4 and 5, provided that you also convey the
-machine-readable Corresponding Source under the terms of this License,
-in one of these ways:
-
-    a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
-
-    b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the
-    Corresponding Source from a network server at no charge.
-
-    c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source.  This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
-
-    d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge.  You need not require recipients to copy the
-    Corresponding Source along with the object code.  If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source.  Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
-
-    e) Convey the object code using peer-to-peer transmission, provided
-    you inform other peers where the object code and Corresponding
-    Source of the work are being offered to the general public at no
-    charge under subsection 6d.
-
-  A separable portion of the object code, whose source code is excluded
-from the Corresponding Source as a System Library, need not be
-included in conveying the object code work.
-
-  A "User Product" is either (1) a "consumer product", which means any
-tangible personal property which is normally used for personal, family,
-or household purposes, or (2) anything designed or sold for incorporation
-into a dwelling.  In determining whether a product is a consumer product,
-doubtful cases shall be resolved in favor of coverage.  For a particular
-product received by a particular user, "normally used" refers to a
-typical or common use of that class of product, regardless of the status
-of the particular user or of the way in which the particular user
-actually uses, or expects or is expected to use, the product.  A product
-is a consumer product regardless of whether the product has substantial
-commercial, industrial or non-consumer uses, unless such uses represent
-the only significant mode of use of the product.
-
-  "Installation Information" for a User Product means any methods,
-procedures, authorization keys, or other information required to install
-and execute modified versions of a covered work in that User Product from
-a modified version of its Corresponding Source.  The information must
-suffice to ensure that the continued functioning of the modified object
-code is in no case prevented or interfered with solely because
-modification has been made.
-
-  If you convey an object code work under this section in, or with, or
-specifically for use in, a User Product, and the conveying occurs as
-part of a transaction in which the right of possession and use of the
-User Product is transferred to the recipient in perpetuity or for a
-fixed term (regardless of how the transaction is characterized), the
-Corresponding Source conveyed under this section must be accompanied
-by the Installation Information.  But this requirement does not apply
-if neither you nor any third party retains the ability to install
-modified object code on the User Product (for example, the work has
-been installed in ROM).
-
-  The requirement to provide Installation Information does not include a
-requirement to continue to provide support service, warranty, or updates
-for a work that has been modified or installed by the recipient, or for
-the User Product in which it has been modified or installed.  Access to a
-network may be denied when the modification itself materially and
-adversely affects the operation of the network or violates the rules and
-protocols for communication across the network.
-
-  Corresponding Source conveyed, and Installation Information provided,
-in accord with this section must be in a format that is publicly
-documented (and with an implementation available to the public in
-source code form), and must require no special password or key for
-unpacking, reading or copying.
-
-  7. Additional Terms.
-
-  "Additional permissions" are terms that supplement the terms of this
-License by making exceptions from one or more of its conditions.
-Additional permissions that are applicable to the entire Program shall
-be treated as though they were included in this License, to the extent
-that they are valid under applicable law.  If additional permissions
-apply only to part of the Program, that part may be used separately
-under those permissions, but the entire Program remains governed by
-this License without regard to the additional permissions.
-
-  When you convey a copy of a covered work, you may at your option
-remove any additional permissions from that copy, or from any part of
-it.  (Additional permissions may be written to require their own
-removal in certain cases when you modify the work.)  You may place
-additional permissions on material, added by you to a covered work,
-for which you have or can give appropriate copyright permission.
-
-  Notwithstanding any other provision of this License, for material you
-add to a covered work, you may (if authorized by the copyright holders of
-that material) supplement the terms of this License with terms:
-
-    a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
-
-    b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
-
-    c) Prohibiting misrepresentation of the origin of that material, or
-    requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
-
-    d) Limiting the use for publicity purposes of names of licensors or
-    authors of the material; or
-
-    e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
-
-    f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions of
-    it) with contractual assumptions of liability to the recipient, for
-    any liability that these contractual assumptions directly impose on
-    those licensors and authors.
-
-  All other non-permissive additional terms are considered "further
-restrictions" within the meaning of section 10.  If the Program as you
-received it, or any part of it, contains a notice stating that it is
-governed by this License along with a term that is a further
-restriction, you may remove that term.  If a license document contains
-a further restriction but permits relicensing or conveying under this
-License, you may add to a covered work material governed by the terms
-of that license document, provided that the further restriction does
-not survive such relicensing or conveying.
-
-  If you add terms to a covered work in accord with this section, you
-must place, in the relevant source files, a statement of the
-additional terms that apply to those files, or a notice indicating
-where to find the applicable terms.
-
-  Additional terms, permissive or non-permissive, may be stated in the
-form of a separately written license, or stated as exceptions;
-the above requirements apply either way.
-
-  8. Termination.
-
-  You may not propagate or modify a covered work except as expressly
-provided under this License.  Any attempt otherwise to propagate or
-modify it is void, and will automatically terminate your rights under
-this License (including any patent licenses granted under the third
-paragraph of section 11).
-
-  However, if you cease all violation of this License, then your
-license from a particular copyright holder is reinstated (a)
-provisionally, unless and until the copyright holder explicitly and
-finally terminates your license, and (b) permanently, if the copyright
-holder fails to notify you of the violation by some reasonable means
-prior to 60 days after the cessation.
-
-  Moreover, your license from a particular copyright holder is
-reinstated permanently if the copyright holder notifies you of the
-violation by some reasonable means, this is the first time you have
-received notice of violation of this License (for any work) from that
-copyright holder, and you cure the violation prior to 30 days after
-your receipt of the notice.
-
-  Termination of your rights under this section does not terminate the
-licenses of parties who have received copies or rights from you under
-this License.  If your rights have been terminated and not permanently
-reinstated, you do not qualify to receive new licenses for the same
-material under section 10.
-
-  9. Acceptance Not Required for Having Copies.
-
-  You are not required to accept this License in order to receive or
-run a copy of the Program.  Ancillary propagation of a covered work
-occurring solely as a consequence of using peer-to-peer transmission
-to receive a copy likewise does not require acceptance.  However,
-nothing other than this License grants you permission to propagate or
-modify any covered work.  These actions infringe copyright if you do
-not accept this License.  Therefore, by modifying or propagating a
-covered work, you indicate your acceptance of this License to do so.
-
-  10. Automatic Licensing of Downstream Recipients.
-
-  Each time you convey a covered work, the recipient automatically
-receives a license from the original licensors, to run, modify and
-propagate that work, subject to this License.  You are not responsible
-for enforcing compliance by third parties with this License.
-
-  An "entity transaction" is a transaction transferring control of an
-organization, or substantially all assets of one, or subdividing an
-organization, or merging organizations.  If propagation of a covered
-work results from an entity transaction, each party to that
-transaction who receives a copy of the work also receives whatever
-licenses to the work the party's predecessor in interest had or could
-give under the previous paragraph, plus a right to possession of the
-Corresponding Source of the work from the predecessor in interest, if
-the predecessor has it or can get it with reasonable efforts.
-
-  You may not impose any further restrictions on the exercise of the
-rights granted or affirmed under this License.  For example, you may
-not impose a license fee, royalty, or other charge for exercise of
-rights granted under this License, and you may not initiate litigation
-(including a cross-claim or counterclaim in a lawsuit) alleging that
-any patent claim is infringed by making, using, selling, offering for
-sale, or importing the Program or any portion of it.
-
-  11. Patents.
-
-  A "contributor" is a copyright holder who authorizes use under this
-License of the Program or a work on which the Program is based.  The
-work thus licensed is called the contributor's "contributor version".
-
-  A contributor's "essential patent claims" are all patent claims
-owned or controlled by the contributor, whether already acquired or
-hereafter acquired, that would be infringed by some manner, permitted
-by this License, of making, using, or selling its contributor version,
-but do not include claims that would be infringed only as a
-consequence of further modification of the contributor version.  For
-purposes of this definition, "control" includes the right to grant
-patent sublicenses in a manner consistent with the requirements of
-this License.
-
-  Each contributor grants you a non-exclusive, worldwide, royalty-free
-patent license under the contributor's essential patent claims, to
-make, use, sell, offer for sale, import and otherwise run, modify and
-propagate the contents of its contributor version.
-
-  In the following three paragraphs, a "patent license" is any express
-agreement or commitment, however denominated, not to enforce a patent
-(such as an express permission to practice a patent or covenant not to
-sue for patent infringement).  To "grant" such a patent license to a
-party means to make such an agreement or commitment not to enforce a
-patent against the party.
-
-  If you convey a covered work, knowingly relying on a patent license,
-and the Corresponding Source of the work is not available for anyone
-to copy, free of charge and under the terms of this License, through a
-publicly available network server or other readily accessible means,
-then you must either (1) cause the Corresponding Source to be so
-available, or (2) arrange to deprive yourself of the benefit of the
-patent license for this particular work, or (3) arrange, in a manner
-consistent with the requirements of this License, to extend the patent
-license to downstream recipients.  "Knowingly relying" means you have
-actual knowledge that, but for the patent license, your conveying the
-covered work in a country, or your recipient's use of the covered work
-in a country, would infringe one or more identifiable patents in that
-country that you have reason to believe are valid.
-
-  If, pursuant to or in connection with a single transaction or
-arrangement, you convey, or propagate by procuring conveyance of, a
-covered work, and grant a patent license to some of the parties
-receiving the covered work authorizing them to use, propagate, modify
-or convey a specific copy of the covered work, then the patent license
-you grant is automatically extended to all recipients of the covered
-work and works based on it.
-
-  A patent license is "discriminatory" if it does not include within
-the scope of its coverage, prohibits the exercise of, or is
-conditioned on the non-exercise of one or more of the rights that are
-specifically granted under this License.  You may not convey a covered
-work if you are a party to an arrangement with a third party that is
-in the business of distributing software, under which you make payment
-to the third party based on the extent of your activity of conveying
-the work, and under which the third party grants, to any of the
-parties who would receive the covered work from you, a discriminatory
-patent license (a) in connection with copies of the covered work
-conveyed by you (or copies made from those copies), or (b) primarily
-for and in connection with specific products or compilations that
-contain the covered work, unless you entered into that arrangement,
-or that patent license was granted, prior to 28 March 2007.
-
-  Nothing in this License shall be construed as excluding or limiting
-any implied license or other defenses to infringement that may
-otherwise be available to you under applicable patent law.
-
-  12. No Surrender of Others' Freedom.
-
-  If conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot convey a
-covered work so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you may
-not convey it at all.  For example, if you agree to terms that obligate you
-to collect a royalty for further conveying from those to whom you convey
-the Program, the only way you could satisfy both those terms and this
-License would be to refrain entirely from conveying the Program.
-
-  13. Use with the GNU Affero General Public License.
-
-  Notwithstanding any other provision of this License, you have
-permission to link or combine any covered work with a work licensed
-under version 3 of the GNU Affero General Public License into a single
-combined work, and to convey the resulting work.  The terms of this
-License will continue to apply to the part which is the covered work,
-but the special requirements of the GNU Affero General Public License,
-section 13, concerning interaction through a network will apply to the
-combination as such.
-
-  14. Revised Versions of this License.
-
-  The Free Software Foundation may publish revised and/or new versions of
-the GNU General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-  Each version is given a distinguishing version number.  If the
-Program specifies that a certain numbered version of the GNU General
-Public License "or any later version" applies to it, you have the
-option of following the terms and conditions either of that numbered
-version or of any later version published by the Free Software
-Foundation.  If the Program does not specify a version number of the
-GNU General Public License, you may choose any version ever published
-by the Free Software Foundation.
-
-  If the Program specifies that a proxy can decide which future
-versions of the GNU General Public License can be used, that proxy's
-public statement of acceptance of a version permanently authorizes you
-to choose that version for the Program.
-
-  Later license versions may give you additional or different
-permissions.  However, no additional obligations are imposed on any
-author or copyright holder as a result of your choosing to follow a
-later version.
-
-  15. Disclaimer of Warranty.
-
-  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
-APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
-HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
-OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
-THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
-IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
-ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. Limitation of Liability.
-
-  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
-THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
-GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
-USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
-DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
-PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
-EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGES.
-
-  17. Interpretation of Sections 15 and 16.
-
-  If the disclaimer of warranty and limitation of liability provided
-above cannot be given local legal effect according to their terms,
-reviewing courts shall apply local law that most closely approximates
-an absolute waiver of all civil liability in connection with the
-Program, unless a warranty or assumption of liability accompanies a
-copy of the Program in return for a fee.
-
-                     END OF TERMS AND CONDITIONS
-
-            How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-state the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <https://www.gnu.org/licenses/>.
-
-Also add information on how to contact you by electronic and paper mail.
-
-  If the program does terminal interaction, make it output a short
-notice like this when it starts in an interactive mode:
-
-    <program>  Copyright (C) <year>  <name of author>
-    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, your program's commands
-might be different; for a GUI interface, you would use an "about box".
-
-  You should also get your employer (if you work as a programmer) or school,
-if any, to sign a "copyright disclaimer" for the program, if necessary.
-For more information on this, and how to apply and follow the GNU GPL, see
-<https://www.gnu.org/licenses/>.
-
-  The GNU General Public License does not permit incorporating your program
-into proprietary programs.  If your program is a subroutine library, you
-may consider it more useful to permit linking proprietary applications with
-the library.  If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.  But first, please read
-<https://www.gnu.org/licenses/why-not-lgpl.html>.
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<https://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<https://www.gnu.org/licenses/why-not-lgpl.html>.
-- 
GitLab


From 6ee1d02f90e9bde8d158493685b9a79f17316361 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 08:40:38 +0000
Subject: [PATCH 040/229] format: doc

---
 doc/counter_ex.c | 9 +++------
 makefile         | 3 +++
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
index 5067003..188f4dd 100644
--- a/doc/counter_ex.c
+++ b/doc/counter_ex.c
@@ -2,21 +2,18 @@
 
 static int acc;
 
-unsigned int
-init_acc(char *a, void **b)
+unsigned int init_acc(char *a, void **b)
 {
     acc = 0;
 }
 
-unsigned int
-get_acc(uint64_t *results, void *none)
+unsigned int get_acc(uint64_t *results, void *none)
 {
     UNUSED(none);
     return a++;
 }
 
-void
-label_acc(char **labels, void *none)
+void label_acc(char **labels, void *none)
 {
     UNUSED(none);
     labels[0] = "acc";
diff --git a/makefile b/makefile
index 9988f8a..c43c867 100644
--- a/makefile
+++ b/makefile
@@ -1,9 +1,11 @@
 .PHONY: all clean mojitos mojitos_group debug format
 
 SRC_DIR = src
+DOC_DIR = doc
 OBJ_DIR = obj
 BIN_DIR = bin
 
+
 OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o util.o)
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
@@ -42,6 +44,7 @@ debug: all
 
 format:
 	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
+	$(ASTYLE) $(DOC_DIR)/*.c $(DOC_DIR)/*.h
 
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-- 
GitLab


From b1d79f008e5fd55f39f60d06e5991c5b2c292db0 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 23 Jan 2023 15:00:56 +0100
Subject: [PATCH 041/229] update doc (formatting, and new header)

---
 doc/counter_ex.c | 15 +++++++++------
 doc/counter_ex.h | 13 ++++++++++++-
 2 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
index 5067003..73696ad 100644
--- a/doc/counter_ex.c
+++ b/doc/counter_ex.c
@@ -2,22 +2,25 @@
 
 static int acc;
 
-unsigned int
-init_acc(char *a, void **b)
+unsigned int init_acc(char *a, void **b)
 {
     acc = 0;
 }
 
-unsigned int
-get_acc(uint64_t *results, void *none)
+unsigned int get_acc(uint64_t *results, void *none)
 {
     UNUSED(none);
     return a++;
 }
 
-void
-label_acc(char **labels, void *none)
+void label_acc(char **labels, void *none)
 {
     UNUSED(none);
     labels[0] = "acc";
 }
+
+void clean_acc(void *none)
+{
+	/* That's a no-op for this example */
+	UNUSED(none);
+}
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 49e185c..beeef91 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -4,4 +4,15 @@
 
 unsigned int init_acc(char *, void **);
 unsigned int get_acc(uint64_t *results, void *);
-void label_counter(char **labels, void *);
+void clean_acc(void*);
+void label_acc(char **labels, void *);
+
+struct optparse_long counters_opt = {"accumulator", 'a', OPTPARSE_NONE};
+struct captor counters = {
+    .usage_arg = NULL,
+    .usage_msg = "dumb accumulator\n"
+    .init = init_acc,
+    .get = get_acc,
+    .clean = clean_acc,
+    .label = label_acc,
+};
-- 
GitLab


From 0112f0fb7c8ba9420bb62323973590be0389264d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 14:24:10 +0000
Subject: [PATCH 042/229] add macros

---
 src/util.c | 27 ++++++++++++++++++++++++---
 src/util.h | 39 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/src/util.c b/src/util.c
index 5ff3acd..186434b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,6 +1,27 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "util.h"
 
-inline uint64_t substractAcc(const uint64_t l, const uint64_t r)
+uint64_t modulo_substraction(uint64_t previous, u_int64_t new)
 {
-    return (l < r) ? UINT64_MAX + (l - r) : l - r;
-}
\ No newline at end of file
+    return new > previous ? (previous - new)
+           : (UINT64_MAX - new) + previous;
+}
diff --git a/src/util.h b/src/util.h
index 1fff9af..6d4a644 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,10 +1,43 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #ifndef _UTIL_H
 #define _UTIL_H
 
-//#warning "TODO: Add licence"
-
 #include <stdint.h>
 
-inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
+#define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate,__LINE__,file)
+
+#define _impl_PASTE(a,b) a##b
+#define _impl_CASSERT_LINE(predicate, line, file) \
+    typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
+
+#define UNUSED(expr) do { (void)(expr); } while (0)
+#define PANIC(code, fmt, ...)                \
+    do {                                     \
+        fprintf(stderr, "Exit on error: ");  \
+        fprintf(stderr, fmt, ##__VA_ARGS__); \
+        fprintf(stderr, "\n");               \
+        exit(code);                          \
+    } while (0)
+
+uint64_t modulo_substraction(const uint64_t l, const uint64_t r);
 
 #endif
-- 
GitLab


From 89508f4d9e097464af8f64467f919f60185e4be8 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 14:25:34 +0000
Subject: [PATCH 043/229] working progress

---
 src/amd_rapl.c    | 323 +++++++++++++++++++++++
 src/amd_rapl.h    |  24 ++
 src/info_reader.c | 158 +++++++-----
 src/info_reader.h | 639 ++++++++++++++++++++++++----------------------
 4 files changed, 768 insertions(+), 376 deletions(-)
 create mode 100644 src/amd_rapl.c
 create mode 100644 src/amd_rapl.h

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
new file mode 100644
index 0000000..b83ded9
--- /dev/null
+++ b/src/amd_rapl.c
@@ -0,0 +1,323 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+#include <stdio.h>
+#include <stdint.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include "info_reader.h"
+#include "util.h"
+#include "amd_rapl.h"
+
+#warning "Must be modified before release"
+#define BUFFER_SIZE 64
+#define MAX_CPUS 64
+#define NB_KEYS 2
+
+// ---------------------------MSR_REGISTERS
+static const uint64_t amd_energy_mask = 0xFFFFFFFF;
+static const uint64_t amd_energy_unit_mask = 0x01F00;
+static const uint64_t msr_rapl_power_unit = 0xC0010299;
+static const uint64_t energy_core_msr = 0xC001029A;
+static const uint64_t energy_pkg_msr = 0xC001029B;
+
+// ------------------------------FILE_PATHS
+static const char *base_str = "/dev/cpu/%d/msr";
+static const char *cpuinfo = "/proc/cpuinfo";
+
+struct cpu_sensor_t {
+    //TODO: check the reset of the msr registers
+#warning "Check the reset of the msr registers"
+    size_t cpu_id;
+    size_t package_id;
+    char *name;
+
+    int *fd;
+    uint64_t energy_units;
+    uint64_t core_energy;
+    uint64_t pkg_energy;
+};
+typedef struct cpu_sensor_t cpu_sensor_t;
+
+struct _amd_rapl_t {
+    cpu_sensor_t *sensors;
+    unsigned int nb;
+};
+typedef struct _amd_rapl_t _amd_rapl_t;
+
+// -----------------------------INFO_READER
+
+static GenericPointer _size_t_allocator(char *s)
+{
+    size_t value = atoi(s);
+    return (GenericPointer) value;
+}
+
+static void _set_cpu_id(GenericPointer storage, GenericPointer data)
+{
+    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    cpu->cpu_id = (size_t) data;
+}
+
+static void _set_package_id(GenericPointer storage, GenericPointer data)
+{
+    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    cpu->package_id = (size_t) data;
+}
+
+static KeyFinder keys[NB_KEYS] = {
+    {"processor", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_cpu_id},
+    {"physical id", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_package_id}
+};
+
+// --------------------------------READ_MSR
+
+uint64_t read_msr(int fd, uint64_t msr)
+{
+    uint64_t data;
+    if (pread(fd, &data, sizeof data, msr) != sizeof data) {
+        fprintf(stderr, "msr(%ld):", msr);
+        perror("pread");
+        exit(127);
+    }
+    return data;
+}
+
+uint64_t read_unit(int fd)
+{
+    u_int64_t unit = read_msr(fd, msr_rapl_power_unit);
+    return (unit & amd_energy_unit_mask) >> 8;
+}
+
+uint64_t read_raw_core_energy(int fd)
+{
+    u_int64_t energy = read_msr(fd, energy_core_msr);
+    return energy & amd_energy_mask;
+}
+
+uint64_t read_raw_pkg_energy(int fd)
+{
+    u_int64_t energy = read_msr(fd, energy_pkg_msr);
+    return energy & amd_energy_mask;
+}
+
+// ---------------------------------ENERGY
+
+uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
+{
+    // raw * (1 / (unit^2)) -> Joule
+    // Joule * 1000000 -> microjoule
+    return (raw * 1000000UL) / (1ul << unit);
+}
+uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
+{
+    // raw * (1 / (unit^2)) -> Joule
+    return raw / (1ul << unit);
+}
+
+// -----------------------------------DEBUG
+
+#ifdef DEBUG
+void debug_print_sensor(cpu_sensor_t *sensor)
+{
+    CASSERT(sizeof(cpu_sensor_t) == 40, amd_rapl_c);
+    printf("cpu_id : %ld, package_id : %ld, energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+           sensor->cpu_id,
+           sensor->package_id,
+           sensor->energy_units,
+           sensor->core_energy,
+           sensor->pkg_energy
+          );
+}
+
+void debug_print_amd_rapl(_amd_rapl_t *rapl)
+{
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+        debug_print_sensor(rapl->sensors[i]);
+    }
+}
+#endif
+
+
+
+// ---------------------------AMD_RAPL_UTIL
+
+uint64_t modulo_substraction(uint64_t previous, u_int64_t new)
+{
+    return new > previous ? (previous - new)
+           : (UINT64_MAX - new) + previous;
+}
+
+unsigned int get_nb_cpu()
+{
+    char filename[BUFFER_SIZE];
+
+    unsigned int n_cpu = 0;
+    for (;; n_cpu++) {
+        sprintf(filename, base_str, n_cpu);
+
+        int fd = open(filename, O_RDONLY);
+        if (fd < 0) {
+            break;
+        }
+        close(fd);
+    }
+    return n_cpu;
+}
+
+void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
+{
+    static const char *base_name = "core%ld";
+    static char filename[BUFFER_SIZE];
+    sprintf(filename, base_str, cpu_id);
+
+    int fd = open(filename, O_RDONLY);
+    if (fd < 0) {
+        perror("rdmsr:open");
+        exit(127);
+    }
+
+    u_int64_t raw_core_energy = read_raw_core_energy(fd);
+    u_int64_t raw_pkg_energy = read_raw_pkg_energy(fd);
+
+    sensor->cpu_id = cpu_id;
+    asprintf(sensor->name, base_name, sensor->cpu_id);
+    sensor->energy_units = read_unit(fd);
+    sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
+    sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
+}
+
+u_int64_t get_core_energy(cpu_sensor_t *sensor)
+{
+    u_int64_t raw_core_energy = read_raw_core_energy(sensor->fd);
+    u_int64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units)
+
+                            u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
+    sensor->core_energy = core_energy;
+    return energy_consumed;
+}
+
+u_int64_t get_pkg_energy(cpu_sensor_t *sensor)
+{
+    u_int64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
+    u_int64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units)
+
+                           u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
+    sensor->pkg_energy = pkg_energy;
+    return energy_consumed;
+}
+
+// ----------------------AMD_RAPL_INTERFACE
+
+
+void free_amd_rapl(_amd_rapl_t *rapl)
+{
+    free(rapl->sensors);
+    free(rapl);
+}
+
+
+unsigned int init_amd_rapl(char *none, void **ptr)
+{
+// 	FILE *fcpuinfo = fopen(cpuinfo, "r");
+// 	if (fcpuinfo == NULL) {
+// 		perror("fopen");
+// 		exit(1);
+// 	}
+//     Parser parser = {
+//         (GenericPointer) cpus,
+// 		0,
+//         MAX_CPUS,
+//         sizeof(cpu_sensor_t),
+//         keys,
+// 		NB_KEYS,
+// 		fcpuinfo
+//     };
+//     parse(&parser);
+// 	fclose(fcpuinfo);
+
+// #ifdef DEBUG
+// 	printf("nb_cpus: %d\n", parser.nb_stored);
+// 	for (unsigned int nb_cpu = 0; nb_cpu < parser.nb_stored; ++nb_cpu) {
+// 		debug_print_sensor(&cpus[nb_cpu]);
+// 	}
+// #endif
+
+    UNUSED(none);
+    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+
+    unsigned int nb_cpu = get_nb_cpu();
+    if (nb_cpu == 0) {
+        perror("get_nb_cpu");
+        exit(127);
+    }
+
+    cpu_sensor_tr *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
+
+    rapl->nb = nb_cpu;
+    rapl->sensors = cpus;
+
+    for (unsigned int i = 0; i < nb_cpu; i++) {
+        init_cpu_sensor(&rapl->sensors[i], i);
+    }
+    return rapl->nb;
+}
+
+
+unsigned int get_amd_rapl(uint64_t results, void *ptr)
+{
+    _amd_rapl_t *rapl = (_amd_rapl_t) ptr;
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+        // TODO: check if unit is the same
+#warning "check if unit is the same"
+        results[i] = get_core_energy(rapl->sensors[i]);
+    }
+    return rapl->nb;
+}
+
+
+
+
+int main()
+{
+    _amd_rapl_t *rapl = (_amd_rapl_t *)malloc(sizeof(_amd_rapl_t));
+    init_amd_rapl(rapl);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+    sleep(1);
+    print_amd_rapl(rapl);
+
+    free_amd_rapl(rapl);
+    return 0;
+}
+
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
new file mode 100644
index 0000000..459c136
--- /dev/null
+++ b/src/amd_rapl.h
@@ -0,0 +1,24 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_amd_rapl(char *, void **);
+unsigned int get_amd_rapl(uint64_t *results, void *);
+void clean_amd_rapl(void *);
+void label_amd_rapl(char **labels, void *);
diff --git a/src/info_reader.c b/src/info_reader.c
index 110d060..e2563c6 100644
--- a/src/info_reader.c
+++ b/src/info_reader.c
@@ -1,89 +1,115 @@
 #include "info_reader.h"
+#include <stdint.h>
 
-#ifdef DEBUG										
-	#warning "PTR_TO_TPTR hide a cast warning"aa	
-#endif												
+#ifdef DEBUG
+#warning "PTR_TO_TPTR hide a cast warning"aa
+#endif
 
-#define MAX_PROCS 128
+#define MAX_PROCS 2
 typedef struct {
-  size_t processor;
-  char *vendor_id;
-  size_t family;
-  size_t core_id;
-  size_t physical_id;
-  char *model_name;
+    size_t processor;
+    char *vendor_id;
+    size_t family;
+    size_t core_id;
+    size_t physical_id;
+    char *model_name;
 } Cpu;
 
-GenericPointer int_allocator(char *s) {
-  size_t value = atoi(s);
-  return (GenericPointer) value;
+GenericPointer int_allocator(char *s)
+{
+    size_t value = atoi(s);
+    return (GenericPointer) value;
 }
 
-GenericPointer string_allocator(char *s) {
-  char *value = malloc(strlen(s) + 1);
-  strcpy(value, s);
-  return (GenericPointer) value;
+GenericPointer string_allocator(char *s)
+{
+    char *value = malloc(strlen(s) + 1);
+    strcpy(value, s);
+    return (GenericPointer) value;
 }
 
-void set_processor(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->processor = data; 
+void set_processor(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->processor = data;
 }
-void set_vendor_id(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->vendor_id = (char*) data; 
+void set_vendor_id(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->vendor_id = (char *) data;
 }
-void set_family(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->family = data; 
+void set_family(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->family = data;
 }
-void set_core_id(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->core_id = data; 
+void set_core_id(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->core_id = data;
 }
-void set_physical_id(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->physical_id = data; 
+void set_physical_id(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->physical_id = data;
 }
-void set_model_name(GenericPointer storage, GenericPointer data) {
-	Cpu* cpu = (Cpu*) storage;
-	cpu->model_name = (char*) data; 
+void set_model_name(GenericPointer storage, GenericPointer data)
+{
+    Cpu *cpu = (Cpu *) storage;
+    cpu->model_name = (char *) data;
 }
 
-int main(int argc, char const *argv[]) {
-  Cpu cpus[MAX_PROCS];
-  KeyFinder keys[] = {
-	  {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
-	  {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
-	  {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
-	  {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
-	  {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
-	  {"model name", ": ", (CopyAllocator *) string_allocator,
-		  (Setter *)set_model_name}
-  };
+struct cpu_sensor_t {
+    //TODO: check the reset of the msr registers
+#warning "Check the reset of the msr registers"
+    size_t cpu_id;
+    size_t package_id;
 
-  Parser parser = {.storage = (GenericPointer) cpus,
-                   .capacity = MAX_PROCS,
-                   .storage_struct_size = sizeof(Cpu),
-                   .keys = keys,
-                   .nb_keys = 6,
-                   .file = fopen("/proc/cpuinfo", "r")};
+    uint64_t energy_units;
+    uint64_t core_energy_status;
+    uint64_t pkg_energy_status;
+};
 
-  parse(&parser);
+int main(int argc, char const *argv[])
+{
+    Cpu cpus[MAX_PROCS];
+    KeyFinder keys[] = {
+        {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
+        {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
+        {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
+        {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
+        {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
+        {
+            "model name", ": ", (CopyAllocator *) string_allocator,
+            (Setter *)set_model_name
+        }
+    };
 
-  for (unsigned int i = 0; i < parser.nb_stored; ++i) {
-    printf("========== PROC[%d] ==========\n", i);
-    printf("Processor: %ld\n", cpus[i].processor);
-    printf("Vendor ID: %s\n", cpus[i].vendor_id);
-    printf("Family: %ld\n", cpus[i].family);
-    printf("Core ID: %ld\n", cpus[i].core_id);
-    printf("Physical ID: %ld\n", cpus[i].physical_id);
-    printf("Model Name: %s\n", cpus[i].model_name);
-    printf("==============================\n");
-    free(cpus[i].vendor_id);
-    free(cpus[i].model_name);
-  }
+    Parser parser = {.storage = (GenericPointer) cpus,
+                     .capacity = MAX_PROCS,
+                     .storage_struct_size = sizeof(Cpu),
+                     .keys = keys,
+                     .nb_keys = 6,
+                     .file = fopen("/proc/cpuinfo", "r")
+                    };
 
-  return 0;
+    parse(&parser);
+
+    for (unsigned int i = 0; i < parser.nb_stored; ++i) {
+        printf("========== PROC[%d] ==========\n", i);
+        printf("Processor: %ld\n", cpus[i].processor);
+        printf("Vendor ID: %s\n", cpus[i].vendor_id);
+        printf("Family: %ld\n", cpus[i].family);
+        printf("Core ID: %ld\n", cpus[i].core_id);
+        printf("Physical ID: %ld\n", cpus[i].physical_id);
+        printf("Model Name: %s\n", cpus[i].model_name);
+        printf("==============================\n");
+        free(cpus[i].vendor_id);
+        free(cpus[i].model_name);
+    }
+
+    printf("size = %ld\n", sizeof (struct cpu_sensor_t));
+
+    return 0;
 }
 
diff --git a/src/info_reader.h b/src/info_reader.h
index 030ea52..4717841 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -8,7 +8,7 @@
  * @brief The parser struct
  * The struct containing all the necessary informations and functions to parse a file
  *
- * @var storage : void* : pointer to the storage where the parsed data will be stored
+ * @var storage : GenericPointer : pointer to the storage where the parsed data will be stored
  * @var nb_stored : unsigned int : the number of struct stored
  * @var capacity : unsigned int : the maximum number of struct that can be stored
  * @var storage_struct_size : size_t : the size of the struct stored in the storage
@@ -22,7 +22,7 @@ typedef struct Parser Parser;
  * @struct KeyFinder
  * @brief The key finder struct
  * The struct containing all the necessary informations and functions to find a key in a line of text
- * 
+ *
  * @var key : char* : the key to be found
  * @var delimiter : char* : the delimiter between the key and the value
  * @var copy : CopyAllocator*: the function to use to make a copy of the value
@@ -58,17 +58,17 @@ static void split_on_delimiter(char *string, const char *delimiter, char **key,
  * @param[in] to The character to replace with.
  * @return None.
  */
-static void replace_first(char* string, char from, char to);
+static void replace_first(char *string, char from, char to);
 
 /**
  * @brief Check if a string starts with a prefix.
- * 
+ *
  * @param[in] prefix The prefix to check.
  * @param[in] string The string to check.
  * @return true The string starts with the prefix.
  * @return false The string does not start with the prefix or one of the input pointers is NULL.
  */
-static bool start_with(const char* prefix, const char* string);
+static bool start_with(const char *prefix, const char *string);
 
 /**
  * @brief Matches a line of text to a key in the parser's list of keys.
@@ -82,38 +82,36 @@ static bool start_with(const char* prefix, const char* string);
  */
 static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value);
 
-
-
-
 typedef size_t GenericPointer;
 typedef GenericPointer (CopyAllocator) (char *string);
 typedef void (Setter) (GenericPointer storage, GenericPointer value);
 
 struct KeyFinder {
-  char *key;
-  char *delimiter;
+    char *key;
+    char *delimiter;
 
-  CopyAllocator *copy;
-  Setter *set;
+    CopyAllocator *copy;
+    Setter *set;
 };
 
 struct Parser {
-  GenericPointer storage;
-  unsigned int nb_stored;
-  unsigned int capacity;
-  size_t storage_struct_size;
+    GenericPointer storage;
+    unsigned int nb_stored;
+    unsigned int capacity;
+    size_t storage_struct_size;
 
-  KeyFinder *keys;
-  unsigned int nb_keys;
+    KeyFinder *keys;
+    unsigned int nb_keys;
 
-  FILE *file;
+    FILE *file;
 };
 
-static void set_value(Parser *parser, KeyFinder *key_finder, char* raw_value) {
-	GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored);
-	GenericPointer value = key_finder->copy(raw_value);
-	key_finder->set(address, value);
-} 
+static void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value)
+{
+    GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored);
+    GenericPointer value = key_finder->copy(raw_value);
+    key_finder->set(address, value);
+}
 
 // static void storage_zero(Parser *parser) {
 // 	static const int zero = 0;
@@ -123,68 +121,72 @@ static void set_value(Parser *parser, KeyFinder *key_finder, char* raw_value) {
 // 	memset(storage, zero, struct_size * capacity);
 // }
 
-static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value) {
-	for (unsigned int i = 0; i < parser->nb_keys; i++) {
-		KeyFinder *finder = &parser->keys[i];
-
-		if (start_with(finder->key, line)) {
-			char* value = NULL;
-			char* key = NULL;
-
-			split_on_delimiter(line, finder->delimiter, &key, &value);
-			if ( key == NULL || value == NULL) {
-				return 0;
-			}
-			*key_finder = finder;
-			*raw_value = value;
-			return 1;
-		}
-	}
-	return 0;
+static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value)
+{
+    for (unsigned int i = 0; i < parser->nb_keys; i++) {
+        KeyFinder *finder = &parser->keys[i];
+
+        if (start_with(finder->key, line)) {
+            char *value = NULL;
+            char *key = NULL;
+
+            split_on_delimiter(line, finder->delimiter, &key, &value);
+            if ( key == NULL || value == NULL) {
+                return 0;
+            }
+            *key_finder = finder;
+            *raw_value = value;
+            return 1;
+        }
+    }
+    return 0;
 }
 
-static unsigned int move_to_next(Parser *parser) {
-	parser->nb_stored += 1;
-	if (parser->nb_stored >= parser->capacity) {
-		return 0;
-	}
-	return 1;
+static unsigned int move_to_next(Parser *parser)
+{
+    parser->nb_stored += 1;
+    if (parser->nb_stored >= parser->capacity) {
+        return 0;
+    }
+    return 1;
 }
 
-static unsigned int parse(Parser *parser) {
-	char *line = NULL;
-	size_t len = 0;
-	ssize_t read;
-	unsigned int key_assigned = 0;
-
-	while ((read = getline(&line, &len, parser->file)) != -1) {
-		if (key_assigned == parser->nb_keys && read > 1) {
-			continue;
-		} else if (read == 1) {
-			if (!move_to_next(parser)) {
-				return 0;
-			}
-			key_assigned = 0;
-		} else {
-			KeyFinder *key_finder = NULL;
-			char *raw_value = NULL;
-			replace_first(line, '\n', '\0');
-			if (match(parser, line, &key_finder, &raw_value)) {
-				set_value(parser, key_finder, raw_value);
-				++key_assigned;
-			}
-		}
-	}
-	if (key_assigned > 0) {
-		parser->nb_stored++;
-	}
-	free(line);
-	return 1;
+static unsigned int parse(Parser *parser)
+{
+    char *line = NULL;
+    size_t len = 0;
+    ssize_t read;
+    unsigned int key_assigned = 0;
+
+    while ((read = getline(&line, &len, parser->file)) != -1) {
+        if (key_assigned == parser->nb_keys && read > 1) {
+            continue;
+        } else if (read == 1) {
+            if (!move_to_next(parser)) {
+                return 0;
+            }
+            key_assigned = 0;
+        } else {
+            KeyFinder *key_finder = NULL;
+            char *raw_value = NULL;
+            replace_first(line, '\n', '\0');
+            if (match(parser, line, &key_finder, &raw_value)) {
+                set_value(parser, key_finder, raw_value);
+                ++key_assigned;
+            }
+        }
+    }
+    if (key_assigned > 0) {
+        parser->nb_stored++;
+    }
+    free(line);
+    return 1;
 }
 
 
 
-static void replace_first(char* string, char from, char to) {
+static void replace_first(char *string, char from, char to)
+{
     for (int i = 0; string[i] != '\0'; i++) {
         if (string[i] == from) {
             string[i] = to;
@@ -193,31 +195,33 @@ static void replace_first(char* string, char from, char to) {
     }
 }
 
-static void split_on_delimiter(char *string, const char* delimiter, char **key, char **value) {
-	*key = NULL;
-	*value = NULL;
-	size_t delimiter_len = strlen(delimiter);
-	char* start_delimiter = strstr(string, delimiter);
-	if (start_delimiter != NULL) {
-		*start_delimiter = '\0';
-		*key = string;
-		*value = start_delimiter + delimiter_len;
-	}
+static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value)
+{
+    *key = NULL;
+    *value = NULL;
+    size_t delimiter_len = strlen(delimiter);
+    char *start_delimiter = strstr(string, delimiter);
+    if (start_delimiter != NULL) {
+        *start_delimiter = '\0';
+        *key = string;
+        *value = start_delimiter + delimiter_len;
+    }
 }
 
-static bool start_with(const char *prefix, const char *string) {
-	if (prefix == NULL || string == NULL) {
-		return false;
-	}
+static bool start_with(const char *prefix, const char *string)
+{
+    if (prefix == NULL || string == NULL) {
+        return false;
+    }
 
-	size_t prefix_len = strlen(prefix);
-	size_t string_len = strlen(string);
+    size_t prefix_len = strlen(prefix);
+    size_t string_len = strlen(string);
 
-	if (string_len < prefix_len) {
-		return false;
-	} else {
-		return  memcmp(prefix, string, prefix_len) == 0;
-	}
+    if (string_len < prefix_len) {
+        return false;
+    } else {
+        return  memcmp(prefix, string, prefix_len) == 0;
+    }
 }
 
 
@@ -235,161 +239,174 @@ static bool start_with(const char *prefix, const char *string) {
 #define TEST_PTR(result, expected) \
 	test_ptr(__FILE__, __LINE__, result, expected)
 
-typedef int (Comparator) (void*, void*);
-typedef char* (Formatter) (char*, void*);
-
-int string_compare(char* string1, char* string2) {
-	if (string1 == NULL && string2 == NULL) {
-		return 1;
-	} else if (string1 == NULL || string2 == NULL) {
-		return 0;
-	} else {
-		return (strcmp(string1, string2) == 0);
-	}
+typedef int (Comparator) (void *, void *);
+typedef char *(Formatter) (char *, void *);
+
+int string_compare(char *string1, char *string2)
+{
+    if (string1 == NULL && string2 == NULL) {
+        return 1;
+    } else if (string1 == NULL || string2 == NULL) {
+        return 0;
+    } else {
+        return (strcmp(string1, string2) == 0);
+    }
 }
 
-char* string_format(__attribute__((unused)) char* buffer, char* string) {
-	return FMT_NULL(string);
+char *string_format(__attribute__((unused)) char *buffer, char *string)
+{
+    return FMT_NULL(string);
 }
 
 
-int boolean_compare(bool* boolean1, bool* boolean2) {
-	return *boolean1 == *boolean2;
+int boolean_compare(bool *boolean1, bool *boolean2)
+{
+    return *boolean1 == *boolean2;
 }
 
-char* boolean_format(__attribute__((unused)) char* buffer, bool* boolean) {
-	return *boolean ? "True" : "False";
+char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
+{
+    return *boolean ? "True" : "False";
 }
 
-int ptr_compare(void* ptr1, void* ptr2) {
-	return ptr1 == ptr2;	
+int ptr_compare(void *ptr1, void *ptr2)
+{
+    return ptr1 == ptr2;
 }
 
-char* ptr_format(char* buffer, void* ptr) {
-	sprintf(buffer, "%p", ptr);
-	return buffer;
+char *ptr_format(char *buffer, void *ptr)
+{
+    sprintf(buffer, "%p", ptr);
+    return buffer;
 }
 
-void test(char* file, int line, void* result, void* expected, Comparator* compare, Formatter* format){
-	static char buffer_result[1000];
-	static char buffer_expected[1000];
-	if (compare(result, expected) == 0){
-		printf("Test %s:%d failed: expected %s, got %s\n",
-				file,
-				line,
-				format(buffer_result, expected),
-				format(buffer_expected, result)
-			  );
-	} else {
-		printf("Test %s:%d passed\n", file, line);
-	}
+void test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+{
+    static char buffer_result[1000];
+    static char buffer_expected[1000];
+    if (compare(result, expected) == 0) {
+        printf("Test %s:%d failed: expected %s, got %s\n",
+               file,
+               line,
+               format(buffer_result, expected),
+               format(buffer_expected, result)
+              );
+    } else {
+        printf("Test %s:%d passed\n", file, line);
+    }
 }
 
-void test_str(char* file, int line, char* result, char* expected) {
-	Comparator* compare = (Comparator*) string_compare;
-	Formatter* format = (Formatter*) string_format;
+void test_str(char *file, int line, char *result, char *expected)
+{
+    Comparator *compare = (Comparator *) string_compare;
+    Formatter *format = (Formatter *) string_format;
 
-	test(file, line, result, expected, compare, format);
+    test(file, line, result, expected, compare, format);
 }
 
-void test_boolean(char* file, int line, bool* result, bool* expected) {
-	Comparator* compare = (Comparator*) boolean_compare;
-	Formatter* format = (Formatter*) boolean_format;
+void test_boolean(char *file, int line, bool *result, bool *expected)
+{
+    Comparator *compare = (Comparator *) boolean_compare;
+    Formatter *format = (Formatter *) boolean_format;
 
-	test(file, line, (void*) result, (void*) expected, compare, format);
+    test(file, line, (void *) result, (void *) expected, compare, format);
 }
 
-void test_ptr(char* file, int line, void* result, void* expected) {
-	Comparator* compare = (Comparator*) ptr_compare;
-	Formatter* format = (Formatter*) ptr_format;
+void test_ptr(char *file, int line, void *result, void *expected)
+{
+    Comparator *compare = (Comparator *) ptr_compare;
+    Formatter *format = (Formatter *) ptr_format;
 
-	test(file, line, result, expected, compare, format);
+    test(file, line, result, expected, compare, format);
 }
 
-void test_replace_first() {
-	printf("==== TEST replace_first() ====\n");
-	char test1[] = "This is my string";
-	replace_first(test1, 'i', 'I');
-	TEST_STR(test1, "ThIs is my string");
+void test_replace_first()
+{
+    printf("==== TEST replace_first() ====\n");
+    char test1[] = "This is my string";
+    replace_first(test1, 'i', 'I');
+    TEST_STR(test1, "ThIs is my string");
 
-	char test2[] = "This is my string";
-	replace_first(test2, 'x', 'X');
-	TEST_STR(test2, "This is my string");
+    char test2[] = "This is my string";
+    replace_first(test2, 'x', 'X');
+    TEST_STR(test2, "This is my string");
 
 
-	char test3[] = "This is my string";
-	replace_first(test3, ' ', '_');
-	TEST_STR(test3, "This_is my string");
+    char test3[] = "This is my string";
+    replace_first(test3, ' ', '_');
+    TEST_STR(test3, "This_is my string");
 }
 
-void test_split_on_delimiter() {
-	printf("==== TEST split_on_delimite() ====\n");
-	char test4[] = "key:value";
-	char* key;
-	char* value;
-	split_on_delimiter(test4, ":", &key, &value);
-	TEST_STR(key, "key");
-	TEST_STR(value, "value");
-
-	char test5[] = "key: value";
-	split_on_delimiter(test5, ":", &key, &value);
-	TEST_STR(key, "key");
-	TEST_STR(value, " value");
-
-	char test6[] = "key:value";
-	replace_first(test6, ':', ' ');
-	split_on_delimiter(test6, " ", &key, &value);
-	TEST_STR(key, "key");
-	TEST_STR(value, "value");
-
-	char test7[] = "";
-	split_on_delimiter(test7, ":", &key, &value);
-	TEST_STR(key, NULL);
-	TEST_STR(value, NULL);
-
-	char test9[] = "key:value:extra";
-	split_on_delimiter(test9, ":", &key, &value);
-	TEST_STR(key, "key");
-	TEST_STR(value, "value:extra");
-
-	char test10[] = "key: value :extra";
-	split_on_delimiter(test10, ":", &key, &value);
-	TEST_STR(key, "key");
-	TEST_STR(value, " value :extra");
+void test_split_on_delimiter()
+{
+    printf("==== TEST split_on_delimite() ====\n");
+    char test4[] = "key:value";
+    char *key;
+    char *value;
+    split_on_delimiter(test4, ":", &key, &value);
+    TEST_STR(key, "key");
+    TEST_STR(value, "value");
+
+    char test5[] = "key: value";
+    split_on_delimiter(test5, ":", &key, &value);
+    TEST_STR(key, "key");
+    TEST_STR(value, " value");
+
+    char test6[] = "key:value";
+    replace_first(test6, ':', ' ');
+    split_on_delimiter(test6, " ", &key, &value);
+    TEST_STR(key, "key");
+    TEST_STR(value, "value");
+
+    char test7[] = "";
+    split_on_delimiter(test7, ":", &key, &value);
+    TEST_STR(key, NULL);
+    TEST_STR(value, NULL);
+
+    char test9[] = "key:value:extra";
+    split_on_delimiter(test9, ":", &key, &value);
+    TEST_STR(key, "key");
+    TEST_STR(value, "value:extra");
+
+    char test10[] = "key: value :extra";
+    split_on_delimiter(test10, ":", &key, &value);
+    TEST_STR(key, "key");
+    TEST_STR(value, " value :extra");
 }
 
-void test_start_with() {
-	printf("==== TEST start_with() ====\n");
-	char* prefix = NULL;
-	char* string = NULL;
-	bool result = false;
-	bool _true = true;
-	bool _false = false;
-
-	prefix = "Hello";
-	string = "Hello World";
-	result = start_with(prefix, string);
-	TEST_BOOLEAN(&result, &_true);
-
-	prefix = "Goodbye";
-	string = "Hello World";
-	result = start_with(prefix, string);
-	TEST_BOOLEAN(&result, &_false);
-
-	prefix = "Hello World";
-	string = "Hello";
-	result = start_with(prefix, string);
-	TEST_BOOLEAN(&result, &_false);
-
-	prefix = "Hello";
-	string = "Hello";
-	result = start_with(prefix, string);
-	TEST_BOOLEAN(&result, &_true);
-
-	prefix = NULL;
-	string = "Hello World";
-	result = start_with(prefix, string);
-	TEST_BOOLEAN(&result, &_false);
+void test_start_with()
+{
+    printf("==== TEST start_with() ====\n");
+    char *prefix = NULL;
+    char *string = NULL;
+    bool result = false;
+    bool _true = true;
+    bool _false = false;
+
+    prefix = "Hello";
+    string = "Hello World";
+    result = start_with(prefix, string);
+    TEST_BOOLEAN(&result, &_true);
+
+    prefix = "Goodbye";
+    string = "Hello World";
+    result = start_with(prefix, string);
+    TEST_BOOLEAN(&result, &_false);
+
+    prefix = "Hello World";
+    string = "Hello";
+    result = start_with(prefix, string);
+    TEST_BOOLEAN(&result, &_false);
+
+    prefix = "Hello";
+    string = "Hello";
+    result = start_with(prefix, string);
+    TEST_BOOLEAN(&result, &_true);
+
+    prefix = NULL;
+    string = "Hello World";
+    result = start_with(prefix, string);
+    TEST_BOOLEAN(&result, &_false);
 }
 
 #define DUMB_KEYFINDER(key_finder, key, delimiter)  \
@@ -416,95 +433,97 @@ void test_start_with() {
 	} while (0);
 
 
-void test_match() {
-	printf("==== TEST match() ====\n");
-	// usefull variable :
-	bool _true = true;
-	bool _false = false;
-	KeyFinder keys[10];
-	char line[100];
-	Parser parser;
-	bool result;
-	KeyFinder* found_key_finder = NULL;
-	char* raw_value = NULL;
-	
-	// Test 1:
-	// -- Setup
-	DUMB_KEYFINDER(keys[0], "key", ": ");
-	DUMB_PARSER(parser, keys, 1);
-	strcpy(line, "key: value");
-	found_key_finder = NULL;
-	raw_value = NULL;
-	// -- Run
-	result = match(&parser, line, &found_key_finder, &raw_value);
-	// -- Verification
-	TEST_BOOLEAN(&result, &_true);
-	TEST_PTR(found_key_finder, &keys[0]);
-	TEST_STR(raw_value, "value"); 
-
-	// Test 2:
-	// -- Setup
-	DUMB_KEYFINDER(keys[0], "key", ": ");
-	DUMB_PARSER(parser, keys, 1)
-	strcpy(line, "not a key: value");
-	found_key_finder = NULL;
-	raw_value = NULL;
-	// -- Run
-	result = match(&parser, line, &found_key_finder, &raw_value);
-	// -- Verification
-	TEST_BOOLEAN(&result, &_false);
-	TEST_PTR(found_key_finder, NULL);
-	TEST_STR(raw_value, NULL); 
-
-	// Test 3:
-	// -- Setup
-	DUMB_KEYFINDER(keys[0],"key", ": ");
-	DUMB_PARSER(parser, keys, 1);
-	strcpy(line, "key:value");
-	found_key_finder = NULL;
-	raw_value = NULL;
-	// -- Run
-	result = match(&parser, line, &found_key_finder, &raw_value);
-	// -- Verification	
-	TEST_BOOLEAN(&result, &_false);
-	TEST_PTR(found_key_finder, NULL);
-	TEST_STR(raw_value, NULL); 
-
-	// Test 4:
-	// -- Setup
-	DUMB_KEYFINDER(keys[0], "key", ": ");
-	DUMB_KEYFINDER(keys[1], "second_key", ": ");
-	DUMB_PARSER(parser, keys, 2);
-	strcpy(line, "second_key: value");
-	found_key_finder = NULL;
-	raw_value = NULL;
-	// -- Run
-	result = match(&parser, line, &found_key_finder, &raw_value);
-	// -- Verification
-	TEST_BOOLEAN(&result, &_true);
-	TEST_PTR(found_key_finder, &keys[1]);
-	TEST_STR(raw_value, "value"); 
-
-	// Test 5:
-	// -- Setup
-	DUMB_KEYFINDER(keys[0], "key", ": ");
-	DUMB_PARSER(parser, keys, 1);
-	strcpy(line, "");
-	found_key_finder = NULL;
-	raw_value = NULL;
-	// -- Run
-	result = match(&parser, line, &found_key_finder, &raw_value);
-	TEST_BOOLEAN(&result, &_false);
-	TEST_PTR(found_key_finder, NULL);
-	TEST_STR(raw_value, NULL); 
+void test_match()
+{
+    printf("==== TEST match() ====\n");
+    // usefull variable :
+    bool _true = true;
+    bool _false = false;
+    KeyFinder keys[10];
+    char line[100];
+    Parser parser;
+    bool result;
+    KeyFinder *found_key_finder = NULL;
+    char *raw_value = NULL;
+
+    // Test 1:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    TEST_BOOLEAN(&result, &_true);
+    TEST_PTR(found_key_finder, &keys[0]);
+    TEST_STR(raw_value, "value");
+
+    // Test 2:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1)
+    strcpy(line, "not a key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
+
+    // Test 3:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0],"key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "key:value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
+
+    // Test 4:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_KEYFINDER(keys[1], "second_key", ": ");
+    DUMB_PARSER(parser, keys, 2);
+    strcpy(line, "second_key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    TEST_BOOLEAN(&result, &_true);
+    TEST_PTR(found_key_finder, &keys[1]);
+    TEST_STR(raw_value, "value");
+
+    // Test 5:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
 }
 
-int main() {
-	test_replace_first();
-	test_split_on_delimiter();
-	test_start_with();
-	test_match();
-	return 0;
+int main()
+{
+    test_replace_first();
+    test_split_on_delimiter();
+    test_start_with();
+    test_match();
+    return 0;
 }
 
 #endif
-- 
GitLab


From 70ab4642ad532768f79a24f02059652c99d38fc5 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 14:27:26 +0000
Subject: [PATCH 044/229] add macros and fix

---
 src/util.c | 27 ++++++++++++++++++++++++---
 src/util.h | 39 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 60 insertions(+), 6 deletions(-)

diff --git a/src/util.c b/src/util.c
index 5ff3acd..93db7f1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1,6 +1,27 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "util.h"
 
-inline uint64_t substractAcc(const uint64_t l, const uint64_t r)
+uint64_t modulo_substraction(uint64_t previous, uint64_t new)
 {
-    return (l < r) ? UINT64_MAX + (l - r) : l - r;
-}
\ No newline at end of file
+    return new > previous ? (previous - new)
+           : (UINT64_MAX - new) + previous;
+}
diff --git a/src/util.h b/src/util.h
index 1fff9af..6d4a644 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,10 +1,43 @@
+/*******************************************************
+ Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #ifndef _UTIL_H
 #define _UTIL_H
 
-//#warning "TODO: Add licence"
-
 #include <stdint.h>
 
-inline uint64_t substractAcc(const uint64_t l, const uint64_t r);
+#define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate,__LINE__,file)
+
+#define _impl_PASTE(a,b) a##b
+#define _impl_CASSERT_LINE(predicate, line, file) \
+    typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
+
+#define UNUSED(expr) do { (void)(expr); } while (0)
+#define PANIC(code, fmt, ...)                \
+    do {                                     \
+        fprintf(stderr, "Exit on error: ");  \
+        fprintf(stderr, fmt, ##__VA_ARGS__); \
+        fprintf(stderr, "\n");               \
+        exit(code);                          \
+    } while (0)
+
+uint64_t modulo_substraction(const uint64_t l, const uint64_t r);
 
 #endif
-- 
GitLab


From a6968e0e1db4392913c4a9313fd1ce3acacc0f33 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 23 Jan 2023 16:25:46 +0100
Subject: [PATCH 045/229] remove useless include generated by
 src/counters_option.sh

(<linux/perf_event.h> is already included in src/counters.c)

plus make it so that it generates a correctly formated code
---
 src/counters_option.sh | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/src/counters_option.sh b/src/counters_option.sh
index 5d1e577..7c99eba 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -5,12 +5,11 @@
 
 linux_include=/usr/include/linux/perf_event.h
 
-echo '#include <linux/perf_event.h>
-
+echo '
 typedef struct counter_option {
-  char *name;
-  __u32 perf_type;
-  __u64 perf_key;
+    char *name;
+    __u32 perf_type;
+    __u64 perf_key;
 } counter_option;
 
 static counter_option perf_static_info[] = {'
@@ -39,7 +38,7 @@ while IFS= read line; do
 		esac
 
 		if [ "$mode" != 'PERF_TYPE_HW_CACHE' ]; then
-			printf '{ .name = "%s", .perf_type = %s, .perf_key = %s},\n' \
+			printf '    { .name = "%s", .perf_type = %s, .perf_key = %s},\n' \
 					"$short_perf" \
 					"$mode" \
 					"$perf_name"
@@ -64,7 +63,7 @@ while IFS= read line; do
                 result_id_str=${result_id% *}
                 result_id_name=${result_id#* }
 
-            	printf '{'
+            	printf '    {'
             	printf ' .name = "%s_%s_%s",' \
             		"$short_perf" \
             		"$op_id_str" \
@@ -85,5 +84,5 @@ done < "$linux_include"
 
 echo '};'
 
-printf 'static unsigned int nb_counter_option = %d;\n' "$nb"
+printf '\nstatic unsigned int nb_counter_option = %d;\n' "$nb"
 
-- 
GitLab


From 202d36be49dd1fbc16352460bbd6e43287a2eeea Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 23 Jan 2023 16:28:50 +0100
Subject: [PATCH 046/229] add basic system detection in configure.sh

---
 configure.sh | 51 +++++++++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 47 insertions(+), 4 deletions(-)

diff --git a/configure.sh b/configure.sh
index 746f129..6a957ff 100755
--- a/configure.sh
+++ b/configure.sh
@@ -4,9 +4,19 @@ try() { "$@" || die "cannot $*"; }
 die() { yell "$*"; exit 111; }
 yell() { echo "$0: $*" >&2; }
 echo() { printf '%s\n' "$*"; }
+isnum() {
+	case "${1#[+-]}" in
+	*[!0-9]*|'') return 1 ;;
+	*) return 0 ;;
+	esac
+}
 
 target=src/captors.h
-hdr_blacklist='counters_option|optparse|captors'
+
+noncaptor='counters_option|optparse|captors'
+
+hdr_blacklist=$noncaptor
+hdr_whitelist=''
 
 usage() {
 	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>]\n' "$(basename "$0")" >&2
@@ -18,7 +28,12 @@ usage() {
 
 ls_captors() {
 	try cd src
-	ls *.h | grep -vE "($hdr_blacklist)" | sed 's/\.h$//'
+	printf -- 'captors:\n' >&2
+	ls -1 *.h |
+		grep -vE "^($hdr_blacklist)\.h$" |
+		grep -E  "^($hdr_whitelist)\.h$" |
+		sed 's/\.h$//' |
+		tee /dev/stderr
 }
 
 gen_captors_h() {
@@ -44,8 +59,8 @@ gen_captors_h() {
 while [ "$1" ]; do
 	case $1 in
 	--include|-i)
-		# no-op for now
-		:
+		shift; [ "$1" ] || usage
+		hdr_whitelist="${hdr_whitelist}|${1}"
 		;;
 	--exclude|-e)
 		shift; [ "$1" ] || usage
@@ -62,4 +77,32 @@ while [ "$1" ]; do
 	shift
 done
 
+[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
+[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
+[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
+
+if [ -r /proc/net/route ]; then
+	dev=$(awk 'NR == 2 { print $1 }' /proc/net/route)
+	[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
+fi
+
+vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
+vendor_lc=$(echo "$vendor" | tr 'A-Z' 'a-z')
+case $vendor_lc in
+*intel*)
+	hdr_whitelist="${hdr_whitelist}|rapl"
+	;;
+*amd*)
+	family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
+	if isnum "$family"; then
+		[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
+	fi
+	;;
+*)
+	yell "unsupported processor vendor id: $vendor"
+	;;
+esac
+
+[ $(ls -1 /sys/class/hwmon | wc -l) -gt 0 ] && hdr_whitelist="${hdr_whitelist}|temperature"
+
 gen_captors_h > "$target"
-- 
GitLab


From 72f4dc47c84f28f93748969be20d8d819c13afd9 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 17:39:34 +0000
Subject: [PATCH 047/229] on test

---
 makefile          |   2 +-
 src/amd_rapl.c    | 114 ++++++++++++++++++++++++++++++----------------
 src/info_reader.c |   6 ++-
 src/util.c        |   6 +--
 4 files changed, 82 insertions(+), 46 deletions(-)

diff --git a/makefile b/makefile
index c43c867..6e47e9e 100644
--- a/makefile
+++ b/makefile
@@ -10,7 +10,7 @@ OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o
 OBJECTS_GRP = $(subst _individual,_group, $(OBJECTS))
 
 CC = gcc
-CFLAGS = -std=gnu99 -O3 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
+CFLAGS = -std=gnu99 -Wall -Wextra -Werror -Wpedantic -Wno-unused-function
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index b83ded9..cb06472 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -53,7 +53,7 @@ struct cpu_sensor_t {
     size_t package_id;
     char *name;
 
-    int *fd;
+    int fd;
     uint64_t energy_units;
     uint64_t core_energy;
     uint64_t pkg_energy;
@@ -141,10 +141,12 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 #ifdef DEBUG
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
-    CASSERT(sizeof(cpu_sensor_t) == 40, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+    CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
+	printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
+		   sensor->name,
+		   sensor->fd,
            sensor->energy_units,
            sensor->core_energy,
            sensor->pkg_energy
@@ -154,21 +156,13 @@ void debug_print_sensor(cpu_sensor_t *sensor)
 void debug_print_amd_rapl(_amd_rapl_t *rapl)
 {
     for (unsigned int i = 0; i < rapl->nb; i++) {
-        debug_print_sensor(rapl->sensors[i]);
+        debug_print_sensor(&rapl->sensors[i]);
     }
 }
 #endif
 
-
-
 // ---------------------------AMD_RAPL_UTIL
 
-uint64_t modulo_substraction(uint64_t previous, u_int64_t new)
-{
-    return new > previous ? (previous - new)
-           : (UINT64_MAX - new) + previous;
-}
-
 unsigned int get_nb_cpu()
 {
     char filename[BUFFER_SIZE];
@@ -186,9 +180,16 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
+char* get_name(size_t cpu_id) {
+    static const char *base_name = "core%ld";
+	size_t memory_needed = snprintf(NULL, 0, base_name, cpu_id);
+	char* name = (char *)calloc(memory_needed, sizeof(char));
+	snprintf(name, memory_needed, base_name, cpu_id);
+	return name;
+}
+
 void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
 {
-    static const char *base_name = "core%ld";
     static char filename[BUFFER_SIZE];
     sprintf(filename, base_str, cpu_id);
 
@@ -202,7 +203,8 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
     u_int64_t raw_pkg_energy = read_raw_pkg_energy(fd);
 
     sensor->cpu_id = cpu_id;
-    asprintf(sensor->name, base_name, sensor->cpu_id);
+	sensor->name = get_name(cpu_id);
+	sensor->fd = fd;
     sensor->energy_units = read_unit(fd);
     sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
     sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
@@ -211,9 +213,9 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
 u_int64_t get_core_energy(cpu_sensor_t *sensor)
 {
     u_int64_t raw_core_energy = read_raw_core_energy(sensor->fd);
-    u_int64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units)
+    u_int64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
 
-                            u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
+	u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
     sensor->core_energy = core_energy;
     return energy_consumed;
 }
@@ -221,13 +223,18 @@ u_int64_t get_core_energy(cpu_sensor_t *sensor)
 u_int64_t get_pkg_energy(cpu_sensor_t *sensor)
 {
     u_int64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
-    u_int64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units)
-
-                           u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
+    u_int64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
+	
+	u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
     sensor->pkg_energy = pkg_energy;
     return energy_consumed;
 }
 
+void clean_cpu_sensor(cpu_sensor_t* sensor) {
+	close(sensor->fd);
+	free(sensor->name);
+}
+
 // ----------------------AMD_RAPL_INTERFACE
 
 
@@ -273,7 +280,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    cpu_sensor_tr *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
+    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
 
     rapl->nb = nb_cpu;
     rapl->sensors = cpus;
@@ -281,43 +288,70 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     for (unsigned int i = 0; i < nb_cpu; i++) {
         init_cpu_sensor(&rapl->sensors[i], i);
     }
+
+	*ptr = (void*) rapl;
     return rapl->nb;
 }
 
 
-unsigned int get_amd_rapl(uint64_t results, void *ptr)
+unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t) ptr;
+    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
     for (unsigned int i = 0; i < rapl->nb; i++) {
         // TODO: check if unit is the same
 #warning "check if unit is the same"
-        results[i] = get_core_energy(rapl->sensors[i]);
+        results[i] = get_core_energy(&rapl->sensors[i]);
     }
     return rapl->nb;
 }
 
+void label_amd_rapl(char **labels, void* ptr) {
+	_amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    for (unsigned int i = 0; i < rapl->nb; i++) {
+         labels[i] = rapl->sensors[i].name;
+    }
+}
+
+void clean_amd_rapl(void *ptr) {
+	_amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+
+	for (unsigned int i = 0; i < rapl->nb; ++i) {
+		clean_cpu_sensor(&rapl->sensors[i]);
+	}
+	free(rapl->sensors);
+	free(rapl);
+}
 
 
 
 int main()
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *)malloc(sizeof(_amd_rapl_t));
-    init_amd_rapl(rapl);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-    sleep(1);
-    print_amd_rapl(rapl);
-
-    free_amd_rapl(rapl);
+	static const unsigned int time = 10;
+	_amd_rapl_t *rapl = NULL;
+    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
+	uint64_t results[nb_cpu];
+	char* labels[nb_cpu];
+
+	label_amd_rapl(labels, (void *) rapl);
+
+	for (unsigned int i = 0; i < rapl->nb; ++i) {
+		printf("%s ", labels[i]);
+	}
+	printf("\n");
+
+	// -- Run
+
+	for (unsigned int i = 0; i < time; ++i) {
+		sleep(1);
+		get_amd_rapl(results, (void*)rapl);
+
+		for (unsigned int j = 0; j < rapl->nb; ++j) {
+			printf("%ln ", results);
+		}
+		printf("\n");
+	}
+
+	clean_amd_rapl(rapl);
     return 0;
 }
 
diff --git a/src/info_reader.c b/src/info_reader.c
index e2563c6..19d84de 100644
--- a/src/info_reader.c
+++ b/src/info_reader.c
@@ -64,10 +64,12 @@ struct cpu_sensor_t {
 #warning "Check the reset of the msr registers"
     size_t cpu_id;
     size_t package_id;
+    char *name;
 
+    int *fd;
     uint64_t energy_units;
-    uint64_t core_energy_status;
-    uint64_t pkg_energy_status;
+    uint64_t core_energy;
+    uint64_t pkg_energy;
 };
 
 int main(int argc, char const *argv[])
diff --git a/src/util.c b/src/util.c
index 186434b..fe3efa1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -20,8 +20,8 @@
 
 #include "util.h"
 
-uint64_t modulo_substraction(uint64_t previous, u_int64_t new)
+uint64_t modulo_substraction(uint64_t previous, uint64_t new)
 {
-    return new > previous ? (previous - new)
-           : (UINT64_MAX - new) + previous;
+    return new > previous ? (new - previous)
+           : (UINT64_MAX - previous) + new;
 }
-- 
GitLab


From 0e4a69d26e8f33cc9caf44fe52405b27353208d5 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 23 Jan 2023 17:40:59 +0000
Subject: [PATCH 048/229] fix: util.c

---
 src/util.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/util.c b/src/util.c
index 93db7f1..fe3efa1 100644
--- a/src/util.c
+++ b/src/util.c
@@ -22,6 +22,6 @@
 
 uint64_t modulo_substraction(uint64_t previous, uint64_t new)
 {
-    return new > previous ? (previous - new)
-           : (UINT64_MAX - new) + previous;
+    return new > previous ? (new - previous)
+           : (UINT64_MAX - previous) + new;
 }
-- 
GitLab


From 28b96095c1c5aa814fcb89ac261c68eee5f103e0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 09:56:37 +0000
Subject: [PATCH 049/229] separate test lib

---
 src/info_reader.h | 102 ++-------------------------------------
 src/small_test.h  | 119 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 124 insertions(+), 97 deletions(-)
 create mode 100644 src/small_test.h

diff --git a/src/info_reader.h b/src/info_reader.h
index 4717841..40948bd 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -226,99 +226,7 @@ static bool start_with(const char *prefix, const char *string)
 
 
 #ifdef __TESTING__
-
-#define FMT_NULL(string) \
-	string = string ? string : "NULL"
-
-#define TEST_STR(result, expected) \
-	test_str(__FILE__, __LINE__, result, expected)
-
-#define TEST_BOOLEAN(result, expected) \
-	test_boolean(__FILE__, __LINE__, result, expected)
-
-#define TEST_PTR(result, expected) \
-	test_ptr(__FILE__, __LINE__, result, expected)
-
-typedef int (Comparator) (void *, void *);
-typedef char *(Formatter) (char *, void *);
-
-int string_compare(char *string1, char *string2)
-{
-    if (string1 == NULL && string2 == NULL) {
-        return 1;
-    } else if (string1 == NULL || string2 == NULL) {
-        return 0;
-    } else {
-        return (strcmp(string1, string2) == 0);
-    }
-}
-
-char *string_format(__attribute__((unused)) char *buffer, char *string)
-{
-    return FMT_NULL(string);
-}
-
-
-int boolean_compare(bool *boolean1, bool *boolean2)
-{
-    return *boolean1 == *boolean2;
-}
-
-char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
-{
-    return *boolean ? "True" : "False";
-}
-
-int ptr_compare(void *ptr1, void *ptr2)
-{
-    return ptr1 == ptr2;
-}
-
-char *ptr_format(char *buffer, void *ptr)
-{
-    sprintf(buffer, "%p", ptr);
-    return buffer;
-}
-
-void test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
-{
-    static char buffer_result[1000];
-    static char buffer_expected[1000];
-    if (compare(result, expected) == 0) {
-        printf("Test %s:%d failed: expected %s, got %s\n",
-               file,
-               line,
-               format(buffer_result, expected),
-               format(buffer_expected, result)
-              );
-    } else {
-        printf("Test %s:%d passed\n", file, line);
-    }
-}
-
-void test_str(char *file, int line, char *result, char *expected)
-{
-    Comparator *compare = (Comparator *) string_compare;
-    Formatter *format = (Formatter *) string_format;
-
-    test(file, line, result, expected, compare, format);
-}
-
-void test_boolean(char *file, int line, bool *result, bool *expected)
-{
-    Comparator *compare = (Comparator *) boolean_compare;
-    Formatter *format = (Formatter *) boolean_format;
-
-    test(file, line, (void *) result, (void *) expected, compare, format);
-}
-
-void test_ptr(char *file, int line, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) ptr_compare;
-    Formatter *format = (Formatter *) ptr_format;
-
-    test(file, line, result, expected, compare, format);
-}
+#include "small_test.h"
 
 void test_replace_first()
 {
@@ -414,21 +322,21 @@ void test_start_with()
 		key_finder = (KeyFinder) {					\
 			key,									\
 			delimiter,								\
-			NULL,									\
-			NULL									\
+			0,										\
+			0										\
 		}; 											\
 	} while (0);
 
 #define DUMB_PARSER(parser, keys, nb_keys)  \
 	do {									\
 		parser = (Parser) {					\
-			NULL,		   					\
+			0,			   					\
 			0,			   					\
 			0,			   					\
 			0,  							\
 			keys,			   				\
 			nb_keys, 		   				\
-			NULL							\
+			0								\
 		};							   		\
 	} while (0);
 
diff --git a/src/small_test.h b/src/small_test.h
new file mode 100644
index 0000000..a63cca8
--- /dev/null
+++ b/src/small_test.h
@@ -0,0 +1,119 @@
+#ifndef __SMALL_TEST_H
+#define __SMALL_TEST_H 
+
+#define FMT_NULL(string) \
+	string = string ? string : "NULL"
+
+#define TEST_STR(result, expected) \
+	test_str(__FILE__, __LINE__, result, expected)
+
+#define TEST_BOOLEAN(result, expected) \
+	test_boolean(__FILE__, __LINE__, result, expected)
+
+#define TEST_PTR(result, expected) \
+	test_ptr(__FILE__, __LINE__, result, expected)
+
+#define TEST_UINT64_T(result, expected) \
+	test_uint64_t(__FILE__, __LINE__, result, expected)
+
+typedef int (Comparator) (void *, void *);
+typedef char *(Formatter) (char *, void *);
+
+int string_compare(char *string1, char *string2)
+{
+    if (string1 == NULL && string2 == NULL) {
+        return 1;
+    } else if (string1 == NULL || string2 == NULL) {
+        return 0;
+    } else {
+        return (strcmp(string1, string2) == 0);
+    }
+}
+
+char *string_format(__attribute__((unused)) char *buffer, char *string)
+{
+    return FMT_NULL(string);
+}
+
+
+int boolean_compare(bool *boolean1, bool *boolean2)
+{
+    return *boolean1 == *boolean2;
+}
+
+char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
+{
+    return *boolean ? "True" : "False";
+}
+
+int ptr_compare(void *ptr1, void *ptr2)
+{
+    return ptr1 == ptr2;
+}
+
+char *ptr_format(char *buffer, void *ptr)
+{
+    sprintf(buffer, "%p", ptr);
+    return buffer;
+}
+
+
+int uint64_t_compare(uint64_t *value1, uint64_t *value2)
+{
+    return *value1 == *value2;
+}
+
+char *uint64_t_format(char *buffer, uint64_t *value)
+{
+    sprintf(buffer, "%ld", *value);
+    return buffer;
+}
+
+void test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+{
+    static char buffer_result[1000];
+    static char buffer_expected[1000];
+    if (compare(result, expected) == 0) {
+        printf("Test %s:%d failed: expected %s, got %s\n",
+               file,
+               line,
+               format(buffer_result, expected),
+               format(buffer_expected, result)
+              );
+    } else {
+        printf("Test %s:%d passed\n", file, line);
+    }
+}
+
+void test_str(char *file, int line, char *result, char *expected)
+{
+    Comparator *compare = (Comparator *) string_compare;
+    Formatter *format = (Formatter *) string_format;
+
+    test(file, line, result, expected, compare, format);
+}
+
+void test_boolean(char *file, int line, bool *result, bool *expected)
+{
+    Comparator *compare = (Comparator *) boolean_compare;
+    Formatter *format = (Formatter *) boolean_format;
+
+    test(file, line, (void *) result, (void *) expected, compare, format);
+}
+
+void test_ptr(char *file, int line, void *result, void *expected)
+{
+    Comparator *compare = (Comparator *) ptr_compare;
+    Formatter *format = (Formatter *) ptr_format;
+
+    test(file, line, result, expected, compare, format);
+}
+
+void test_uint64_t(char *file, int line, void *result, void *expected)
+{
+    Comparator *compare = (Comparator *) uint64_t_compare;
+    Formatter *format = (Formatter *) uint64_t_format;
+
+    test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
+}
+#endif
-- 
GitLab


From 56d5175173c643446298bb199b6bb2f1e8315056 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 09:56:57 +0000
Subject: [PATCH 050/229] building tests

---
 src/amd_rapl.c | 192 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 139 insertions(+), 53 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index cb06472..9bdfbed 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -44,7 +44,6 @@ static const uint64_t energy_pkg_msr = 0xC001029B;
 
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
-static const char *cpuinfo = "/proc/cpuinfo";
 
 struct cpu_sensor_t {
     //TODO: check the reset of the msr registers
@@ -68,6 +67,8 @@ typedef struct _amd_rapl_t _amd_rapl_t;
 
 // -----------------------------INFO_READER
 
+#ifdef __READ_CPUINFO__
+static const char *cpuinfo = "/proc/cpuinfo";
 static GenericPointer _size_t_allocator(char *s)
 {
     size_t value = atoi(s);
@@ -90,6 +91,7 @@ static KeyFinder keys[NB_KEYS] = {
     {"processor", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_cpu_id},
     {"physical id", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_package_id}
 };
+#endif
 
 // --------------------------------READ_MSR
 
@@ -107,7 +109,7 @@ uint64_t read_msr(int fd, uint64_t msr)
 uint64_t read_unit(int fd)
 {
     u_int64_t unit = read_msr(fd, msr_rapl_power_unit);
-    return (unit & amd_energy_unit_mask) >> 8;
+    return ((unit & amd_energy_unit_mask) >> 8);
 }
 
 uint64_t read_raw_core_energy(int fd)
@@ -126,14 +128,17 @@ uint64_t read_raw_pkg_energy(int fd)
 
 uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
 {
+	static const uint64_t to_microjoule = 1000000UL;
     // raw * (1 / (unit^2)) -> Joule
-    // Joule * 1000000 -> microjoule
-    return (raw * 1000000UL) / (1ul << unit);
+    // Joule * 1000000 -> uJoule
+	uint64_t microjoule = (raw * to_microjoule) / (1UL << unit);
+	return microjoule;
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
-    // raw * (1 / (unit^2)) -> Joule
-    return raw / (1ul << unit);
+	// raw * (1 / (unit^2)) -> Joule
+	int64_t joule = raw / (1UL << unit);
+	return joule;
 }
 
 // -----------------------------------DEBUG
@@ -141,12 +146,12 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 #ifdef DEBUG
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
-    CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-	printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+    //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
+    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
-		   sensor->name,
-		   sensor->fd,
+           sensor->name,
+           sensor->fd,
            sensor->energy_units,
            sensor->core_energy,
            sensor->pkg_energy
@@ -159,6 +164,21 @@ void debug_print_amd_rapl(_amd_rapl_t *rapl)
         debug_print_sensor(&rapl->sensors[i]);
     }
 }
+
+// typedef struct {
+//     size_t cpu_id;
+//     uint64_t *results;
+//     size_t capacity;
+// } CpuLogger;
+// 
+// CpuLogger init_logger(size_t cpu_id, size_t capacity)
+// {
+// 
+// }
+// 
+// void log_value();
+
+
 #endif
 
 // ---------------------------AMD_RAPL_UTIL
@@ -180,12 +200,13 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-char* get_name(size_t cpu_id) {
+char *get_name(size_t cpu_id)
+{
     static const char *base_name = "core%ld";
-	size_t memory_needed = snprintf(NULL, 0, base_name, cpu_id);
-	char* name = (char *)calloc(memory_needed, sizeof(char));
-	snprintf(name, memory_needed, base_name, cpu_id);
-	return name;
+    static const size_t max_lenght = 20;
+    char *name = (char *)calloc(max_lenght, sizeof(char));
+    snprintf(name, max_lenght, base_name, cpu_id);
+    return name;
 }
 
 void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
@@ -203,8 +224,8 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
     u_int64_t raw_pkg_energy = read_raw_pkg_energy(fd);
 
     sensor->cpu_id = cpu_id;
-	sensor->name = get_name(cpu_id);
-	sensor->fd = fd;
+    sensor->name = get_name(cpu_id);
+    sensor->fd = fd;
     sensor->energy_units = read_unit(fd);
     sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
     sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
@@ -215,7 +236,7 @@ u_int64_t get_core_energy(cpu_sensor_t *sensor)
     u_int64_t raw_core_energy = read_raw_core_energy(sensor->fd);
     u_int64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
 
-	u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
+    u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
     sensor->core_energy = core_energy;
     return energy_consumed;
 }
@@ -224,15 +245,16 @@ u_int64_t get_pkg_energy(cpu_sensor_t *sensor)
 {
     u_int64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
     u_int64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-	
-	u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
+
+    u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
     sensor->pkg_energy = pkg_energy;
     return energy_consumed;
 }
 
-void clean_cpu_sensor(cpu_sensor_t* sensor) {
-	close(sensor->fd);
-	free(sensor->name);
+void clean_cpu_sensor(cpu_sensor_t *sensor)
+{
+    close(sensor->fd);
+    free(sensor->name);
 }
 
 // ----------------------AMD_RAPL_INTERFACE
@@ -289,7 +311,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         init_cpu_sensor(&rapl->sensors[i], i);
     }
 
-	*ptr = (void*) rapl;
+    *ptr = (void *) rapl;
     return rapl->nb;
 }
 
@@ -305,53 +327,117 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
     return rapl->nb;
 }
 
-void label_amd_rapl(char **labels, void* ptr) {
-	_amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+void label_amd_rapl(char **labels, void *ptr)
+{
+    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
     for (unsigned int i = 0; i < rapl->nb; i++) {
-         labels[i] = rapl->sensors[i].name;
+        labels[i] = rapl->sensors[i].name;
     }
 }
 
-void clean_amd_rapl(void *ptr) {
-	_amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+void clean_amd_rapl(void *ptr)
+{
+    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
 
-	for (unsigned int i = 0; i < rapl->nb; ++i) {
-		clean_cpu_sensor(&rapl->sensors[i]);
-	}
-	free(rapl->sensors);
-	free(rapl);
+    for (unsigned int i = 0; i < rapl->nb; ++i) {
+        clean_cpu_sensor(&rapl->sensors[i]);
+    }
+    free(rapl->sensors);
+    free(rapl);
 }
 
 
+#ifdef __TESTING_AMD__
+#include "small_test.h"
+
+void test_raw_to_microjoule() {
+	printf("==== TEST raw_to_microjoule() ====\n");
+	uint64_t raw = 0;
+	uint64_t unit = 0;
+	uint64_t result = 0;
+	uint64_t expected = 0;
+	
+	// Test 1:
+	// -- Setup
+	raw = 100;
+	unit = 0;
+	expected = 100000000;
+	// -- Run
+	result = raw_to_microjoule(raw, unit);
+	// -- Verification
+	TEST_UINT64_T(&result, &expected);
+	
+	// TEST 2:
+	// -- Setup
+	raw = 200;
+	unit = 1;
+	expected = 100000000;
+	// -- Run
+	result = raw_to_microjoule(raw, unit);
+	// -- Verification
+	TEST_UINT64_T(&result, &expected);
+
+	// TEST 3:
+	// -- Setup
+	raw = 500;
+	unit = 2;
+	expected = 125000000;
+	// -- Run
+	result = raw_to_microjoule(raw, unit);
+	// -- Verification
+	TEST_UINT64_T(&result, &expected);
+
+	// TEST 4:
+	// -- Setup
+	raw = 1000;
+	unit = 3;
+	expected = 125000000;
+	// -- Run
+	result = raw_to_microjoule(raw, unit);
+	// -- Verification
+	TEST_UINT64_T(&result, &expected);
+	
+	// TEST 5:
+	// -- Setup
+	raw = 10000;
+	unit = 4;
+	expected = 625000000;
+	// -- Run
+	result = raw_to_microjoule(raw, unit);
+	// -- Verification
+	TEST_UINT64_T(&result, &expected);
+}
 
 int main()
 {
-	static const unsigned int time = 10;
-	_amd_rapl_t *rapl = NULL;
+	test_raw_to_microjoule();
+    static const unsigned int time = 10;
+    _amd_rapl_t *rapl = NULL;
     unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-	uint64_t results[nb_cpu];
-	char* labels[nb_cpu];
+    uint64_t results[nb_cpu];
+    char *labels[nb_cpu];
 
-	label_amd_rapl(labels, (void *) rapl);
+    label_amd_rapl(labels, (void *) rapl);
 
-	for (unsigned int i = 0; i < rapl->nb; ++i) {
-		printf("%s ", labels[i]);
-	}
-	printf("\n");
+    for (unsigned int i = 0; i < rapl->nb; ++i) {
+        printf("%s ", labels[i]);
+    }
+    printf("\n");
 
-	// -- Run
+    // -- Run
 
-	for (unsigned int i = 0; i < time; ++i) {
-		sleep(1);
-		get_amd_rapl(results, (void*)rapl);
+    for (unsigned int i = 0; i < time; ++i) {
+        sleep(1);
+        get_amd_rapl(results, (void *)rapl);
 
-		for (unsigned int j = 0; j < rapl->nb; ++j) {
-			printf("%ln ", results);
-		}
-		printf("\n");
-	}
+        for (unsigned int j = 0; j < rapl->nb; ++j) {
+            printf("%ld ", results[j]);
+        }
+        printf("\n");
+    }
 
-	clean_amd_rapl(rapl);
+    clean_amd_rapl(rapl);
     return 0;
 }
 
+#endif
-- 
GitLab


From 6f7fa2eab376fe5625bf43906822bb5ba9543a29 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 12:13:51 +0000
Subject: [PATCH 051/229] add tests

---
 src/amd_rapl.c   | 117 +++++++++++++++++++++++++++++++++++++++++++++--
 src/small_test.h |   5 ++
 2 files changed, 117 insertions(+), 5 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 9bdfbed..4877825 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -30,10 +30,7 @@
 #include "util.h"
 #include "amd_rapl.h"
 
-#warning "Must be modified before release"
 #define BUFFER_SIZE 64
-#define MAX_CPUS 64
-#define NB_KEYS 2
 
 // ---------------------------MSR_REGISTERS
 static const uint64_t amd_energy_mask = 0xFFFFFFFF;
@@ -46,8 +43,6 @@ static const uint64_t energy_pkg_msr = 0xC001029B;
 static const char *base_str = "/dev/cpu/%d/msr";
 
 struct cpu_sensor_t {
-    //TODO: check the reset of the msr registers
-#warning "Check the reset of the msr registers"
     size_t cpu_id;
     size_t package_id;
     char *name;
@@ -68,6 +63,11 @@ typedef struct _amd_rapl_t _amd_rapl_t;
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
+
+#warning "Must be modified before release"
+#define MAX_CPUS 64
+#define NB_KEYS 2
+
 static const char *cpuinfo = "/proc/cpuinfo";
 static GenericPointer _size_t_allocator(char *s)
 {
@@ -408,9 +408,116 @@ void test_raw_to_microjoule() {
 	TEST_UINT64_T(&result, &expected);
 }
 
+void test_get_name() {
+	printf("==== TEST get_name() ====\n");
+	size_t cpu_id = 0;
+	char* result = NULL;
+	char expected[100];
+
+	// TEST 1:
+	// -- Setup
+	cpu_id = 0;
+	strcpy(expected, "core0");
+	// -- Run
+	result = get_name(cpu_id);
+	// -- Verification
+	TEST_STR(result, expected);
+	free(result);
+
+	// TEST 2:
+	// -- Setup
+	cpu_id = 10000;
+	strcpy(expected, "core10000");
+	// -- Run
+	result = get_name(cpu_id);
+	// -- Verification
+	TEST_STR(result, expected);
+	free(result);
+}
+
+#define NONE 0
+#define DUMB_SENSOR(sensor, cpu_id, name)	\
+	do {									\
+		sensor = (cpu_sensor_t) {			\
+			cpu_id,							\
+			NONE,							\
+			name,							\
+			NONE,							\
+			NONE,							\
+			NONE, 							\
+			NONE							\
+		}; 									\
+	} while(0);
+
+#define DUMB_RAPL(rapl, sensors, nb)		\
+	do {									\
+		rapl = (_amd_rapl_t) {				\
+			sensors,						\
+			nb								\
+		};									\
+	} while(0);
+
+void test_label_amd_rapl() {
+	printf("==== TEST label_amd_rapl() ====\n");
+	cpu_sensor_t sensors[100];
+	_amd_rapl_t rapl;
+	char *results[100];
+	char expecteds[10][100];
+	uint64_t nb = 0;
+
+	// Test 1:
+	// -- Setup
+	nb = 1;
+	DUMB_SENSOR(sensors[0], 0, "core0"); 
+	DUMB_RAPL(rapl, sensors, nb);
+	strcpy(expecteds[0], "core0");
+	// -- Run
+	label_amd_rapl(results, (void*) &rapl);
+	// -- Verification
+	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+
+	// Test 2:
+	// -- Setup
+	nb = 4;
+	DUMB_SENSOR(sensors[0], 0, "core0"); 
+	DUMB_SENSOR(sensors[1], 1, "core1"); 
+	DUMB_SENSOR(sensors[2], 2, "core2"); 
+	DUMB_SENSOR(sensors[3], 3, "core3"); 
+	DUMB_RAPL(rapl, sensors, nb);
+	strcpy(expecteds[0], "core0");
+	strcpy(expecteds[1], "core1");
+	strcpy(expecteds[2], "core2");
+	strcpy(expecteds[3], "core3");
+	// -- Run
+	label_amd_rapl(results, (void*) &rapl);
+	// -- Verification
+	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+	
+	// Test 3:
+	// -- Setup
+	nb = 4;
+	DUMB_SENSOR(sensors[0], 0, "core0"); 
+	DUMB_SENSOR(sensors[1], 3, "core3"); 
+	DUMB_SENSOR(sensors[2], 1, "core1"); 
+	DUMB_SENSOR(sensors[3], 2, "core2"); 
+	DUMB_RAPL(rapl, sensors, nb);
+	strcpy(expecteds[0], "core0");
+	strcpy(expecteds[1], "core3");
+	strcpy(expecteds[2], "core1");
+	strcpy(expecteds[3], "core2");
+	// -- Run
+	label_amd_rapl(results, (void*) &rapl);
+	// -- Verification
+	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+}
+
+
 int main()
 {
 	test_raw_to_microjoule();
+	test_get_name();
+	test_label_amd_rapl();
+
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
     unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
diff --git a/src/small_test.h b/src/small_test.h
index a63cca8..b8673dd 100644
--- a/src/small_test.h
+++ b/src/small_test.h
@@ -16,6 +16,11 @@
 #define TEST_UINT64_T(result, expected) \
 	test_uint64_t(__FILE__, __LINE__, result, expected)
 
+#define TEST_T_ARRAY(function, size, results, expecteds)	\
+	for (unsigned int i = 0; i < size; i++) {				\
+		function(results[i], expecteds[i]);					\
+	}
+
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
 
-- 
GitLab


From 79214a8bf2356abb3ca5996c01ae5775999704e2 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 13:11:53 +0000
Subject: [PATCH 052/229] add make tests

---
 .gitignore                                    |   1 +
 makefile                                      |  10 +-
 src/amd_rapl.c                                | 293 +++++++++---------
 src/info_reader.h                             | 211 -------------
 tests/amd_rapl.c                              | 220 +++++++++++++
 .../example_info_reader.c                     |   2 +-
 tests/info_reader.c                           | 233 ++++++++++++++
 tests/main.c                                  |  13 +
 {src => tests}/small_test.h                   |  36 ++-
 9 files changed, 647 insertions(+), 372 deletions(-)
 create mode 100644 tests/amd_rapl.c
 rename src/info_reader.c => tests/example_info_reader.c (98%)
 create mode 100644 tests/info_reader.c
 create mode 100644 tests/main.c
 rename {src => tests}/small_test.h (69%)

diff --git a/.gitignore b/.gitignore
index 5a8f74f..ca55d73 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,5 @@
 *.o
 src/counters_option.h
+tests/tests
 bin
 obj
diff --git a/makefile b/makefile
index 6e47e9e..15503a9 100644
--- a/makefile
+++ b/makefile
@@ -1,9 +1,10 @@
-.PHONY: all clean mojitos mojitos_group debug format
+.PHONY: all clean mojitos mojitos_group debug format tests
 
 SRC_DIR = src
 DOC_DIR = doc
 OBJ_DIR = obj
 BIN_DIR = bin
+TESTS_DIR = tests
 
 
 OBJECTS = $(addprefix $(OBJ_DIR)/, mojitos.o counters.o rapl.o network.o load.o infiniband.o temperature.o util.o)
@@ -42,10 +43,17 @@ $(BIN_DIR):
 debug: CFLAGS += -DDEBUG -g
 debug: all
 
+tests: 	
+	gcc -Wall -Wextra -Wpedantic $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/tests
+	$(TESTS_DIR)/tests
+
 format:
 	$(ASTYLE) $(SRC_DIR)/*.c $(SRC_DIR)/*.h
 	$(ASTYLE) $(DOC_DIR)/*.c $(DOC_DIR)/*.h
+	$(ASTYLE) $(TESTS_DIR)/*.c $(TESTS_DIR)/*.h
+
 
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
 	\rm -f $(SRC_DIR)/counters_option.h
+	\rm $(TESTS_DIR)/tests
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 4877825..91b6009 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -128,17 +128,17 @@ uint64_t read_raw_pkg_energy(int fd)
 
 uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
 {
-	static const uint64_t to_microjoule = 1000000UL;
+    static const uint64_t to_microjoule = 1000000UL;
     // raw * (1 / (unit^2)) -> Joule
     // Joule * 1000000 -> uJoule
-	uint64_t microjoule = (raw * to_microjoule) / (1UL << unit);
-	return microjoule;
+    uint64_t microjoule = (raw * to_microjoule) / (1UL << unit);
+    return microjoule;
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
-	// raw * (1 / (unit^2)) -> Joule
-	int64_t joule = raw / (1UL << unit);
-	return joule;
+    // raw * (1 / (unit^2)) -> Joule
+    int64_t joule = raw / (1UL << unit);
+    return joule;
 }
 
 // -----------------------------------DEBUG
@@ -170,12 +170,12 @@ void debug_print_amd_rapl(_amd_rapl_t *rapl)
 //     uint64_t *results;
 //     size_t capacity;
 // } CpuLogger;
-// 
+//
 // CpuLogger init_logger(size_t cpu_id, size_t capacity)
 // {
-// 
+//
 // }
-// 
+//
 // void log_value();
 
 
@@ -350,89 +350,91 @@ void clean_amd_rapl(void *ptr)
 #ifdef __TESTING_AMD__
 #include "small_test.h"
 
-void test_raw_to_microjoule() {
-	printf("==== TEST raw_to_microjoule() ====\n");
-	uint64_t raw = 0;
-	uint64_t unit = 0;
-	uint64_t result = 0;
-	uint64_t expected = 0;
-	
-	// Test 1:
-	// -- Setup
-	raw = 100;
-	unit = 0;
-	expected = 100000000;
-	// -- Run
-	result = raw_to_microjoule(raw, unit);
-	// -- Verification
-	TEST_UINT64_T(&result, &expected);
-	
-	// TEST 2:
-	// -- Setup
-	raw = 200;
-	unit = 1;
-	expected = 100000000;
-	// -- Run
-	result = raw_to_microjoule(raw, unit);
-	// -- Verification
-	TEST_UINT64_T(&result, &expected);
-
-	// TEST 3:
-	// -- Setup
-	raw = 500;
-	unit = 2;
-	expected = 125000000;
-	// -- Run
-	result = raw_to_microjoule(raw, unit);
-	// -- Verification
-	TEST_UINT64_T(&result, &expected);
-
-	// TEST 4:
-	// -- Setup
-	raw = 1000;
-	unit = 3;
-	expected = 125000000;
-	// -- Run
-	result = raw_to_microjoule(raw, unit);
-	// -- Verification
-	TEST_UINT64_T(&result, &expected);
-	
-	// TEST 5:
-	// -- Setup
-	raw = 10000;
-	unit = 4;
-	expected = 625000000;
-	// -- Run
-	result = raw_to_microjoule(raw, unit);
-	// -- Verification
-	TEST_UINT64_T(&result, &expected);
+void test_raw_to_microjoule()
+{
+    printf("==== TEST raw_to_microjoule() ====\n");
+    uint64_t raw = 0;
+    uint64_t unit = 0;
+    uint64_t result = 0;
+    uint64_t expected = 0;
+
+    // Test 1:
+    // -- Setup
+    raw = 100;
+    unit = 0;
+    expected = 100000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+
+    // TEST 2:
+    // -- Setup
+    raw = 200;
+    unit = 1;
+    expected = 100000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+
+    // TEST 3:
+    // -- Setup
+    raw = 500;
+    unit = 2;
+    expected = 125000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+
+    // TEST 4:
+    // -- Setup
+    raw = 1000;
+    unit = 3;
+    expected = 125000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+
+    // TEST 5:
+    // -- Setup
+    raw = 10000;
+    unit = 4;
+    expected = 625000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
 }
 
-void test_get_name() {
-	printf("==== TEST get_name() ====\n");
-	size_t cpu_id = 0;
-	char* result = NULL;
-	char expected[100];
-
-	// TEST 1:
-	// -- Setup
-	cpu_id = 0;
-	strcpy(expected, "core0");
-	// -- Run
-	result = get_name(cpu_id);
-	// -- Verification
-	TEST_STR(result, expected);
-	free(result);
-
-	// TEST 2:
-	// -- Setup
-	cpu_id = 10000;
-	strcpy(expected, "core10000");
-	// -- Run
-	result = get_name(cpu_id);
-	// -- Verification
-	TEST_STR(result, expected);
-	free(result);
+void test_get_name()
+{
+    printf("==== TEST get_name() ====\n");
+    size_t cpu_id = 0;
+    char *result = NULL;
+    char expected[100];
+
+    // TEST 1:
+    // -- Setup
+    cpu_id = 0;
+    strcpy(expected, "core0");
+    // -- Run
+    result = get_name(cpu_id);
+    // -- Verification
+    TEST_STR(result, expected);
+    free(result);
+
+    // TEST 2:
+    // -- Setup
+    cpu_id = 10000;
+    strcpy(expected, "core10000");
+    // -- Run
+    result = get_name(cpu_id);
+    // -- Verification
+    TEST_STR(result, expected);
+    free(result);
 }
 
 #define NONE 0
@@ -457,66 +459,67 @@ void test_get_name() {
 		};									\
 	} while(0);
 
-void test_label_amd_rapl() {
-	printf("==== TEST label_amd_rapl() ====\n");
-	cpu_sensor_t sensors[100];
-	_amd_rapl_t rapl;
-	char *results[100];
-	char expecteds[10][100];
-	uint64_t nb = 0;
-
-	// Test 1:
-	// -- Setup
-	nb = 1;
-	DUMB_SENSOR(sensors[0], 0, "core0"); 
-	DUMB_RAPL(rapl, sensors, nb);
-	strcpy(expecteds[0], "core0");
-	// -- Run
-	label_amd_rapl(results, (void*) &rapl);
-	// -- Verification
-	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
-
-	// Test 2:
-	// -- Setup
-	nb = 4;
-	DUMB_SENSOR(sensors[0], 0, "core0"); 
-	DUMB_SENSOR(sensors[1], 1, "core1"); 
-	DUMB_SENSOR(sensors[2], 2, "core2"); 
-	DUMB_SENSOR(sensors[3], 3, "core3"); 
-	DUMB_RAPL(rapl, sensors, nb);
-	strcpy(expecteds[0], "core0");
-	strcpy(expecteds[1], "core1");
-	strcpy(expecteds[2], "core2");
-	strcpy(expecteds[3], "core3");
-	// -- Run
-	label_amd_rapl(results, (void*) &rapl);
-	// -- Verification
-	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
-	
-	// Test 3:
-	// -- Setup
-	nb = 4;
-	DUMB_SENSOR(sensors[0], 0, "core0"); 
-	DUMB_SENSOR(sensors[1], 3, "core3"); 
-	DUMB_SENSOR(sensors[2], 1, "core1"); 
-	DUMB_SENSOR(sensors[3], 2, "core2"); 
-	DUMB_RAPL(rapl, sensors, nb);
-	strcpy(expecteds[0], "core0");
-	strcpy(expecteds[1], "core3");
-	strcpy(expecteds[2], "core1");
-	strcpy(expecteds[3], "core2");
-	// -- Run
-	label_amd_rapl(results, (void*) &rapl);
-	// -- Verification
-	TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+void test_label_amd_rapl()
+{
+    printf("==== TEST label_amd_rapl() ====\n");
+    cpu_sensor_t sensors[100];
+    _amd_rapl_t rapl;
+    char *results[100];
+    char expecteds[10][100];
+    uint64_t nb = 0;
+
+    // Test 1:
+    // -- Setup
+    nb = 1;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+
+    // Test 2:
+    // -- Setup
+    nb = 4;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_SENSOR(sensors[1], 1, "core1");
+    DUMB_SENSOR(sensors[2], 2, "core2");
+    DUMB_SENSOR(sensors[3], 3, "core3");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    strcpy(expecteds[1], "core1");
+    strcpy(expecteds[2], "core2");
+    strcpy(expecteds[3], "core3");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+
+    // Test 3:
+    // -- Setup
+    nb = 4;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_SENSOR(sensors[1], 3, "core3");
+    DUMB_SENSOR(sensors[2], 1, "core1");
+    DUMB_SENSOR(sensors[3], 2, "core2");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    strcpy(expecteds[1], "core3");
+    strcpy(expecteds[2], "core1");
+    strcpy(expecteds[3], "core2");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 }
 
 
 int main()
 {
-	test_raw_to_microjoule();
-	test_get_name();
-	test_label_amd_rapl();
+    test_raw_to_microjoule();
+    test_get_name();
+    test_label_amd_rapl();
 
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
diff --git a/src/info_reader.h b/src/info_reader.h
index 40948bd..019667f 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -224,214 +224,3 @@ static bool start_with(const char *prefix, const char *string)
     }
 }
 
-
-#ifdef __TESTING__
-#include "small_test.h"
-
-void test_replace_first()
-{
-    printf("==== TEST replace_first() ====\n");
-    char test1[] = "This is my string";
-    replace_first(test1, 'i', 'I');
-    TEST_STR(test1, "ThIs is my string");
-
-    char test2[] = "This is my string";
-    replace_first(test2, 'x', 'X');
-    TEST_STR(test2, "This is my string");
-
-
-    char test3[] = "This is my string";
-    replace_first(test3, ' ', '_');
-    TEST_STR(test3, "This_is my string");
-}
-
-void test_split_on_delimiter()
-{
-    printf("==== TEST split_on_delimite() ====\n");
-    char test4[] = "key:value";
-    char *key;
-    char *value;
-    split_on_delimiter(test4, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test5[] = "key: value";
-    split_on_delimiter(test5, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value");
-
-    char test6[] = "key:value";
-    replace_first(test6, ':', ' ');
-    split_on_delimiter(test6, " ", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test7[] = "";
-    split_on_delimiter(test7, ":", &key, &value);
-    TEST_STR(key, NULL);
-    TEST_STR(value, NULL);
-
-    char test9[] = "key:value:extra";
-    split_on_delimiter(test9, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value:extra");
-
-    char test10[] = "key: value :extra";
-    split_on_delimiter(test10, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value :extra");
-}
-
-void test_start_with()
-{
-    printf("==== TEST start_with() ====\n");
-    char *prefix = NULL;
-    char *string = NULL;
-    bool result = false;
-    bool _true = true;
-    bool _false = false;
-
-    prefix = "Hello";
-    string = "Hello World";
-    result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
-
-    prefix = "Goodbye";
-    string = "Hello World";
-    result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
-
-    prefix = "Hello World";
-    string = "Hello";
-    result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
-
-    prefix = "Hello";
-    string = "Hello";
-    result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
-
-    prefix = NULL;
-    string = "Hello World";
-    result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
-}
-
-#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
-	do { 											\
-		key_finder = (KeyFinder) {					\
-			key,									\
-			delimiter,								\
-			0,										\
-			0										\
-		}; 											\
-	} while (0);
-
-#define DUMB_PARSER(parser, keys, nb_keys)  \
-	do {									\
-		parser = (Parser) {					\
-			0,			   					\
-			0,			   					\
-			0,			   					\
-			0,  							\
-			keys,			   				\
-			nb_keys, 		   				\
-			0								\
-		};							   		\
-	} while (0);
-
-
-void test_match()
-{
-    printf("==== TEST match() ====\n");
-    // usefull variable :
-    bool _true = true;
-    bool _false = false;
-    KeyFinder keys[10];
-    char line[100];
-    Parser parser;
-    bool result;
-    KeyFinder *found_key_finder = NULL;
-    char *raw_value = NULL;
-
-    // Test 1:
-    // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
-    strcpy(line, "key: value");
-    found_key_finder = NULL;
-    raw_value = NULL;
-    // -- Run
-    result = match(&parser, line, &found_key_finder, &raw_value);
-    // -- Verification
-    TEST_BOOLEAN(&result, &_true);
-    TEST_PTR(found_key_finder, &keys[0]);
-    TEST_STR(raw_value, "value");
-
-    // Test 2:
-    // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1)
-    strcpy(line, "not a key: value");
-    found_key_finder = NULL;
-    raw_value = NULL;
-    // -- Run
-    result = match(&parser, line, &found_key_finder, &raw_value);
-    // -- Verification
-    TEST_BOOLEAN(&result, &_false);
-    TEST_PTR(found_key_finder, NULL);
-    TEST_STR(raw_value, NULL);
-
-    // Test 3:
-    // -- Setup
-    DUMB_KEYFINDER(keys[0],"key", ": ");
-    DUMB_PARSER(parser, keys, 1);
-    strcpy(line, "key:value");
-    found_key_finder = NULL;
-    raw_value = NULL;
-    // -- Run
-    result = match(&parser, line, &found_key_finder, &raw_value);
-    // -- Verification
-    TEST_BOOLEAN(&result, &_false);
-    TEST_PTR(found_key_finder, NULL);
-    TEST_STR(raw_value, NULL);
-
-    // Test 4:
-    // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_KEYFINDER(keys[1], "second_key", ": ");
-    DUMB_PARSER(parser, keys, 2);
-    strcpy(line, "second_key: value");
-    found_key_finder = NULL;
-    raw_value = NULL;
-    // -- Run
-    result = match(&parser, line, &found_key_finder, &raw_value);
-    // -- Verification
-    TEST_BOOLEAN(&result, &_true);
-    TEST_PTR(found_key_finder, &keys[1]);
-    TEST_STR(raw_value, "value");
-
-    // Test 5:
-    // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
-    strcpy(line, "");
-    found_key_finder = NULL;
-    raw_value = NULL;
-    // -- Run
-    result = match(&parser, line, &found_key_finder, &raw_value);
-    TEST_BOOLEAN(&result, &_false);
-    TEST_PTR(found_key_finder, NULL);
-    TEST_STR(raw_value, NULL);
-}
-
-int main()
-{
-    test_replace_first();
-    test_split_on_delimiter();
-    test_start_with();
-    test_match();
-    return 0;
-}
-
-#endif
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
new file mode 100644
index 0000000..10e5695
--- /dev/null
+++ b/tests/amd_rapl.c
@@ -0,0 +1,220 @@
+#include "small_test.h"
+#include "../src/amd_rapl.c"
+
+int test_raw_to_microjoule()
+{
+    printf("==== TEST raw_to_microjoule() ====\n");
+    int nb_error = 0;
+
+    uint64_t raw = 0;
+    uint64_t unit = 0;
+    uint64_t result = 0;
+    uint64_t expected = 0;
+
+    // Test 1:
+    // -- Setup
+    raw = 100;
+    unit = 0;
+    expected = 100000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    nb_error += TEST_UINT64_T(&result, &expected);
+
+    // nb_error += TEST 2:
+    // -- Setup
+    raw = 200;
+    unit = 1;
+    expected = 100000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    nb_error += TEST_UINT64_T(&result, &expected);
+
+    // nb_error += TEST 3:
+    // -- Setup
+    raw = 500;
+    unit = 2;
+    expected = 125000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    nb_error += TEST_UINT64_T(&result, &expected);
+
+    // nb_error += TEST 4:
+    // -- Setup
+    raw = 1000;
+    unit = 3;
+    expected = 125000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    nb_error += TEST_UINT64_T(&result, &expected);
+
+    // nb_error += TEST 5:
+    // -- Setup
+    raw = 10000;
+    unit = 4;
+    expected = 625000000;
+    // -- Run
+    result = raw_to_microjoule(raw, unit);
+    // -- Verification
+    nb_error += TEST_UINT64_T(&result, &expected);
+}
+
+int test_get_name()
+{
+    int nb_error = 0;
+
+    printf("==== TEST get_name() ====\n");
+    size_t cpu_id = 0;
+    char *result = NULL;
+    char expected[100];
+
+    // nb_error += TEST 1:
+    // -- Setup
+    cpu_id = 0;
+    strcpy(expected, "core0");
+    // -- Run
+    result = get_name(cpu_id);
+    // -- Verification
+    nb_error += TEST_STR(result, expected);
+    free(result);
+
+    // nb_error += TEST 2:
+    // -- Setup
+    cpu_id = 10000;
+    strcpy(expected, "core10000");
+    // -- Run
+    result = get_name(cpu_id);
+    // -- Verification
+    nb_error += TEST_STR(result, expected);
+    free(result);
+
+    return nb_error;
+}
+
+#define NONE 0
+#define DUMB_SENSOR(sensor, cpu_id, name)	\
+	do {									\
+		sensor = (cpu_sensor_t) {			\
+			cpu_id,							\
+			NONE,							\
+			name,							\
+			NONE,							\
+			NONE,							\
+			NONE, 							\
+			NONE							\
+		}; 									\
+	} while(0);
+
+#define DUMB_RAPL(rapl, sensors, nb)		\
+	do {									\
+		rapl = (_amd_rapl_t) {				\
+			sensors,						\
+			nb								\
+		};									\
+	} while(0);
+
+int test_label_amd_rapl()
+{
+    int nb_error = 0;
+    printf("==== TEST label_amd_rapl() ====\n");
+    cpu_sensor_t sensors[100];
+    _amd_rapl_t rapl;
+    char *results[100];
+    char expecteds[10][100];
+    uint64_t nb = 0;
+
+    // Test 1:
+    // -- Setup
+    nb = 1;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
+
+    // Test 2:
+    // -- Setup
+    nb = 4;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_SENSOR(sensors[1], 1, "core1");
+    DUMB_SENSOR(sensors[2], 2, "core2");
+    DUMB_SENSOR(sensors[3], 3, "core3");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    strcpy(expecteds[1], "core1");
+    strcpy(expecteds[2], "core2");
+    strcpy(expecteds[3], "core3");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
+
+    // Test 3:
+    // -- Setup
+    nb = 4;
+    DUMB_SENSOR(sensors[0], 0, "core0");
+    DUMB_SENSOR(sensors[1], 3, "core3");
+    DUMB_SENSOR(sensors[2], 1, "core1");
+    DUMB_SENSOR(sensors[3], 2, "core2");
+    DUMB_RAPL(rapl, sensors, nb);
+    strcpy(expecteds[0], "core0");
+    strcpy(expecteds[1], "core3");
+    strcpy(expecteds[2], "core1");
+    strcpy(expecteds[3], "core2");
+    // -- Run
+    label_amd_rapl(results, (void *) &rapl);
+    // -- Verification
+    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
+
+    return nb_error;
+}
+
+int test_amd_rapl()
+{
+    int nb_error = 0;
+    nb_error += test_raw_to_microjoule();
+    nb_error += test_get_name();
+    nb_error += test_label_amd_rapl();
+    return nb_error;
+}
+
+#ifdef __TESTING__AMD__
+int main()
+{
+    test_amd_rapl();
+    static const unsigned int time = 10;
+    _amd_rapl_t *rapl = NULL;
+    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
+    uint64_t results[nb_cpu];
+    char *labels[nb_cpu];
+
+    label_amd_rapl(labels, (void *) rapl);
+
+    for (unsigned int i = 0; i < rapl->nb; ++i) {
+        printf("%s ", labels[i]);
+    }
+    printf("\n");
+
+    // -- Run
+
+    for (unsigned int i = 0; i < time; ++i) {
+        sleep(1);
+        get_amd_rapl(results, (void *)rapl);
+
+        for (unsigned int j = 0; j < rapl->nb; ++j) {
+            printf("%ld ", results[j]);
+        }
+        printf("\n");
+    }
+
+    clean_amd_rapl(rapl);
+    return 0;
+}
+
+#endif
+
diff --git a/src/info_reader.c b/tests/example_info_reader.c
similarity index 98%
rename from src/info_reader.c
rename to tests/example_info_reader.c
index 19d84de..1dd6464 100644
--- a/src/info_reader.c
+++ b/tests/example_info_reader.c
@@ -2,7 +2,7 @@
 #include <stdint.h>
 
 #ifdef DEBUG
-#warning "PTR_TO_TPTR hide a cast warning"aa
+#warning "PTR_TO_TPTR hide a cast warning"
 #endif
 
 #define MAX_PROCS 2
diff --git a/tests/info_reader.c b/tests/info_reader.c
new file mode 100644
index 0000000..36d2e96
--- /dev/null
+++ b/tests/info_reader.c
@@ -0,0 +1,233 @@
+#include "small_test.h"
+
+int test_replace_first()
+{
+    int nb_error = 0;
+
+    printf("==== TEST replace_first() ====\n");
+    char test1[] = "This is my string";
+    replace_first(test1, 'i', 'I');
+    nb_error += TEST_STR(test1, "ThIs is my string");
+
+    char test2[] = "This is my string";
+    replace_first(test2, 'x', 'X');
+    nb_error += TEST_STR(test2, "This is my string");
+
+
+    char test3[] = "This is my string";
+    replace_first(test3, ' ', '_');
+    nb_error += TEST_STR(test3, "This_is my string");
+    return nb_error;
+}
+
+int test_split_on_delimiter()
+{
+    int nb_error = 0;
+
+    printf("==== TEST split_on_delimite() ====\n");
+    char test4[] = "key:value";
+    char *key;
+    char *value;
+    split_on_delimiter(test4, ":", &key, &value);
+    nb_error += TEST_STR(key, "key");
+    nb_error += TEST_STR(value, "value");
+
+    char test5[] = "key: value";
+    split_on_delimiter(test5, ":", &key, &value);
+    nb_error += TEST_STR(key, "key");
+    nb_error += TEST_STR(value, " value");
+
+    char test6[] = "key:value";
+    replace_first(test6, ':', ' ');
+    split_on_delimiter(test6, " ", &key, &value);
+    nb_error += TEST_STR(key, "key");
+    nb_error += TEST_STR(value, "value");
+
+    char test7[] = "";
+    split_on_delimiter(test7, ":", &key, &value);
+    nb_error += TEST_STR(key, NULL);
+    nb_error += TEST_STR(value, NULL);
+
+    char test9[] = "key:value:extra";
+    split_on_delimiter(test9, ":", &key, &value);
+    nb_error += TEST_STR(key, "key");
+    nb_error += TEST_STR(value, "value:extra");
+
+    char test10[] = "key: value :extra";
+    split_on_delimiter(test10, ":", &key, &value);
+    nb_error += TEST_STR(key, "key");
+    nb_error += TEST_STR(value, " value :extra");
+
+    return nb_error;
+}
+
+int test_start_with()
+{
+    int nb_error = 0;
+
+    printf("==== TEST start_with() ====\n");
+    char *prefix = NULL;
+    char *string = NULL;
+    bool result = false;
+    bool _true = true;
+    bool _false = false;
+
+    prefix = "Hello";
+    string = "Hello World";
+    result = start_with(prefix, string);
+    nb_error += TEST_BOOLEAN(&result, &_true);
+
+    prefix = "Goodbye";
+    string = "Hello World";
+    result = start_with(prefix, string);
+    nb_error += TEST_BOOLEAN(&result, &_false);
+
+    prefix = "Hello World";
+    string = "Hello";
+    result = start_with(prefix, string);
+    nb_error += TEST_BOOLEAN(&result, &_false);
+
+    prefix = "Hello";
+    string = "Hello";
+    result = start_with(prefix, string);
+    nb_error += TEST_BOOLEAN(&result, &_true);
+
+    prefix = NULL;
+    string = "Hello World";
+    result = start_with(prefix, string);
+    nb_error += TEST_BOOLEAN(&result, &_false);
+
+    return nb_error;
+}
+
+#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
+	do { 											\
+		key_finder = (KeyFinder) {					\
+			key,									\
+			delimiter,								\
+			0,										\
+			0										\
+		}; 											\
+	} while (0);
+
+#define DUMB_PARSER(parser, keys, nb_keys)  \
+	do {									\
+		parser = (Parser) {					\
+			0,			   					\
+			0,			   					\
+			0,			   					\
+			0,  							\
+			keys,			   				\
+			nb_keys, 		   				\
+			0								\
+		};							   		\
+	} while (0);
+
+
+int test_match()
+{
+    int nb_error = 0;
+    printf("==== TEST match() ====\n");
+    // usefull variable :
+    bool _true = true;
+    bool _false = false;
+    KeyFinder keys[10];
+    char line[100];
+    Parser parser;
+    bool result;
+    KeyFinder *found_key_finder = NULL;
+    char *raw_value = NULL;
+
+    // Test 1:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    nb_error += TEST_BOOLEAN(&result, &_true);
+    nb_error += TEST_PTR(found_key_finder, &keys[0]);
+    nb_error += TEST_STR(raw_value, "value");
+
+    // Test 2:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1)
+    strcpy(line, "not a key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    nb_error += TEST_BOOLEAN(&result, &_false);
+    nb_error += TEST_PTR(found_key_finder, NULL);
+    nb_error += TEST_STR(raw_value, NULL);
+
+    // Test 3:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0],"key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "key:value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    nb_error += TEST_BOOLEAN(&result, &_false);
+    nb_error += TEST_PTR(found_key_finder, NULL);
+    nb_error += TEST_STR(raw_value, NULL);
+
+    // Test 4:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_KEYFINDER(keys[1], "second_key", ": ");
+    DUMB_PARSER(parser, keys, 2);
+    strcpy(line, "second_key: value");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    // -- Verification
+    nb_error += TEST_BOOLEAN(&result, &_true);
+    nb_error += TEST_PTR(found_key_finder, &keys[1]);
+    nb_error += TEST_STR(raw_value, "value");
+
+    // Test 5:
+    // -- Setup
+    DUMB_KEYFINDER(keys[0], "key", ": ");
+    DUMB_PARSER(parser, keys, 1);
+    strcpy(line, "");
+    found_key_finder = NULL;
+    raw_value = NULL;
+    // -- Run
+    result = match(&parser, line, &found_key_finder, &raw_value);
+    nb_error += TEST_BOOLEAN(&result, &_false);
+    nb_error += TEST_PTR(found_key_finder, NULL);
+    nb_error += TEST_STR(raw_value, NULL);
+
+    return nb_error;
+}
+
+int test_info_reader()
+{
+    int nb_error = 0;
+
+    nb_error += test_replace_first();
+    nb_error += test_split_on_delimiter();
+    nb_error += test_start_with();
+    nb_error += test_match();
+
+    return nb_error;
+}
+
+#ifdef __TESTING_INFO_READER__
+int main()
+{
+    test_info_reader();
+    return 0;
+}
+#endif
+
diff --git a/tests/main.c b/tests/main.c
new file mode 100644
index 0000000..ee65c19
--- /dev/null
+++ b/tests/main.c
@@ -0,0 +1,13 @@
+#include "amd_rapl.c"
+#include "info_reader.c"
+
+int main()
+{
+    int nb_error = 0;
+
+    nb_error += test_amd_rapl();
+    nb_error += test_info_reader();
+
+    return nb_error;
+}
+
diff --git a/src/small_test.h b/tests/small_test.h
similarity index 69%
rename from src/small_test.h
rename to tests/small_test.h
index b8673dd..8f426ce 100644
--- a/src/small_test.h
+++ b/tests/small_test.h
@@ -1,5 +1,10 @@
 #ifndef __SMALL_TEST_H
-#define __SMALL_TEST_H 
+#define __SMALL_TEST_H
+
+#include <stdbool.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdio.h>
 
 #define FMT_NULL(string) \
 	string = string ? string : "NULL"
@@ -16,9 +21,9 @@
 #define TEST_UINT64_T(result, expected) \
 	test_uint64_t(__FILE__, __LINE__, result, expected)
 
-#define TEST_T_ARRAY(function, size, results, expecteds)	\
-	for (unsigned int i = 0; i < size; i++) {				\
-		function(results[i], expecteds[i]);					\
+#define TEST_T_ARRAY(function, nb_error, size, results, expecteds)	\
+	for (unsigned int i = 0; i < size; i++) {						\
+		nb_error += function(results[i], expecteds[i]);				\
 	}
 
 typedef int (Comparator) (void *, void *);
@@ -74,11 +79,12 @@ char *uint64_t_format(char *buffer, uint64_t *value)
     return buffer;
 }
 
-void test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+int test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
 {
     static char buffer_result[1000];
     static char buffer_expected[1000];
-    if (compare(result, expected) == 0) {
+    int is_equal = compare(result, expected);
+    if  (!is_equal) {
         printf("Test %s:%d failed: expected %s, got %s\n",
                file,
                line,
@@ -88,37 +94,39 @@ void test(char *file, int line, void *result, void *expected, Comparator *compar
     } else {
         printf("Test %s:%d passed\n", file, line);
     }
+    return !is_equal;
 }
 
-void test_str(char *file, int line, char *result, char *expected)
+int test_str(char *file, int line, char *result, char *expected)
 {
     Comparator *compare = (Comparator *) string_compare;
     Formatter *format = (Formatter *) string_format;
 
-    test(file, line, result, expected, compare, format);
+    return test(file, line, result, expected, compare, format);
 }
 
-void test_boolean(char *file, int line, bool *result, bool *expected)
+int test_boolean(char *file, int line, bool *result, bool *expected)
 {
     Comparator *compare = (Comparator *) boolean_compare;
     Formatter *format = (Formatter *) boolean_format;
 
-    test(file, line, (void *) result, (void *) expected, compare, format);
+    return test(file, line, (int *) result, (void *) expected, compare, format);
 }
 
-void test_ptr(char *file, int line, void *result, void *expected)
+int test_ptr(char *file, int line, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) ptr_compare;
     Formatter *format = (Formatter *) ptr_format;
 
-    test(file, line, result, expected, compare, format);
+    return test(file, line, result, expected, compare, format);
 }
 
-void test_uint64_t(char *file, int line, void *result, void *expected)
+int test_uint64_t(char *file, int line, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) uint64_t_compare;
     Formatter *format = (Formatter *) uint64_t_format;
 
-    test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
+    return test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
 }
 #endif
+
-- 
GitLab


From 87fc85cb4ed4d3b8cf7fb554590e7674b9a9329c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 13:20:50 +0000
Subject: [PATCH 053/229] add new macro

---
 src/amd_rapl.c    | 3 +--
 src/info_reader.h | 8 --------
 src/util.h        | 6 ++++++
 3 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 91b6009..e0baad8 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -320,8 +320,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
     for (unsigned int i = 0; i < rapl->nb; i++) {
-        // TODO: check if unit is the same
-#warning "check if unit is the same"
+		DEBUG_WARNING("check if unit is the same")
         results[i] = get_core_energy(&rapl->sensors[i]);
     }
     return rapl->nb;
diff --git a/src/info_reader.h b/src/info_reader.h
index 019667f..1696ede 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -113,14 +113,6 @@ static void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value)
     key_finder->set(address, value);
 }
 
-// static void storage_zero(Parser *parser) {
-// 	static const int zero = 0;
-// 	GenericPointer storage = parser->storage;
-// 	size_t capacity = parser->capacity;
-// 	size_t struct_size = parser->storage_struct_size;
-// 	memset(storage, zero, struct_size * capacity);
-// }
-
 static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value)
 {
     for (unsigned int i = 0; i < parser->nb_keys; i++) {
diff --git a/src/util.h b/src/util.h
index 6d4a644..9468d41 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,6 +29,12 @@
 #define _impl_CASSERT_LINE(predicate, line, file) \
     typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
 
+#ifdef DEBUG					
+	#define DEBUG_WARNING(warning) #warning warning
+#else
+	#define DEBUG_WARNING(warning) do { } while(0);		
+#endif
+
 #define UNUSED(expr) do { (void)(expr); } while (0)
 #define PANIC(code, fmt, ...)                \
     do {                                     \
-- 
GitLab


From cd89c3608c3d8dd7eb026d0732d059e881b45932 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 14:02:22 +0000
Subject: [PATCH 054/229] add util tests

---
 src/util.c         |  4 ++--
 tests/amd_rapl.c   |  2 ++
 tests/main.c       |  2 ++
 tests/small_test.h |  3 ++-
 tests/util.c       | 58 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 66 insertions(+), 3 deletions(-)
 create mode 100644 tests/util.c

diff --git a/src/util.c b/src/util.c
index fe3efa1..7efa66f 100644
--- a/src/util.c
+++ b/src/util.c
@@ -22,6 +22,6 @@
 
 uint64_t modulo_substraction(uint64_t previous, uint64_t new)
 {
-    return new > previous ? (new - previous)
-           : (UINT64_MAX - previous) + new;
+    return new >= previous ? (new - previous)
+           : (UINT64_MAX - previous + 1) + new;
 }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 10e5695..e890ca4 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -60,6 +60,8 @@ int test_raw_to_microjoule()
     result = raw_to_microjoule(raw, unit);
     // -- Verification
     nb_error += TEST_UINT64_T(&result, &expected);
+
+	return nb_error;
 }
 
 int test_get_name()
diff --git a/tests/main.c b/tests/main.c
index ee65c19..950632d 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,4 +1,5 @@
 #include "amd_rapl.c"
+#include "util.c"
 #include "info_reader.c"
 
 int main()
@@ -7,6 +8,7 @@ int main()
 
     nb_error += test_amd_rapl();
     nb_error += test_info_reader();
+	nb_error += test_util();
 
     return nb_error;
 }
diff --git a/tests/small_test.h b/tests/small_test.h
index 8f426ce..5cb6616 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -3,6 +3,7 @@
 
 #include <stdbool.h>
 #include <string.h>
+#include <inttypes.h>
 #include <stdint.h>
 #include <stdio.h>
 
@@ -75,7 +76,7 @@ int uint64_t_compare(uint64_t *value1, uint64_t *value2)
 
 char *uint64_t_format(char *buffer, uint64_t *value)
 {
-    sprintf(buffer, "%ld", *value);
+    sprintf(buffer, "%"PRIu64"", *value);
     return buffer;
 }
 
diff --git a/tests/util.c b/tests/util.c
new file mode 100644
index 0000000..218cf5a
--- /dev/null
+++ b/tests/util.c
@@ -0,0 +1,58 @@
+#include "../src/util.h"
+#include "small_test.h"
+
+
+int test_modulo_substraction() {
+	printf("==== TEST test_modulo_substraction() ====\n");
+	int nb_error = 0;
+	uint64_t previous = 0;
+	uint64_t new = 0;
+	uint64_t result = 0;
+	uint64_t expected = 0;
+
+	// Test 1:
+	// -- Setup
+	previous = 10;
+	new = 10;
+	expected = 0;
+	// -- Run
+	result = modulo_substraction(previous, new);	
+	// -- Verification
+	nb_error = TEST_UINT64_T(&result, &expected);
+	
+	// Test 2:
+	// -- Setup
+	previous = UINT64_MAX;
+	new = 0;
+	expected = 1;
+	// -- Run
+	result = modulo_substraction(previous, new);	
+	// -- Verification
+	nb_error = TEST_UINT64_T(&result, &expected);
+
+	// Test 3:
+	// -- Setup
+	previous = 0;
+	new = UINT64_MAX;
+	expected = UINT64_MAX;
+	// -- Run
+	result = modulo_substraction(previous, new);	
+	// -- Verification
+	nb_error = TEST_UINT64_T(&result, &expected);
+	
+	// Test 4:
+	// -- Setup
+	previous = 20;
+	new = 10;
+	expected = UINT64_MAX - 9;
+	// -- Run
+	result = modulo_substraction(previous, new);	
+	// -- Verification
+	nb_error = TEST_UINT64_T(&result, &expected);
+	
+	return nb_error;
+}
+int test_util() {
+	int nb_error = test_modulo_substraction();
+	return nb_error;
+}
-- 
GitLab


From 917d9d1e0b4d0343ae8da67730696801ff227ee9 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 14:03:24 +0000
Subject: [PATCH 055/229] update .gitignore

---
 .gitignore | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 44d1164..2721f47 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
 src/counters_option.h
 src/captors.h
-tests/tests
+tests/run
 bin
 obj
-- 
GitLab


From 4afbb05a4f52230ad4aa928467bf8a87c13d92d6 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 15:09:29 +0000
Subject: [PATCH 056/229] update test framework

---
 tests/.small_test.h.swp | Bin 0 -> 16384 bytes
 tests/amd_rapl.c        |  10 ++--
 tests/info_reader.c     |   9 ++--
 tests/main.c            |   3 +-
 tests/small_test.h      |  28 +++++++++--
 tests/util.c            | 103 +++++++++++++++++++++-------------------
 6 files changed, 90 insertions(+), 63 deletions(-)
 create mode 100644 tests/.small_test.h.swp

diff --git a/tests/.small_test.h.swp b/tests/.small_test.h.swp
new file mode 100644
index 0000000000000000000000000000000000000000..3ebcb5fb09f2f1e9646145b69c8054103f3a9a64
GIT binary patch
literal 16384
zcmYc?2=nw+u+TGNU|?VnU|<OUaz1&gsRF~QAO?n_%;Mt2l-$fbkQ^QiQkPm(mRf{I
z4M?gEq!4VNetCXTc5y*sa;koAepY5lezAT@YH>-iesOMMPEI_Ct(O7PGKxn-U^E1%
z5dx(pX}T7?48}%=1|Z{<l@t|(g+f8hQ9K#~qaiRF0;3@?8UmvsFd71*Aut*OqaiRt
zLZGC8iJ_i>fq@C?-&QEih(<F*`65tyGL(j?gK|fy(GVC7fzc2c4S~@R7!85Z5Eu=C
z(GVC7fzc2c4S~@R7!83z7y^kY3=A@i3=BS?4!!^b1FZl5lAnR$5<dgOMScc`J^Ty|
zEBF~0Ch;>c)bTSgWb-pHWbrdF`13O`=<qWzX!A2Lu<<i6T;pS4xXQ=Cu!fI;p@NTr
zp`4F_A&8HGL5YunL6MJv;X5w_!y#S<hJ(Be3^lwA3|_np48pt&3<A6i4E($d3}1K{
z7|!!BFr4FIU|7$?z%YS_fuWy=fgy*7fkBmrfkB0bf#D}N1H)Nv28J`-3=Ffm85m}A
zGcaUxGcZJQGcc%dGcX8oGcd4nGca7`VqiGW#lUcui-F+`7Xw2J7Xw2R7Xw2o7Xw2w
z7Xw2Q7Xw2g7XyPX7XyPf7Xt$a7Xt$u7Xt$;7X!m?P6mdZoD2*TIT;xGIT;xGI2jny
zI2jmHI2jncIT;u{IT;u{I2jn^I2jmZI2joJa4;~u<X~WU&cVR&jDvyUDF*|?8V&}A
zRU8Zq-5d-Iog54d9UKe{!5j<>fgB7B>KqIVA{-11LL3YXf*cGCSJ@dDF0(T*OkrnW
zn8eP&Fp-^sA(@?lA(5Sd!IqtY!J3_c!HS)M;VK&g!(}!GhIMQV4DD<T43TUM4Ek&g
z3_n;I7{0SIFg#>sVA#mYz|hFbz!1dBz~IQrz+l44z#zfOz#zoR!0?BKf#DYm1H(@i
z28JCh3=G>?7#M0<7#KWQ7#Q4H7#P@D7#LVt7#LVs7#Q|5GcfFBW?*P$W?=AThNKT~
zW(EcoW(EcpW(EdkW(Ec(P?}+8V7SA?z;KI+f#E0<1H)k^28M%73=B({7#RAQ7#R9s
z14~4veFX&t1-Ja7+{BWS)FK6~G!T;kn_!88t%8PIei4HL2x8TRS0B^{1_cHNLh1;~
zgI%hrK+qhhx}^O4oYcg;c(C6}tih%`=jRqA7A2PC7b$2ZgW0Jd{~-%&D!?>C6<9M=
zGi2tKD1cVW#6#sYk~0!P!Iqhms-pms%*o74)dA~N&?-tTF3l-{@lq=aQj<$kQ#2VE
zYQb(ON-ZfZ$^#pxkp?yZq8X+Qra?ym>Hr-Dh!-@iiS>GMNl|8AI_W-#>Vw*g;_>2=
zA{?HE1O?3X5FX4A=$=;0ERIhtEKSU@1_uQsKtRc^peQr1Buzu9AhEbOH6<obNfW9<
zAvLEsRiPTJ9HbC}p|TJTn1lq8Mp9{7T53@|%zhmOh`Th=^g}}wrW~S3M**fyQwOdd
z=CHKH%$(E|gc1eSVjYF_{1OG#;+Q-oi2BSl1qBVb7c~{CA@Kz>B3d;$7Ub3%1=V6J
z)f6iQB^`z2c$nRYqyY6CI3!{63bqQcpi{6{P!CgAuu@QuP=^E(C;`G{ZDGkq17<SZ
zR}j_3C5a`O$qHcO(Sj@5(7?bT7N;_ZfiOjgT!ABDl;vlpAaVnQ2Xl*#0&<>%CO938
zBB=zPfM9`GV{50NTCAZ73Ur0E(!Au7%=|n}P*Me3keQcR0$$e^50leK&d)0@fp}L7
zCWv9IEgUF>xCVzPWacTT7Axo?+Xc?5a09T}n3<D`Y8zM!Ui+bi0VE!v0T1;mL`+9P
zNmVHz$g|YUL`g|UL8~k=r!*DpUvLC!m1gFZn3=?vKr=fuDqwnHvM_yUWe~(PLj_w~
zr~)I9w?N4WrZFBGH5xDhs6s;>1vC*OO$Id6A&$W1sRAV(g@TeIB(D^d6k+!TIA*m#
ziqUK+C@BIvzM!NC?sAYRFh|2R8tN#(*&v5P3La?SYe5Tj1$zahkfPF5B?T)5CAY+!
z;#4J2a6rNtss`r3`1r(<lA_F{(vsBpcnyuxywc*-6irQNGK2UWRs%q_!qXg@wO}8>
z+yM6mR1-Y>L3{<6Dnm4*L0&?wUEF*_;{8H>d^8|MI#MV@1W5A-BnTin;og9RA*euu
zdI)4!a&7^L%FIhQ)KP$FFwz92F9T?)R*PPsLp2*f(g{>LGfe?z3`jG`Ckiz+Fau#i
zpb{2jKL|sOF@zX{O~0BNHvN!N4B}FFU?cn2PzM^R5H+BnE~zX?O-W6Iii285kXDYS
z0yO)<Qk$kV157O_Q)wW|JWT}+NP<LC%D|bDuTZT3&HhU863JG<B{eOzs3<i>!L_I;
zzevGKK^0U*>L}zT#ixQqG_4hC70NR}<&S|TgK|o0T4r9Vf{Ux0YfzA@OT24PkbjT{
zT(Lq70|O_Pf-)XlX2!>BTEmU-^z#gf2Nj6%ZlQk8A)fwz8k*?ZLAJ)nyLtM!#>eX@
z;5Wq6#}#ToEdwVf%tZ>?w(z1HT5A<YXT~BbTM$pvnv;{0GlqdPEx$-XqcpELGd(Xg
z1>E?`RIpVruvW-auu&+^tV*?3$kf)>RHz222kC%?2iPAW@s2@3j*%L$f*cWuI$+JP
z7DF+T?V6mR5CgaWV1=FrvX6Z{{lI>Q)Q<>_h^PQt9qQ>9VrCK_0`(%2I&hGJ%`Ye^
zBFE@}kRW`ff(nn+#5{6LcJlZ4adq^=XF8~9NJel3<8(75rzzM%^Q(eAjA5mq1S$%Y
z;OP^+m;(i*a%Ns~PH9T2f=zKrN@l)Zh8+W{P+keDSY}=cD3=zaib5QLE|vlcN{}Gj
z3Gwm4zK%XVkX+)ypq!bO2PzxTghBm(6J7>}1-y{;|FHS}_52JBYxx-%)<FCFnfwe4
z#{3KnjQk7?4EziX2lyBm_VF<=?1lF8OZgZWtoRrhnE4nOnD`hNR`D`0tl(u}SO_(H
zKFE9``+%d$MnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(M23KJYF<ia8tNb#s7H=6
zMT0a7stN1tBa0zMx1l4Dq)*+z1{k0NbdcdJ#JCZjX)Cx+sNJBkOVFqj$QSW2N$3C-
zWU>Jy3z>U@j77n`1mVFv10V2%4zYpELkSg_HkbwqCayq(w~(0}5<Cvlgw4;Ou@uNi
a9#y@o0SY!PP3X*$4s0M#6Fz%{&Hn%&q=H-k

literal 0
HcmV?d00001

diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index e890ca4..1ddf234 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -3,7 +3,7 @@
 
 int test_raw_to_microjoule()
 {
-    printf("==== TEST raw_to_microjoule() ====\n");
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
 
     uint64_t raw = 0;
@@ -61,14 +61,14 @@ int test_raw_to_microjoule()
     // -- Verification
     nb_error += TEST_UINT64_T(&result, &expected);
 
-	return nb_error;
+    return nb_error;
 }
 
 int test_get_name()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
 
-    printf("==== TEST get_name() ====\n");
     size_t cpu_id = 0;
     char *result = NULL;
     char expected[100];
@@ -120,8 +120,8 @@ int test_get_name()
 
 int test_label_amd_rapl()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
-    printf("==== TEST label_amd_rapl() ====\n");
     cpu_sensor_t sensors[100];
     _amd_rapl_t rapl;
     char *results[100];
@@ -178,6 +178,8 @@ int test_label_amd_rapl()
 
 int test_amd_rapl()
 {
+    INIT_TEST_FILE();
+
     int nb_error = 0;
     nb_error += test_raw_to_microjoule();
     nb_error += test_get_name();
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 36d2e96..3953109 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -2,9 +2,9 @@
 
 int test_replace_first()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
 
-    printf("==== TEST replace_first() ====\n");
     char test1[] = "This is my string";
     replace_first(test1, 'i', 'I');
     nb_error += TEST_STR(test1, "ThIs is my string");
@@ -22,9 +22,9 @@ int test_replace_first()
 
 int test_split_on_delimiter()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
 
-    printf("==== TEST split_on_delimite() ====\n");
     char test4[] = "key:value";
     char *key;
     char *value;
@@ -63,9 +63,9 @@ int test_split_on_delimiter()
 
 int test_start_with()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
 
-    printf("==== TEST start_with() ====\n");
     char *prefix = NULL;
     char *string = NULL;
     bool result = false;
@@ -126,8 +126,8 @@ int test_start_with()
 
 int test_match()
 {
+    INIT_TEST_FUNCTION();
     int nb_error = 0;
-    printf("==== TEST match() ====\n");
     // usefull variable :
     bool _true = true;
     bool _false = false;
@@ -213,6 +213,7 @@ int test_match()
 
 int test_info_reader()
 {
+    INIT_TEST_FILE();
     int nb_error = 0;
 
     nb_error += test_replace_first();
diff --git a/tests/main.c b/tests/main.c
index 950632d..b14f518 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -8,8 +8,9 @@ int main()
 
     nb_error += test_amd_rapl();
     nb_error += test_info_reader();
-	nb_error += test_util();
+    nb_error += test_util();
 
+    DEFERRED_ERROR(nb_error);
     return nb_error;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index 5cb6616..b93cd7b 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -27,6 +27,15 @@
 		nb_error += function(results[i], expecteds[i]);				\
 	}
 
+#define INIT_TEST_FILE() \
+	init_test_file(__FILE__, __func__);
+
+#define INIT_TEST_FUNCTION() \
+	init_test_function(__func__);
+
+#define DEFERRED_ERROR(nb_error) \
+	do { printf("========== Deferred Error : %d\n", nb_error); } while(0)
+
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
 
@@ -80,20 +89,31 @@ char *uint64_t_format(char *buffer, uint64_t *value)
     return buffer;
 }
 
+void init_test_file(const char *file, const char *function)
+{
+    printf("========== TEST in %s -> %s()\n", file, function);
+}
+
+void init_test_function(const char *function)
+{
+    printf("|=> %s()\n", function);
+}
+
 int test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
 {
     static char buffer_result[1000];
     static char buffer_expected[1000];
     int is_equal = compare(result, expected);
+    char c_result = is_equal ? 'V' : 'X';
+    printf("[%c]    | %s:%d: ", c_result, file, line);
+
     if  (!is_equal) {
-        printf("Test %s:%d failed: expected %s, got %s\n",
-               file,
-               line,
+        printf("failed, expected %s, got %s\n",
                format(buffer_result, expected),
                format(buffer_expected, result)
               );
     } else {
-        printf("Test %s:%d passed\n", file, line);
+        printf("passed\n");
     }
     return !is_equal;
 }
diff --git a/tests/util.c b/tests/util.c
index 218cf5a..eba4da3 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -2,57 +2,60 @@
 #include "small_test.h"
 
 
-int test_modulo_substraction() {
-	printf("==== TEST test_modulo_substraction() ====\n");
-	int nb_error = 0;
-	uint64_t previous = 0;
-	uint64_t new = 0;
-	uint64_t result = 0;
-	uint64_t expected = 0;
+int test_modulo_substraction()
+{
+    INIT_TEST_FUNCTION();
+    int nb_error = 0;
+    uint64_t previous = 0;
+    uint64_t new = 0;
+    uint64_t result = 0;
+    uint64_t expected = 0;
 
-	// Test 1:
-	// -- Setup
-	previous = 10;
-	new = 10;
-	expected = 0;
-	// -- Run
-	result = modulo_substraction(previous, new);	
-	// -- Verification
-	nb_error = TEST_UINT64_T(&result, &expected);
-	
-	// Test 2:
-	// -- Setup
-	previous = UINT64_MAX;
-	new = 0;
-	expected = 1;
-	// -- Run
-	result = modulo_substraction(previous, new);	
-	// -- Verification
-	nb_error = TEST_UINT64_T(&result, &expected);
+    // Test 1:
+    // -- Setup
+    previous = 10;
+    new = 10;
+    expected = 0;
+    // -- Run
+    result = modulo_substraction(previous, new);
+    // -- Verification
+    nb_error = TEST_UINT64_T(&result, &expected);
 
-	// Test 3:
-	// -- Setup
-	previous = 0;
-	new = UINT64_MAX;
-	expected = UINT64_MAX;
-	// -- Run
-	result = modulo_substraction(previous, new);	
-	// -- Verification
-	nb_error = TEST_UINT64_T(&result, &expected);
-	
-	// Test 4:
-	// -- Setup
-	previous = 20;
-	new = 10;
-	expected = UINT64_MAX - 9;
-	// -- Run
-	result = modulo_substraction(previous, new);	
-	// -- Verification
-	nb_error = TEST_UINT64_T(&result, &expected);
-	
-	return nb_error;
+    // Test 2:
+    // -- Setup
+    previous = UINT64_MAX;
+    new = 0;
+    expected = 1;
+    // -- Run
+    result = modulo_substraction(previous, new);
+    // -- Verification
+    nb_error = TEST_UINT64_T(&result, &expected);
+
+    // Test 3:
+    // -- Setup
+    previous = 0;
+    new = UINT64_MAX;
+    expected = UINT64_MAX;
+    // -- Run
+    result = modulo_substraction(previous, new);
+    // -- Verification
+    nb_error = TEST_UINT64_T(&result, &expected);
+
+    // Test 4:
+    // -- Setup
+    previous = 20;
+    new = 10;
+    expected = UINT64_MAX - 9;
+    // -- Run
+    result = modulo_substraction(previous, new);
+    // -- Verification
+    nb_error = TEST_UINT64_T(&result, &expected);
+
+    return nb_error;
 }
-int test_util() {
-	int nb_error = test_modulo_substraction();
-	return nb_error;
+int test_util()
+{
+    INIT_TEST_FILE();
+    int nb_error = test_modulo_substraction();
+    return nb_error;
 }
-- 
GitLab


From f96d52de8b37b8e22cfd0b275cfba014f279555d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 15:10:06 +0000
Subject: [PATCH 057/229] fix: format

---
 doc/counter_ex.c | 4 ++--
 doc/counter_ex.h | 2 +-
 src/amd_rapl.c   | 2 +-
 src/util.h       | 6 +++---
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
index 73696ad..0dc6f29 100644
--- a/doc/counter_ex.c
+++ b/doc/counter_ex.c
@@ -21,6 +21,6 @@ void label_acc(char **labels, void *none)
 
 void clean_acc(void *none)
 {
-	/* That's a no-op for this example */
-	UNUSED(none);
+    /* That's a no-op for this example */
+    UNUSED(none);
 }
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index beeef91..4ab7915 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -4,7 +4,7 @@
 
 unsigned int init_acc(char *, void **);
 unsigned int get_acc(uint64_t *results, void *);
-void clean_acc(void*);
+void clean_acc(void *);
 void label_acc(char **labels, void *);
 
 struct optparse_long counters_opt = {"accumulator", 'a', OPTPARSE_NONE};
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index e0baad8..238161c 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -320,7 +320,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
     for (unsigned int i = 0; i < rapl->nb; i++) {
-		DEBUG_WARNING("check if unit is the same")
+        DEBUG_WARNING("check if unit is the same")
         results[i] = get_core_energy(&rapl->sensors[i]);
     }
     return rapl->nb;
diff --git a/src/util.h b/src/util.h
index 9468d41..991c71e 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,10 +29,10 @@
 #define _impl_CASSERT_LINE(predicate, line, file) \
     typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
 
-#ifdef DEBUG					
-	#define DEBUG_WARNING(warning) #warning warning
+#ifdef DEBUG
+#define DEBUG_WARNING(warning) #warning warning
 #else
-	#define DEBUG_WARNING(warning) do { } while(0);		
+#define DEBUG_WARNING(warning) do { } while(0);
 #endif
 
 #define UNUSED(expr) do { (void)(expr); } while (0)
-- 
GitLab


From 23b861984b65c10228036fd19fcc71a66971263d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 15:11:16 +0000
Subject: [PATCH 058/229] rm vim file

---
 tests/.small_test.h.swp | Bin 16384 -> 0 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100644 tests/.small_test.h.swp

diff --git a/tests/.small_test.h.swp b/tests/.small_test.h.swp
deleted file mode 100644
index 3ebcb5fb09f2f1e9646145b69c8054103f3a9a64..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 16384
zcmYc?2=nw+u+TGNU|?VnU|<OUaz1&gsRF~QAO?n_%;Mt2l-$fbkQ^QiQkPm(mRf{I
z4M?gEq!4VNetCXTc5y*sa;koAepY5lezAT@YH>-iesOMMPEI_Ct(O7PGKxn-U^E1%
z5dx(pX}T7?48}%=1|Z{<l@t|(g+f8hQ9K#~qaiRF0;3@?8UmvsFd71*Aut*OqaiRt
zLZGC8iJ_i>fq@C?-&QEih(<F*`65tyGL(j?gK|fy(GVC7fzc2c4S~@R7!85Z5Eu=C
z(GVC7fzc2c4S~@R7!83z7y^kY3=A@i3=BS?4!!^b1FZl5lAnR$5<dgOMScc`J^Ty|
zEBF~0Ch;>c)bTSgWb-pHWbrdF`13O`=<qWzX!A2Lu<<i6T;pS4xXQ=Cu!fI;p@NTr
zp`4F_A&8HGL5YunL6MJv;X5w_!y#S<hJ(Be3^lwA3|_np48pt&3<A6i4E($d3}1K{
z7|!!BFr4FIU|7$?z%YS_fuWy=fgy*7fkBmrfkB0bf#D}N1H)Nv28J`-3=Ffm85m}A
zGcaUxGcZJQGcc%dGcX8oGcd4nGca7`VqiGW#lUcui-F+`7Xw2J7Xw2R7Xw2o7Xw2w
z7Xw2Q7Xw2g7XyPX7XyPf7Xt$a7Xt$u7Xt$;7X!m?P6mdZoD2*TIT;xGIT;xGI2jny
zI2jmHI2jncIT;u{IT;u{I2jn^I2jmZI2joJa4;~u<X~WU&cVR&jDvyUDF*|?8V&}A
zRU8Zq-5d-Iog54d9UKe{!5j<>fgB7B>KqIVA{-11LL3YXf*cGCSJ@dDF0(T*OkrnW
zn8eP&Fp-^sA(@?lA(5Sd!IqtY!J3_c!HS)M;VK&g!(}!GhIMQV4DD<T43TUM4Ek&g
z3_n;I7{0SIFg#>sVA#mYz|hFbz!1dBz~IQrz+l44z#zfOz#zoR!0?BKf#DYm1H(@i
z28JCh3=G>?7#M0<7#KWQ7#Q4H7#P@D7#LVt7#LVs7#Q|5GcfFBW?*P$W?=AThNKT~
zW(EcoW(EcpW(EdkW(Ec(P?}+8V7SA?z;KI+f#E0<1H)k^28M%73=B({7#RAQ7#R9s
z14~4veFX&t1-Ja7+{BWS)FK6~G!T;kn_!88t%8PIei4HL2x8TRS0B^{1_cHNLh1;~
zgI%hrK+qhhx}^O4oYcg;c(C6}tih%`=jRqA7A2PC7b$2ZgW0Jd{~-%&D!?>C6<9M=
zGi2tKD1cVW#6#sYk~0!P!Iqhms-pms%*o74)dA~N&?-tTF3l-{@lq=aQj<$kQ#2VE
zYQb(ON-ZfZ$^#pxkp?yZq8X+Qra?ym>Hr-Dh!-@iiS>GMNl|8AI_W-#>Vw*g;_>2=
zA{?HE1O?3X5FX4A=$=;0ERIhtEKSU@1_uQsKtRc^peQr1Buzu9AhEbOH6<obNfW9<
zAvLEsRiPTJ9HbC}p|TJTn1lq8Mp9{7T53@|%zhmOh`Th=^g}}wrW~S3M**fyQwOdd
z=CHKH%$(E|gc1eSVjYF_{1OG#;+Q-oi2BSl1qBVb7c~{CA@Kz>B3d;$7Ub3%1=V6J
z)f6iQB^`z2c$nRYqyY6CI3!{63bqQcpi{6{P!CgAuu@QuP=^E(C;`G{ZDGkq17<SZ
zR}j_3C5a`O$qHcO(Sj@5(7?bT7N;_ZfiOjgT!ABDl;vlpAaVnQ2Xl*#0&<>%CO938
zBB=zPfM9`GV{50NTCAZ73Ur0E(!Au7%=|n}P*Me3keQcR0$$e^50leK&d)0@fp}L7
zCWv9IEgUF>xCVzPWacTT7Axo?+Xc?5a09T}n3<D`Y8zM!Ui+bi0VE!v0T1;mL`+9P
zNmVHz$g|YUL`g|UL8~k=r!*DpUvLC!m1gFZn3=?vKr=fuDqwnHvM_yUWe~(PLj_w~
zr~)I9w?N4WrZFBGH5xDhs6s;>1vC*OO$Id6A&$W1sRAV(g@TeIB(D^d6k+!TIA*m#
ziqUK+C@BIvzM!NC?sAYRFh|2R8tN#(*&v5P3La?SYe5Tj1$zahkfPF5B?T)5CAY+!
z;#4J2a6rNtss`r3`1r(<lA_F{(vsBpcnyuxywc*-6irQNGK2UWRs%q_!qXg@wO}8>
z+yM6mR1-Y>L3{<6Dnm4*L0&?wUEF*_;{8H>d^8|MI#MV@1W5A-BnTin;og9RA*euu
zdI)4!a&7^L%FIhQ)KP$FFwz92F9T?)R*PPsLp2*f(g{>LGfe?z3`jG`Ckiz+Fau#i
zpb{2jKL|sOF@zX{O~0BNHvN!N4B}FFU?cn2PzM^R5H+BnE~zX?O-W6Iii285kXDYS
z0yO)<Qk$kV157O_Q)wW|JWT}+NP<LC%D|bDuTZT3&HhU863JG<B{eOzs3<i>!L_I;
zzevGKK^0U*>L}zT#ixQqG_4hC70NR}<&S|TgK|o0T4r9Vf{Ux0YfzA@OT24PkbjT{
zT(Lq70|O_Pf-)XlX2!>BTEmU-^z#gf2Nj6%ZlQk8A)fwz8k*?ZLAJ)nyLtM!#>eX@
z;5Wq6#}#ToEdwVf%tZ>?w(z1HT5A<YXT~BbTM$pvnv;{0GlqdPEx$-XqcpELGd(Xg
z1>E?`RIpVruvW-auu&+^tV*?3$kf)>RHz222kC%?2iPAW@s2@3j*%L$f*cWuI$+JP
z7DF+T?V6mR5CgaWV1=FrvX6Z{{lI>Q)Q<>_h^PQt9qQ>9VrCK_0`(%2I&hGJ%`Ye^
zBFE@}kRW`ff(nn+#5{6LcJlZ4adq^=XF8~9NJel3<8(75rzzM%^Q(eAjA5mq1S$%Y
z;OP^+m;(i*a%Ns~PH9T2f=zKrN@l)Zh8+W{P+keDSY}=cD3=zaib5QLE|vlcN{}Gj
z3Gwm4zK%XVkX+)ypq!bO2PzxTghBm(6J7>}1-y{;|FHS}_52JBYxx-%)<FCFnfwe4
z#{3KnjQk7?4EziX2lyBm_VF<=?1lF8OZgZWtoRrhnE4nOnD`hNR`D`0tl(u}SO_(H
zKFE9``+%d$MnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(M23KJYF<ia8tNb#s7H=6
zMT0a7stN1tBa0zMx1l4Dq)*+z1{k0NbdcdJ#JCZjX)Cx+sNJBkOVFqj$QSW2N$3C-
zWU>Jy3z>U@j77n`1mVFv10V2%4zYpELkSg_HkbwqCayq(w~(0}5<Cvlgw4;Ou@uNi
a9#y@o0SY!PP3X*$4s0M#6Fz%{&Hn%&q=H-k

-- 
GitLab


From b5b2cf76a91d0956ac085173b3e1297e69dc039a Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 24 Jan 2023 15:13:12 +0000
Subject: [PATCH 059/229] add ignore vim files

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 2721f47..6aa6785 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,5 @@ src/captors.h
 tests/run
 bin
 obj
+*.swp
+*.swo
-- 
GitLab


From 09e8fc5ab8e5b36ef1c7d14b4196990843a0bcd4 Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Tue, 24 Jan 2023 17:22:51 +0100
Subject: [PATCH 060/229] late commit fix registres acc

---
 .vscode/settings.json | 5 +++++
 src/counters.c        | 4 +++-
 src/network.c         | 3 ++-
 src/rapl.c            | 3 ++-
 src/util.c            | 6 +++---
 5 files changed, 15 insertions(+), 6 deletions(-)
 create mode 100644 .vscode/settings.json

diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..480615b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,5 @@
+{
+    "files.associations": {
+        "util.h": "c"
+    }
+}
\ No newline at end of file
diff --git a/src/counters.c b/src/counters.c
index de00d62..874e6fc 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -27,6 +27,8 @@
 #include <stdint.h>
 #include <asm/unistd.h>
 #include <stdint.h>
+#include "util.h"
+
 
 struct _counter_t {
     int nbcores;
@@ -217,7 +219,7 @@ unsigned int get_counters(uint64_t *results, void *ptr)
     _get_counters(state, state->tmp_counters_values);
 
     for (int i = 0; i < state->nbperf; i++) {
-        results[i] = state->tmp_counters_values[i] - state->counters_values[i];
+        results[i] = modulo_substraction(state->tmp_counters_values[i], state->counters_values[i]);
     }
 
     memcpy(state->counters_values, state->tmp_counters_values, state->nbperf * sizeof(uint64_t));
diff --git a/src/network.c b/src/network.c
index f57a383..bee3e5a 100644
--- a/src/network.c
+++ b/src/network.c
@@ -23,6 +23,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <stdint.h>
+#include "util.h"
 
 #define NB_SENSOR 4
 #define UNUSED(expr) do { (void)(expr); } while (0)
@@ -112,7 +113,7 @@ unsigned int get_network(uint64_t *results, void *ptr)
     _get_network(state->tmp_values, state->sources);
 
     for (int i = 0; i < NB_SENSOR; i++) {
-        results[i] = state->tmp_values[i] - state->values[i];
+        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
     }
 
     memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
diff --git a/src/rapl.c b/src/rapl.c
index cd558d2..26e9854 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -25,6 +25,7 @@
 #include <fcntl.h>
 #include <inttypes.h>
 #include <errno.h>
+#include "util.h"
 
 
 #define MAX_HEADER 128
@@ -167,7 +168,7 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
     _get_rapl(state->tmp_values, state);
 
     for (unsigned int i = 0; i < state->nb; i++) {
-        results[i] = state->tmp_values[i] - state->values[i];
+        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
     }
 
     memcpy(state->values, state->tmp_values, sizeof(uint64_t)*state->nb);
diff --git a/src/util.c b/src/util.c
index 7efa66f..71928c4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -20,8 +20,8 @@
 
 #include "util.h"
 
-uint64_t modulo_substraction(uint64_t previous, uint64_t new)
+uint64_t uint64_t modulo_substraction(const uint64_t l, const uint64_t r)
 {
-    return new >= previous ? (new - previous)
-           : (UINT64_MAX - previous + 1) + new;
+    return l >= r ? (l - r)
+           : (UINT64_MAX - r + 1) + l;
 }
-- 
GitLab


From 8c8bed402e1b9ea46bf4e902b162bb6dd1e6699b Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Tue, 24 Jan 2023 17:37:52 +0100
Subject: [PATCH 061/229] fix build util + format

---
 makefile   | 3 ++-
 src/util.c | 2 +-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/makefile b/makefile
index f92c57a..d3d470f 100644
--- a/makefile
+++ b/makefile
@@ -14,7 +14,8 @@ OBJ =  \
 	$(OBJ_DIR)/network.o \
 	$(OBJ_DIR)/load.o \
 	$(OBJ_DIR)/infiniband.o \
-	$(OBJ_DIR)/temperature.o
+	$(OBJ_DIR)/temperature.o \
+	$(OBJ_DIR)/util.o
 
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
diff --git a/src/util.c b/src/util.c
index 71928c4..e7324e6 100644
--- a/src/util.c
+++ b/src/util.c
@@ -20,7 +20,7 @@
 
 #include "util.h"
 
-uint64_t uint64_t modulo_substraction(const uint64_t l, const uint64_t r)
+uint64_t modulo_substraction(const uint64_t l, const uint64_t r)
 {
     return l >= r ? (l - r)
            : (UINT64_MAX - r + 1) + l;
-- 
GitLab


From 70da6bd39077135cd21b43c24d5bf04c45da6f0d Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Wed, 25 Jan 2023 10:23:17 +0100
Subject: [PATCH 062/229] format

---
 .gitignore            | 14 +++++++-------
 .vscode/settings.json |  8 ++++----
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/.gitignore b/.gitignore
index 6aa6785..37d1e63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,7 @@
-src/counters_option.h
-src/captors.h
-tests/run
-bin
-obj
-*.swp
-*.swo
+src/counters_option.h
+src/captors.h
+tests/run
+bin
+obj
+*.swp
+*.swo
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 480615b..bf13b61 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,5 +1,5 @@
-{
-    "files.associations": {
-        "util.h": "c"
-    }
+{
+    "files.associations": {
+        "util.h": "c"
+    }
 }
\ No newline at end of file
-- 
GitLab


From b18cbdcb7225d95e25ca7ec0e139d225208ae75f Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Wed, 25 Jan 2023 10:33:01 +0100
Subject: [PATCH 063/229] mod_subst doc + fix

---
 src/util.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/util.c b/src/util.c
index e7324e6..936a704 100644
--- a/src/util.c
+++ b/src/util.c
@@ -20,8 +20,15 @@
 
 #include "util.h"
 
-uint64_t modulo_substraction(const uint64_t l, const uint64_t r)
+/**
+ * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs, 
+ * meaning that if lhs is greater, rhs's value overflowed.
+ * @param lhs 
+ * @param rhs 
+ * @return uint64_t 
+ */
+uint64_t modulo_substraction(const uint64_t lhs, const uint64_t rhs)
 {
-    return l >= r ? (l - r)
-           : (UINT64_MAX - r + 1) + l;
+    return rhs >= lhs ? (rhs - lhs)
+           : (UINT64_MAX - lhs + 1) + rhs;
 }
-- 
GitLab


From 37f3ea271952fbed80c3f1c31b87f0c622cf0d84 Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Wed, 25 Jan 2023 10:35:30 +0100
Subject: [PATCH 064/229] ignore .vscode

---
 .gitignore            | 1 +
 .vscode/settings.json | 5 -----
 2 files changed, 1 insertion(+), 5 deletions(-)
 delete mode 100644 .vscode/settings.json

diff --git a/.gitignore b/.gitignore
index 37d1e63..8110229 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@ bin
 obj
 *.swp
 *.swo
+.vscode
diff --git a/.vscode/settings.json b/.vscode/settings.json
deleted file mode 100644
index bf13b61..0000000
--- a/.vscode/settings.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-    "files.associations": {
-        "util.h": "c"
-    }
-}
\ No newline at end of file
-- 
GitLab


From 6d780a6f57df660413ba345d3e68602c7dcd0222 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 09:41:58 +0000
Subject: [PATCH 065/229] split code

---
 tests/small_test.h | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index b93cd7b..774d497 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -7,8 +7,17 @@
 #include <stdint.h>
 #include <stdio.h>
 
-#define FMT_NULL(string) \
-	string = string ? string : "NULL"
+
+// ---------------------------API_INTERFACE
+
+#define INIT_TEST_FILE() \
+	init_test_file(__FILE__, __func__);
+
+#define INIT_TEST_FUNCTION() \
+	init_test_function(__func__);
+
+#define DEFERRED_ERROR(nb_error) \
+	do { printf("========== Deferred Error : %d\n", nb_error); } while(0)
 
 #define TEST_STR(result, expected) \
 	test_str(__FILE__, __LINE__, result, expected)
@@ -27,14 +36,11 @@
 		nb_error += function(results[i], expecteds[i]);				\
 	}
 
-#define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__);
 
-#define INIT_TEST_FUNCTION() \
-	init_test_function(__func__);
+// --------------------------------API_CODE
 
-#define DEFERRED_ERROR(nb_error) \
-	do { printf("========== Deferred Error : %d\n", nb_error); } while(0)
+#define FMT_NULL(string) \
+	string = string ? string : "NULL"
 
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
-- 
GitLab


From fb5aceb534d213df0665c359f8d7d718089ae472 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 09:50:29 +0000
Subject: [PATCH 066/229] fix interface

---
 tests/small_test.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 774d497..9e5842d 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -11,13 +11,13 @@
 // ---------------------------API_INTERFACE
 
 #define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__);
+	init_test_file(__FILE__, __func__)
 
 #define INIT_TEST_FUNCTION() \
-	init_test_function(__func__);
+	init_test_function(__func__)
 
 #define DEFERRED_ERROR(nb_error) \
-	do { printf("========== Deferred Error : %d\n", nb_error); } while(0)
+	printf("========== Deferred Error : %d\n", nb_error)
 
 #define TEST_STR(result, expected) \
 	test_str(__FILE__, __LINE__, result, expected)
-- 
GitLab


From 293c73b40a191d92b7ccbef4198f25d9843c3153 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 09:58:48 +0000
Subject: [PATCH 067/229] change test flags

---
 makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/makefile b/makefile
index d3d470f..f7779a6 100644
--- a/makefile
+++ b/makefile
@@ -52,7 +52,7 @@ debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
 debug: all
 
 tests:
-	gcc -Wall -Wextra -Wpedantic $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
+	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
 	$(TESTS_DIR)/run
 
 format:
-- 
GitLab


From 3f358f242077732e267dfc53a5625b45db593d53 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 20:17:46 +0000
Subject: [PATCH 068/229] move doc .c to .h

---
 src/util.c | 8 +-------
 src/util.h | 8 ++++++++
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/src/util.c b/src/util.c
index 936a704..e473d01 100644
--- a/src/util.c
+++ b/src/util.c
@@ -20,13 +20,7 @@
 
 #include "util.h"
 
-/**
- * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs, 
- * meaning that if lhs is greater, rhs's value overflowed.
- * @param lhs 
- * @param rhs 
- * @return uint64_t 
- */
+
 uint64_t modulo_substraction(const uint64_t lhs, const uint64_t rhs)
 {
     return rhs >= lhs ? (rhs - lhs)
diff --git a/src/util.h b/src/util.h
index 991c71e..099c903 100644
--- a/src/util.h
+++ b/src/util.h
@@ -44,6 +44,14 @@
         exit(code);                          \
     } while (0)
 
+
+/**
+ * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs, 
+ * meaning that if lhs is greater, rhs's value overflowed.
+ * @param lhs 
+ * @param rhs 
+ * @return uint64_t 
+ */
 uint64_t modulo_substraction(const uint64_t l, const uint64_t r);
 
 #endif
-- 
GitLab


From 08cf1f376b868b5d0caed236cab0e5b82cdbb407 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 20:45:35 +0000
Subject: [PATCH 069/229] format

---
 src/util.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/util.h b/src/util.h
index 099c903..fe6584b 100644
--- a/src/util.h
+++ b/src/util.h
@@ -46,11 +46,11 @@
 
 
 /**
- * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs, 
+ * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,
  * meaning that if lhs is greater, rhs's value overflowed.
- * @param lhs 
- * @param rhs 
- * @return uint64_t 
+ * @param lhs
+ * @param rhs
+ * @return uint64_t
  */
 uint64_t modulo_substraction(const uint64_t l, const uint64_t r);
 
-- 
GitLab


From e73132cf555541805c4f2462384f21f873960d1b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 20:45:46 +0000
Subject: [PATCH 070/229] add doc

---
 tests/small_test.h | 107 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 107 insertions(+)

diff --git a/tests/small_test.h b/tests/small_test.h
index 9e5842d..1cdb700 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -10,27 +10,134 @@
 
 // ---------------------------API_INTERFACE
 
+/**
+ * @def INIT_TEST_FILE()
+ * @brief Initialize the test file
+ * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
+ *
+ * @param __FILE__ preprocessor macro that provides the name of the current file
+ * @param __func__ preprocessor macro that provides the name of the current function
+ *
+ * @code
+ * INIT_TEST_FILE();
+ * @endcode
+ */
 #define INIT_TEST_FILE() \
 	init_test_file(__FILE__, __func__)
 
+/**
+ * @def INIT_TEST_FUNCTION()
+ * @brief Initialize the test function
+ * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
+ *
+ * @param __func__ preprocessor macro that provides the name of the current function
+ *
+ * @code
+ * INIT_TEST_FUNCTION();
+ * @endcode
+ */
 #define INIT_TEST_FUNCTION() \
 	init_test_function(__func__)
 
+/**
+ * @def DEFERRED_ERROR(nb_error)
+ * @brief Print deferred errors
+ * This macro is used to print deferred errors. It takes a single argument, `nb_error`, which is the number of errors encountered during the test.
+ *
+ * @param nb_error the number of errors encountered during the test
+ *
+ * @code
+ * DEFERRED_ERROR(5);
+ * @endcode
+ */
 #define DEFERRED_ERROR(nb_error) \
 	printf("========== Deferred Error : %d\n", nb_error)
 
+/**
+ * @def TEST_STR(result, expected)
+ * @brief Test strings
+ * This macro is used to test strings. It takes two arguments: `result`, which is the string to be tested, and `expected`, which is the expected value of the string.
+ * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ *
+ * @param result the string to be tested
+ * @param expected the expected value of the string
+ *
+ * @code
+ * TEST_STR("Hello", "Hello");
+ * @endcode
+ */
 #define TEST_STR(result, expected) \
 	test_str(__FILE__, __LINE__, result, expected)
 
+/**
+ * @def TEST_BOOLEAN(result, expected)
+ * @brief Test booleans
+ * This macro is used to test booleans. It takes two arguments: `result`, which is the boolean to be tested, and `expected`, which is the expected value of the boolean.
+ * The macro uses the `test_boolean()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ *
+ * @param result the boolean to be tested
+ * @param expected the expected value of the boolean
+ *
+ * @code
+ * TEST_BOOLEAN(1 == 1, true);
+ * @endcode
+ */
 #define TEST_BOOLEAN(result, expected) \
 	test_boolean(__FILE__, __LINE__, result, expected)
 
+/**
+ * @def TEST_PTR(result, expected)
+ * @brief Test pointers
+ * This macro is used to test pointers. It takes two arguments: `result`, which is the pointer to be tested, and `expected`, which is the expected value of the pointer.
+ * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ *
+ * @param result the pointer to be tested
+ * @param expected the expected value of the pointer
+ *
+ * @code
+ * int x = 5;
+ * int *ptr = &x;
+ * TEST_PTR(ptr, &x);
+ * @endcode
+ */
 #define TEST_PTR(result, expected) \
 	test_ptr(__FILE__, __LINE__, result, expected)
 
+
+/**
+ * @def TEST_UINT64_T(result, expected)
+ * @brief Test 64-bit unsigned integers
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `result`, which is the integer to be tested, and `expected`, which is the expected value of the integer.
+ * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ *
+ * @param result the integer to be tested
+ * @param expected the expected value of the integer
+ *
+ * @code
+ * TEST_UINT64_T(5, 5);
+ * @endcode
+ */
 #define TEST_UINT64_T(result, expected) \
 	test_uint64_t(__FILE__, __LINE__, result, expected)
 
+/**
+ * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
+ * @brief Test arrays of data
+ * The macro uses a for loop to iterate through the array and apply the test function to each element,
+ * adding any errors to the nb_error variable.
+ *
+ * @param function the test function to be used on each element of the array
+ * @param nb_error the number of errors encountered during the test
+ * @param size the number of elements in the array
+ * @param results the array of elements to be tested
+ * @param expecteds the array of expected values
+
+ * @code
+ * int results[3] = {1, 2, 3};
+ * int expecteds[3] = {1, 2, 3};
+ * TEST_T_ARRAY(TEST_INT, errors, 3, results, expecteds);
+ * @endcode
+*/
 #define TEST_T_ARRAY(function, nb_error, size, results, expecteds)	\
 	for (unsigned int i = 0; i < size; i++) {						\
 		nb_error += function(results[i], expecteds[i]);				\
-- 
GitLab


From da14a2d94922ed8ea93e207f7bfd818a5e4f2f11 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 21:34:14 +0000
Subject: [PATCH 071/229] delete redefinitions of macros

---
 makefile          |  2 +-
 src/infiniband.c  |  4 +---
 src/load.c        |  2 +-
 src/mojitos.c     | 10 +---------
 src/network.c     |  1 -
 src/rapl.c        |  3 ---
 src/temperature.c |  3 +--
 7 files changed, 5 insertions(+), 20 deletions(-)

diff --git a/makefile b/makefile
index f7779a6..07c7e4f 100644
--- a/makefile
+++ b/makefile
@@ -63,6 +63,6 @@ format:
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
 	\rm -f $(SRC_DIR)/counters_option.h
-	\rm $(TESTS_DIR)/run
+	\rm -f $(TESTS_DIR)/run
 
 .PHONY: all clean mojitos debug format tests
diff --git a/src/infiniband.c b/src/infiniband.c
index 6f47ab2..303795e 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -21,13 +21,11 @@
 #include <fcntl.h>
 #include <stdio.h>
 #include <string.h>
-
 #include <glob.h>
-
 #include <stdint.h>
+#include "util.h"
 
 #define NB_SENSOR 4
-#define UNUSED(expr) do { (void)(expr); } while (0)
 
 struct network_t {
     uint64_t values[NB_SENSOR];
diff --git a/src/load.c b/src/load.c
index 96d08b8..6dcf2b0 100644
--- a/src/load.c
+++ b/src/load.c
@@ -23,9 +23,9 @@
 #include <stdint.h>
 #include <string.h>
 #include <stdio.h>
+#include "util.h"
 
 #define LOAD_BUFFER_SIZE 1024
-#define UNUSED(expr) do { (void)(expr); } while (0)
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid = -1;
diff --git a/src/mojitos.c b/src/mojitos.c
index 55af9f5..3c164c6 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <time.h>
 #include <unistd.h>
+#include "util.h"
 
 #define NB_MAX_OPTS 10
 #define NB_MAX_CAPTORS 20
@@ -33,15 +34,6 @@
 #define OPTPARSE_API static
 #include "optparse.h"
 
-#define UNUSED(expr) do { (void)(expr); } while (0)
-#define PANIC(code, fmt, ...)  				 \
-	do {									 \
-		fprintf(stderr, "Exit on error: ");  \
-		fprintf(stderr, fmt, ##__VA_ARGS__); \
-		fprintf(stderr, "\n"); 			     \
-		exit(code); 						 \
-	} while (0)
-
 typedef unsigned int (*initializer_t)(char *, void **);
 typedef void (*labeler_t)(char **, void *);
 typedef unsigned int (*getter_t)(uint64_t *, void *);
diff --git a/src/network.c b/src/network.c
index bee3e5a..543a053 100644
--- a/src/network.c
+++ b/src/network.c
@@ -26,7 +26,6 @@
 #include "util.h"
 
 #define NB_SENSOR 4
-#define UNUSED(expr) do { (void)(expr); } while (0)
 
 static char *route = "/proc/net/route";
 struct network_t {
diff --git a/src/rapl.c b/src/rapl.c
index 26e9854..8a04d31 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -27,10 +27,7 @@
 #include <errno.h>
 #include "util.h"
 
-
 #define MAX_HEADER 128
-#define UNUSED(expr) do { (void)(expr); } while (0)
-
 
 char *get_rapl_string(const char *filename)
 {
diff --git a/src/temperature.c b/src/temperature.c
index 049ade7..acc0702 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -24,8 +24,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <stdint.h>
-
-#define UNUSED(expr) do { (void)(expr); } while (0)
+#include "util.h"
 
 struct temperature_t {
     char **label_list;
-- 
GitLab


From 1a3157b0107b270137de33518e857110873bfbe3 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Wed, 25 Jan 2023 22:38:47 +0000
Subject: [PATCH 072/229] cleanup

---
 src/amd_rapl.c | 200 +------------------------------------------------
 src/util.h     |   6 --
 2 files changed, 3 insertions(+), 203 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 238161c..26d1446 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <assert.h>
 
 #include "info_reader.h"
 #include "util.h"
@@ -269,30 +270,6 @@ void free_amd_rapl(_amd_rapl_t *rapl)
 
 unsigned int init_amd_rapl(char *none, void **ptr)
 {
-// 	FILE *fcpuinfo = fopen(cpuinfo, "r");
-// 	if (fcpuinfo == NULL) {
-// 		perror("fopen");
-// 		exit(1);
-// 	}
-//     Parser parser = {
-//         (GenericPointer) cpus,
-// 		0,
-//         MAX_CPUS,
-//         sizeof(cpu_sensor_t),
-//         keys,
-// 		NB_KEYS,
-// 		fcpuinfo
-//     };
-//     parse(&parser);
-// 	fclose(fcpuinfo);
-
-// #ifdef DEBUG
-// 	printf("nb_cpus: %d\n", parser.nb_stored);
-// 	for (unsigned int nb_cpu = 0; nb_cpu < parser.nb_stored; ++nb_cpu) {
-// 		debug_print_sensor(&cpus[nb_cpu]);
-// 	}
-// #endif
-
     UNUSED(none);
     _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
@@ -320,7 +297,6 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
     for (unsigned int i = 0; i < rapl->nb; i++) {
-        DEBUG_WARNING("check if unit is the same")
         results[i] = get_core_energy(&rapl->sensors[i]);
     }
     return rapl->nb;
@@ -347,179 +323,9 @@ void clean_amd_rapl(void *ptr)
 
 
 #ifdef __TESTING_AMD__
-#include "small_test.h"
-
-void test_raw_to_microjoule()
-{
-    printf("==== TEST raw_to_microjoule() ====\n");
-    uint64_t raw = 0;
-    uint64_t unit = 0;
-    uint64_t result = 0;
-    uint64_t expected = 0;
-
-    // Test 1:
-    // -- Setup
-    raw = 100;
-    unit = 0;
-    expected = 100000000;
-    // -- Run
-    result = raw_to_microjoule(raw, unit);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-
-    // TEST 2:
-    // -- Setup
-    raw = 200;
-    unit = 1;
-    expected = 100000000;
-    // -- Run
-    result = raw_to_microjoule(raw, unit);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-
-    // TEST 3:
-    // -- Setup
-    raw = 500;
-    unit = 2;
-    expected = 125000000;
-    // -- Run
-    result = raw_to_microjoule(raw, unit);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-
-    // TEST 4:
-    // -- Setup
-    raw = 1000;
-    unit = 3;
-    expected = 125000000;
-    // -- Run
-    result = raw_to_microjoule(raw, unit);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-
-    // TEST 5:
-    // -- Setup
-    raw = 10000;
-    unit = 4;
-    expected = 625000000;
-    // -- Run
-    result = raw_to_microjoule(raw, unit);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-}
-
-void test_get_name()
-{
-    printf("==== TEST get_name() ====\n");
-    size_t cpu_id = 0;
-    char *result = NULL;
-    char expected[100];
-
-    // TEST 1:
-    // -- Setup
-    cpu_id = 0;
-    strcpy(expected, "core0");
-    // -- Run
-    result = get_name(cpu_id);
-    // -- Verification
-    TEST_STR(result, expected);
-    free(result);
-
-    // TEST 2:
-    // -- Setup
-    cpu_id = 10000;
-    strcpy(expected, "core10000");
-    // -- Run
-    result = get_name(cpu_id);
-    // -- Verification
-    TEST_STR(result, expected);
-    free(result);
-}
-
-#define NONE 0
-#define DUMB_SENSOR(sensor, cpu_id, name)	\
-	do {									\
-		sensor = (cpu_sensor_t) {			\
-			cpu_id,							\
-			NONE,							\
-			name,							\
-			NONE,							\
-			NONE,							\
-			NONE, 							\
-			NONE							\
-		}; 									\
-	} while(0);
-
-#define DUMB_RAPL(rapl, sensors, nb)		\
-	do {									\
-		rapl = (_amd_rapl_t) {				\
-			sensors,						\
-			nb								\
-		};									\
-	} while(0);
-
-void test_label_amd_rapl()
-{
-    printf("==== TEST label_amd_rapl() ====\n");
-    cpu_sensor_t sensors[100];
-    _amd_rapl_t rapl;
-    char *results[100];
-    char expecteds[10][100];
-    uint64_t nb = 0;
-
-    // Test 1:
-    // -- Setup
-    nb = 1;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_RAPL(rapl, sensors, nb);
-    strcpy(expecteds[0], "core0");
-    // -- Run
-    label_amd_rapl(results, (void *) &rapl);
-    // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
-
-    // Test 2:
-    // -- Setup
-    nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 1, "core1");
-    DUMB_SENSOR(sensors[2], 2, "core2");
-    DUMB_SENSOR(sensors[3], 3, "core3");
-    DUMB_RAPL(rapl, sensors, nb);
-    strcpy(expecteds[0], "core0");
-    strcpy(expecteds[1], "core1");
-    strcpy(expecteds[2], "core2");
-    strcpy(expecteds[3], "core3");
-    // -- Run
-    label_amd_rapl(results, (void *) &rapl);
-    // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
-
-    // Test 3:
-    // -- Setup
-    nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 3, "core3");
-    DUMB_SENSOR(sensors[2], 1, "core1");
-    DUMB_SENSOR(sensors[3], 2, "core2");
-    DUMB_RAPL(rapl, sensors, nb);
-    strcpy(expecteds[0], "core0");
-    strcpy(expecteds[1], "core3");
-    strcpy(expecteds[2], "core1");
-    strcpy(expecteds[3], "core2");
-    // -- Run
-    label_amd_rapl(results, (void *) &rapl);
-    // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
-}
-
-
+#ifdef DEBUG
 int main()
 {
-    test_raw_to_microjoule();
-    test_get_name();
-    test_label_amd_rapl();
-
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
     unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
@@ -548,5 +354,5 @@ int main()
     clean_amd_rapl(rapl);
     return 0;
 }
-
+#endif
 #endif
diff --git a/src/util.h b/src/util.h
index fe6584b..6e510fb 100644
--- a/src/util.h
+++ b/src/util.h
@@ -29,12 +29,6 @@
 #define _impl_CASSERT_LINE(predicate, line, file) \
     typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1];
 
-#ifdef DEBUG
-#define DEBUG_WARNING(warning) #warning warning
-#else
-#define DEBUG_WARNING(warning) do { } while(0);
-#endif
-
 #define UNUSED(expr) do { (void)(expr); } while (0)
 #define PANIC(code, fmt, ...)                \
     do {                                     \
-- 
GitLab


From 3a2df456a3b08d6a010fe2debcc07c0ca68102be Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 30 Jan 2023 07:07:39 +0000
Subject: [PATCH 073/229] format

---
 src/amd_rapl.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 26d1446..c06bb29 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -258,15 +258,13 @@ void clean_cpu_sensor(cpu_sensor_t *sensor)
     free(sensor->name);
 }
 
-// ----------------------AMD_RAPL_INTERFACE
-
-
 void free_amd_rapl(_amd_rapl_t *rapl)
 {
     free(rapl->sensors);
     free(rapl);
 }
 
+// ----------------------AMD_RAPL_INTERFACE
 
 unsigned int init_amd_rapl(char *none, void **ptr)
 {
-- 
GitLab


From 8cb79df658c60b6c30d59f04f723f46aee48ea98 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 30 Jan 2023 09:34:07 +0100
Subject: [PATCH 074/229] build: change how captors are initialised

---
 configure.sh  | 105 +++++++++++++++++++++++++++++++-------------------
 src/mojitos.c |  27 ++++++-------
 2 files changed, 80 insertions(+), 52 deletions(-)

diff --git a/configure.sh b/configure.sh
index 6a957ff..2d21bf5 100755
--- a/configure.sh
+++ b/configure.sh
@@ -10,34 +10,52 @@ isnum() {
 	*) return 0 ;;
 	esac
 }
+dprint() {
+	for v in "$@"; do
+		decho "$v : $(eval "echo \$$v")"
+	done
+}
+decho() {
+	[ "$debug" = '1' ] && echo "$@"
+}
 
+debug=0
 target=src/captors.h
 
-noncaptor='counters_option|optparse|captors'
+noncaptor='counters_option|optparse|captors|util|info_reader'
 
 hdr_blacklist=$noncaptor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>]\n' "$(basename "$0")" >&2
+	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>] [-u <captor>]\n' "$(basename "$0")" >&2
 	printf -- '-e | --exclude      :   exclude captor, can be called multiple times\n' >&2
 	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
 	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
+	printf -- '-u | --unique       :   only include the specified captor\n' >&2
+	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
 	exit 1
 }
 
 ls_captors() {
 	try cd src
-	printf -- 'captors:\n' >&2
+
+	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
+	dprint hdr_blacklist
+	dprint hdr_whitelist
+
 	ls -1 *.h |
-		grep -vE "^($hdr_blacklist)\.h$" |
-		grep -E  "^($hdr_whitelist)\.h$" |
-		sed 's/\.h$//' |
-		tee /dev/stderr
+		grep -xEv "($hdr_blacklist)\.h" |
+		grep -xE  "($hdr_whitelist)\.h" |
+		sed 's/\.h$//'
 }
 
 gen_captors_h() {
 	captors=$(ls_captors)
+	nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+	printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
+	printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
+	echo "$captors" >&2
 
 	[ -n "$captors" ] || return
 
@@ -45,17 +63,50 @@ gen_captors_h() {
 	for captor in $captors; do
 		printf '#include "%s.h"\n' "$captor"
 	done
-	printf '\n'
+	printf '\n#define NB_CAPTORS %d\n\n' "$nb_captors"
 
 	# gen `init_captors()`
-	printf 'void init_captors()\n{\n'
+	printf 'void init_captors(struct optparse_long *longopts, struct captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
 	for captor in $captors; do
-		printf '    longopts[NB_MAX_OPTS + nb_defined_captors] = %s_opt;\n' "$captor"
-		printf '    captors[nb_defined_captors++] = %s;\n' "$captor"
+		printf '    longopts[offset + *nb_defined] = %s_opt;\n' "$captor"
+		printf '    captors[(*nb_defined)++] = %s;\n' "$captor"
 	done
+	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
+detect_caps() {
+	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
+	[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
+	[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
+
+	if [ -r /proc/net/route ]; then
+		dev=$(awk 'NR == 2 { print $1 }' /proc/net/route)
+		[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
+	fi
+
+	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
+	vendor_lc=$(echo "$vendor" | tr 'A-Z' 'a-z')
+	case $vendor_lc in
+	*intel*)
+		hdr_whitelist="${hdr_whitelist}|rapl"
+		;;
+	*amd*)
+		family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
+		if isnum "$family"; then
+			[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
+		fi
+		;;
+	*)
+		yell "unsupported processor vendor id: $vendor"
+		;;
+	esac
+
+	[ $(ls -1 /sys/class/hwmon | wc -l) -gt 0 ] && hdr_whitelist="${hdr_whitelist}|temperature"
+}
+
+detect_caps
+
 while [ "$1" ]; do
 	case $1 in
 	--include|-i)
@@ -70,6 +121,10 @@ while [ "$1" ]; do
 		ls_captors
 		exit 0
 		;;
+	--unique|-u)
+		shift; [ "$1" ] || usage
+		hdr_whitelist=$1
+		;;
 	--help|-h)
 		usage
 		;;
@@ -77,32 +132,4 @@ while [ "$1" ]; do
 	shift
 done
 
-[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
-[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
-[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
-
-if [ -r /proc/net/route ]; then
-	dev=$(awk 'NR == 2 { print $1 }' /proc/net/route)
-	[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
-fi
-
-vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
-vendor_lc=$(echo "$vendor" | tr 'A-Z' 'a-z')
-case $vendor_lc in
-*intel*)
-	hdr_whitelist="${hdr_whitelist}|rapl"
-	;;
-*amd*)
-	family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
-	if isnum "$family"; then
-		[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
-	fi
-	;;
-*)
-	yell "unsupported processor vendor id: $vendor"
-	;;
-esac
-
-[ $(ls -1 /sys/class/hwmon | wc -l) -gt 0 ] && hdr_whitelist="${hdr_whitelist}|temperature"
-
 gen_captors_h > "$target"
diff --git a/src/mojitos.c b/src/mojitos.c
index 3c164c6..dc113fc 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -19,6 +19,7 @@
 
  *******************************************************/
 
+#include <assert.h>
 #include <inttypes.h>
 #include <signal.h>
 #include <stdio.h>
@@ -27,9 +28,6 @@
 #include <unistd.h>
 #include "util.h"
 
-#define NB_MAX_OPTS 10
-#define NB_MAX_CAPTORS 20
-
 #define OPTPARSE_IMPLEMENTATION
 #define OPTPARSE_API static
 #include "optparse.h"
@@ -48,9 +46,14 @@ struct captor {
     labeler_t label;
 };
 
-struct captor captors[NB_MAX_CAPTORS];
+int nb_defined_captors = 0;
+
+#include "captors.h"
+
+struct captor captors[NB_CAPTORS];
 
-struct optparse_long longopts[NB_MAX_OPTS + NB_MAX_CAPTORS] = {
+#define NB_OPTS 6
+struct optparse_long longopts[NB_OPTS + NB_CAPTORS + 1] = {
     {"overhead-stats", 's', OPTPARSE_NONE},
     {"list", 'l', OPTPARSE_NONE},
     {"freq", 'f', OPTPARSE_REQUIRED},
@@ -59,16 +62,14 @@ struct optparse_long longopts[NB_MAX_OPTS + NB_MAX_CAPTORS] = {
     {"logfile", 'o', OPTPARSE_REQUIRED},
 };
 
-int nb_defined_captors = 0;
-
-#include "captors.h"
 
 void usage(char **argv)
 {
     printf("Usage : %s [OPTIONS] [CAPTOR ...] [-o logfile] [-e cmd ...]\n"
            "\nOPTIONS:\n"
-           "-t <time>\n"
-           "-f <freq>\n"
+           "-t <time>\t\tspecify time\n"
+           "-f <freq>\t\tspecify frequency\n"
+           "-e <cmd>\t\tspecify a command\n"
            "-l\t\tlist the possible performance counters and quit\n"
            "-s\t\tenable overhead statistics in nanoseconds\n"
            "if time==0 then loops infinitively\n"
@@ -83,7 +84,7 @@ void usage(char **argv)
     printf("\nCAPTORS:\n");
 
     for (int i = 0; i < nb_defined_captors; i++) {
-        printf("-%c", longopts[NB_MAX_OPTS + i].shortname);
+        printf("-%c", longopts[NB_OPTS + i].shortname);
         if (captors[i].usage_arg != NULL) {
             printf(" %s", captors[i].usage_arg);
         }
@@ -159,7 +160,7 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors();
+    init_captors(longopts, captors, NB_OPTS + NB_CAPTORS, NB_OPTS, &nb_defined_captors);
 
     if (argc == 1) {
         usage(argv);
@@ -207,7 +208,7 @@ int main(int argc, char **argv)
         default: {
             int ismatch = 0;
             for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                if (opt == longopts[NB_MAX_OPTS + i].shortname) {
+                if (opt == longopts[NB_OPTS + i].shortname) {
                     ismatch = 1;
                     add_source(&captors[i], options.optarg);
                 }
-- 
GitLab


From 30f3885e9da6d0b6ab4cf0ba6a8b79e318911a7c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 30 Jan 2023 09:21:50 +0000
Subject: [PATCH 075/229] compile with amd

---
 makefile       |  3 ++-
 src/amd_rapl.c | 12 ++++++++----
 src/amd_rapl.h | 10 ++++++++++
 3 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/makefile b/makefile
index 07c7e4f..eabffaf 100644
--- a/makefile
+++ b/makefile
@@ -15,7 +15,8 @@ OBJ =  \
 	$(OBJ_DIR)/load.o \
 	$(OBJ_DIR)/infiniband.o \
 	$(OBJ_DIR)/temperature.o \
-	$(OBJ_DIR)/util.o
+	$(OBJ_DIR)/util.o \
+	$(OBJ_DIR)/amd_rapl.o 
 
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index c06bb29..eca6831 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -29,7 +29,6 @@
 
 #include "info_reader.h"
 #include "util.h"
-#include "amd_rapl.h"
 
 #define BUFFER_SIZE 64
 
@@ -100,7 +99,7 @@ uint64_t read_msr(int fd, uint64_t msr)
 {
     uint64_t data;
     if (pread(fd, &data, sizeof data, msr) != sizeof data) {
-        fprintf(stderr, "msr(%ld):", msr);
+        fprintf(stderr, "read_msr(%ld):", msr);
         perror("pread");
         exit(127);
     }
@@ -217,7 +216,9 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        perror("rdmsr:open");
+        fprintf(stderr, "open(");
+        fprintf(stderr, base_str, cpu_id);
+        perror(")");
         exit(127);
     }
 
@@ -273,7 +274,9 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int nb_cpu = get_nb_cpu();
     if (nb_cpu == 0) {
-        perror("get_nb_cpu");
+        fprintf(stderr, "open(");
+        fprintf(stderr, base_str,0);
+        perror(")");
         exit(127);
     }
 
@@ -319,6 +322,7 @@ void clean_amd_rapl(void *ptr)
     free(rapl);
 }
 
+// -----------------------------ENTRY_POINT
 
 #ifdef __TESTING_AMD__
 #ifdef DEBUG
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 459c136..4f375b9 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -22,3 +22,13 @@ unsigned int init_amd_rapl(char *, void **);
 unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
+
+struct optparse_long amd_rapl_opt = {"amd_rapl", 'a', OPTPARSE_NONE};
+struct captor amd_rapl = {
+    .usage_arg = NULL,
+    .usage_msg = "AMD_RAPL",
+    .init = init_amd_rapl,
+    .get = get_amd_rapl,
+    .clean = clean_amd_rapl,
+    .label = label_amd_rapl,
+};
-- 
GitLab


From eb2a21a7c30e8da64ee7db24558a8e39ba797be4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 07:08:21 +0000
Subject: [PATCH 076/229] update test lib

---
 tests/amd_rapl.c    |  78 ++++++++++-----------------
 tests/info_reader.c | 129 ++++++++++++++++++--------------------------
 tests/main.c        |  19 +++----
 tests/small_test.h  | 122 ++++++++++++++++++++++++++++-------------
 tests/util.c        |  25 ++++-----
 5 files changed, 180 insertions(+), 193 deletions(-)

diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 1ddf234..25408f1 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -1,11 +1,7 @@
 #include "small_test.h"
 #include "../src/amd_rapl.c"
 
-int test_raw_to_microjoule()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
-
+TFUNCTION(test_raw_to_microjoule, {
     uint64_t raw = 0;
     uint64_t unit = 0;
     uint64_t result = 0;
@@ -19,9 +15,9 @@ int test_raw_to_microjoule()
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-    nb_error += TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
-    // nb_error += TEST 2:
+    // TEST 2:
     // -- Setup
     raw = 200;
     unit = 1;
@@ -29,9 +25,9 @@ int test_raw_to_microjoule()
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-    nb_error += TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
-    // nb_error += TEST 3:
+    // TEST 3:
     // -- Setup
     raw = 500;
     unit = 2;
@@ -39,9 +35,9 @@ int test_raw_to_microjoule()
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-    nb_error += TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
-    // nb_error += TEST 4:
+    // TEST 4:
     // -- Setup
     raw = 1000;
     unit = 3;
@@ -49,9 +45,9 @@ int test_raw_to_microjoule()
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-    nb_error += TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
-    // nb_error += TEST 5:
+    // TEST 5:
     // -- Setup
     raw = 10000;
     unit = 4;
@@ -59,42 +55,34 @@ int test_raw_to_microjoule()
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-    nb_error += TEST_UINT64_T(&result, &expected);
-
-    return nb_error;
-}
-
-int test_get_name()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+    TEST_UINT64_T(&result, &expected);
+})
 
+TFUNCTION(test_get_name, {
     size_t cpu_id = 0;
     char *result = NULL;
     char expected[100];
 
-    // nb_error += TEST 1:
+    // TEST 1:
     // -- Setup
     cpu_id = 0;
     strcpy(expected, "core0");
     // -- Run
     result = get_name(cpu_id);
     // -- Verification
-    nb_error += TEST_STR(result, expected);
+    TEST_STR(result, expected);
     free(result);
 
-    // nb_error += TEST 2:
+    // TEST 2:
     // -- Setup
     cpu_id = 10000;
     strcpy(expected, "core10000");
     // -- Run
     result = get_name(cpu_id);
     // -- Verification
-    nb_error += TEST_STR(result, expected);
+    TEST_STR(result, expected);
     free(result);
-
-    return nb_error;
-}
+})
 
 #define NONE 0
 #define DUMB_SENSOR(sensor, cpu_id, name)	\
@@ -118,10 +106,7 @@ int test_get_name()
 		};									\
 	} while(0);
 
-int test_label_amd_rapl()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+TFUNCTION(test_label_amd_rapl, {
     cpu_sensor_t sensors[100];
     _amd_rapl_t rapl;
     char *results[100];
@@ -137,7 +122,7 @@ int test_label_amd_rapl()
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 2:
     // -- Setup
@@ -154,7 +139,7 @@ int test_label_amd_rapl()
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 3:
     // -- Setup
@@ -171,21 +156,14 @@ int test_label_amd_rapl()
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb_error, nb, results, expecteds);
-
-    return nb_error;
-}
-
-int test_amd_rapl()
-{
-    INIT_TEST_FILE();
-
-    int nb_error = 0;
-    nb_error += test_raw_to_microjoule();
-    nb_error += test_get_name();
-    nb_error += test_label_amd_rapl();
-    return nb_error;
-}
+    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+})
+
+TFILE_ENTRY_POINT(test_amd_rapl, {
+    CALL_TFUNCTION(test_raw_to_microjoule);
+    CALL_TFUNCTION(test_get_name);
+    CALL_TFUNCTION(test_label_amd_rapl);
+})
 
 #ifdef __TESTING__AMD__
 int main()
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 3953109..761d86a 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,71 +1,57 @@
 #include "small_test.h"
 
-int test_replace_first()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
-
+TFUNCTION(test_replace_first, {
     char test1[] = "This is my string";
     replace_first(test1, 'i', 'I');
-    nb_error += TEST_STR(test1, "ThIs is my string");
+    TEST_STR(test1, "ThIs is my string");
 
     char test2[] = "This is my string";
     replace_first(test2, 'x', 'X');
-    nb_error += TEST_STR(test2, "This is my string");
+    TEST_STR(test2, "This is my string");
 
 
     char test3[] = "This is my string";
     replace_first(test3, ' ', '_');
-    nb_error += TEST_STR(test3, "This_is my string");
-    return nb_error;
-}
-
-int test_split_on_delimiter()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+    TEST_STR(test3, "This_is my string");
+})
 
+TFUNCTION(test_split_on_delimiter, {
     char test4[] = "key:value";
     char *key;
     char *value;
+
     split_on_delimiter(test4, ":", &key, &value);
-    nb_error += TEST_STR(key, "key");
-    nb_error += TEST_STR(value, "value");
+    TEST_STR(key, "key");
+    TEST_STR(value, "value");
 
     char test5[] = "key: value";
     split_on_delimiter(test5, ":", &key, &value);
-    nb_error += TEST_STR(key, "key");
-    nb_error += TEST_STR(value, " value");
+    TEST_STR(key, "key");
+    TEST_STR(value, " value");
 
     char test6[] = "key:value";
     replace_first(test6, ':', ' ');
     split_on_delimiter(test6, " ", &key, &value);
-    nb_error += TEST_STR(key, "key");
-    nb_error += TEST_STR(value, "value");
+    TEST_STR(key, "key");
+    TEST_STR(value, "value");
 
     char test7[] = "";
     split_on_delimiter(test7, ":", &key, &value);
-    nb_error += TEST_STR(key, NULL);
-    nb_error += TEST_STR(value, NULL);
+    TEST_STR(key, NULL);
+    TEST_STR(value, NULL);
 
     char test9[] = "key:value:extra";
     split_on_delimiter(test9, ":", &key, &value);
-    nb_error += TEST_STR(key, "key");
-    nb_error += TEST_STR(value, "value:extra");
+    TEST_STR(key, "key");
+    TEST_STR(value, "value:extra");
 
     char test10[] = "key: value :extra";
     split_on_delimiter(test10, ":", &key, &value);
-    nb_error += TEST_STR(key, "key");
-    nb_error += TEST_STR(value, " value :extra");
-
-    return nb_error;
-}
-
-int test_start_with()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+    TEST_STR(key, "key");
+    TEST_STR(value, " value :extra");
+})
 
+TFUNCTION(test_start_with, {
     char *prefix = NULL;
     char *string = NULL;
     bool result = false;
@@ -75,30 +61,28 @@ int test_start_with()
     prefix = "Hello";
     string = "Hello World";
     result = start_with(prefix, string);
-    nb_error += TEST_BOOLEAN(&result, &_true);
+    TEST_BOOLEAN(&result, &_true);
 
     prefix = "Goodbye";
     string = "Hello World";
     result = start_with(prefix, string);
-    nb_error += TEST_BOOLEAN(&result, &_false);
+    TEST_BOOLEAN(&result, &_false);
 
     prefix = "Hello World";
     string = "Hello";
     result = start_with(prefix, string);
-    nb_error += TEST_BOOLEAN(&result, &_false);
+    TEST_BOOLEAN(&result, &_false);
 
     prefix = "Hello";
     string = "Hello";
     result = start_with(prefix, string);
-    nb_error += TEST_BOOLEAN(&result, &_true);
+    TEST_BOOLEAN(&result, &_true);
 
     prefix = NULL;
     string = "Hello World";
     result = start_with(prefix, string);
-    nb_error += TEST_BOOLEAN(&result, &_false);
-
-    return nb_error;
-}
+    TEST_BOOLEAN(&result, &_false);
+})
 
 #define DUMB_KEYFINDER(key_finder, key, delimiter)  \
 	do { 											\
@@ -124,10 +108,7 @@ int test_start_with()
 	} while (0);
 
 
-int test_match()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+TFUNCTION(test_match, {
     // usefull variable :
     bool _true = true;
     bool _false = false;
@@ -148,9 +129,9 @@ int test_match()
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    nb_error += TEST_BOOLEAN(&result, &_true);
-    nb_error += TEST_PTR(found_key_finder, &keys[0]);
-    nb_error += TEST_STR(raw_value, "value");
+    TEST_BOOLEAN(&result, &_true);
+    TEST_PTR(found_key_finder, &keys[0]);
+    TEST_STR(raw_value, "value");
 
     // Test 2:
     // -- Setup
@@ -162,9 +143,9 @@ int test_match()
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    nb_error += TEST_BOOLEAN(&result, &_false);
-    nb_error += TEST_PTR(found_key_finder, NULL);
-    nb_error += TEST_STR(raw_value, NULL);
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
 
     // Test 3:
     // -- Setup
@@ -176,9 +157,9 @@ int test_match()
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    nb_error += TEST_BOOLEAN(&result, &_false);
-    nb_error += TEST_PTR(found_key_finder, NULL);
-    nb_error += TEST_STR(raw_value, NULL);
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
 
     // Test 4:
     // -- Setup
@@ -191,9 +172,9 @@ int test_match()
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    nb_error += TEST_BOOLEAN(&result, &_true);
-    nb_error += TEST_PTR(found_key_finder, &keys[1]);
-    nb_error += TEST_STR(raw_value, "value");
+    TEST_BOOLEAN(&result, &_true);
+    TEST_PTR(found_key_finder, &keys[1]);
+    TEST_STR(raw_value, "value");
 
     // Test 5:
     // -- Setup
@@ -204,25 +185,17 @@ int test_match()
     raw_value = NULL;
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
-    nb_error += TEST_BOOLEAN(&result, &_false);
-    nb_error += TEST_PTR(found_key_finder, NULL);
-    nb_error += TEST_STR(raw_value, NULL);
-
-    return nb_error;
-}
-
-int test_info_reader()
-{
-    INIT_TEST_FILE();
-    int nb_error = 0;
-
-    nb_error += test_replace_first();
-    nb_error += test_split_on_delimiter();
-    nb_error += test_start_with();
-    nb_error += test_match();
-
-    return nb_error;
-}
+    TEST_BOOLEAN(&result, &_false);
+    TEST_PTR(found_key_finder, NULL);
+    TEST_STR(raw_value, NULL);
+})
+
+TFILE_ENTRY_POINT(test_info_reader, {
+    CALL_TFUNCTION(test_replace_first);
+    CALL_TFUNCTION(test_split_on_delimiter);
+    CALL_TFUNCTION(test_start_with);
+    CALL_TFUNCTION(test_match);
+})
 
 #ifdef __TESTING_INFO_READER__
 int main()
diff --git a/tests/main.c b/tests/main.c
index b14f518..a3a43cb 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,16 +1,9 @@
-#include "amd_rapl.c"
 #include "util.c"
+#include "amd_rapl.c"
 #include "info_reader.c"
 
-int main()
-{
-    int nb_error = 0;
-
-    nb_error += test_amd_rapl();
-    nb_error += test_info_reader();
-    nb_error += test_util();
-
-    DEFERRED_ERROR(nb_error);
-    return nb_error;
-}
-
+TFILE_ENTRY_POINT(main, {
+    CALL_TFUNCTION(test_util);
+    CALL_TFUNCTION(test_amd_rapl);
+    CALL_TFUNCTION(test_info_reader);
+})
diff --git a/tests/small_test.h b/tests/small_test.h
index 1cdb700..0e39868 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -7,51 +7,66 @@
 #include <stdint.h>
 #include <stdio.h>
 
-
 // ---------------------------API_INTERFACE
 
 /**
- * @def INIT_TEST_FILE()
- * @brief Initialize the test file
- * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
+ * @brief Define the entry point of a test file.
+ * This macro is used to define the entry point of a test file.
+ * It defines a function with the specified file_name that contains the test code specified in code.
  *
- * @param __FILE__ preprocessor macro that provides the name of the current file
- * @param __func__ preprocessor macro that provides the name of the current function
+ * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
+ * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
+ * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
+ * The function returns the value of __error_counter__,
+ * which indicates the number of errors encountered during the tests.
  *
- * @code
- * INIT_TEST_FILE();
- * @endcode
+ * @param file_name The name of the function that serves as the entry point for the test file.
+ * @param code The test code to be executed in the function.
  */
-#define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__)
+#define TFILE_ENTRY_POINT(file_name, code) \
+  int file_name() \
+{ \
+  INIT_TEST_FILE();\
+  int __error_counter__ = 0;\
+  do code while(0);\
+  DEFERRED_FILE_ERROR(__error_counter__); \
+  return __error_counter__;\
+}
 
 /**
- * @def INIT_TEST_FUNCTION()
- * @brief Initialize the test function
- * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
+ * @brief Define a test function within a test file.
+ * This macro is used to define a test function within a test file.
+ * It defines a function with the specified function_name that contains the test code specified in code.
  *
- * @param __func__ preprocessor macro that provides the name of the current function
+ * When the function is called, it initializes the test function using the INIT_TEST_FUNCTION macro,
+ * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
+ * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
+ * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
  *
- * @code
- * INIT_TEST_FUNCTION();
- * @endcode
+ * @param function_name The name of the test function.
+ * @param code The test code to be executed in the function.
  */
-#define INIT_TEST_FUNCTION() \
-	init_test_function(__func__)
+#define TFUNCTION(function_name, code) \
+  int function_name() \
+{ \
+  INIT_TEST_FUNCTION(); \
+  int __error_counter__ = 0; \
+  do code while(0); \
+  DEFERRED_FUNCTION_ERROR(__error_counter__); \
+  return __error_counter__; \
+}
 
 /**
- * @def DEFERRED_ERROR(nb_error)
- * @brief Print deferred errors
- * This macro is used to print deferred errors. It takes a single argument, `nb_error`, which is the number of errors encountered during the test.
+ * @brief Call a test function within a test file.
+ * This macro is used to call a test function within a test file.
+ * It calls the function specified by function_name and adds the return value to the __error_counter__ variable.
+ * This allows multiple test functions to be executed and their error count to be accumulated.
  *
- * @param nb_error the number of errors encountered during the test
- *
- * @code
- * DEFERRED_ERROR(5);
- * @endcode
+ * @param function_name The name of the test function to be called.
  */
-#define DEFERRED_ERROR(nb_error) \
-	printf("========== Deferred Error : %d\n", nb_error)
+#define CALL_TFUNCTION(function_name) \
+  __error_counter__ += function_name()
+
 
 /**
  * @def TEST_STR(result, expected)
@@ -67,7 +82,7 @@
  * @endcode
  */
 #define TEST_STR(result, expected) \
-	test_str(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_str(__FILE__, __LINE__, result, expected)
 
 /**
  * @def TEST_BOOLEAN(result, expected)
@@ -83,7 +98,7 @@
  * @endcode
  */
 #define TEST_BOOLEAN(result, expected) \
-	test_boolean(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_boolean(__FILE__, __LINE__, result, expected)
 
 /**
  * @def TEST_PTR(result, expected)
@@ -101,7 +116,7 @@
  * @endcode
  */
 #define TEST_PTR(result, expected) \
-	test_ptr(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_ptr(__FILE__, __LINE__, result, expected)
 
 
 /**
@@ -118,7 +133,7 @@
  * @endcode
  */
 #define TEST_UINT64_T(result, expected) \
-	test_uint64_t(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_uint64_t(__FILE__, __LINE__, result, expected)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
@@ -138,14 +153,49 @@
  * TEST_T_ARRAY(TEST_INT, errors, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(function, nb_error, size, results, expecteds)	\
+#define TEST_T_ARRAY(function, size, results, expecteds)	\
 	for (unsigned int i = 0; i < size; i++) {						\
-		nb_error += function(results[i], expecteds[i]);				\
+		function(results[i], expecteds[i]);				\
 	}
 
 
 // --------------------------------API_CODE
 
+/**
+ * @def INIT_TEST_FILE()
+ * @brief Initialize the test file
+ * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
+ *
+ * @param __FILE__ preprocessor macro that provides the name of the current file
+ * @param __func__ preprocessor macro that provides the name of the current function
+ *
+ * @code
+ * INIT_TEST_FILE();
+ * @endcode
+ */
+#define INIT_TEST_FILE() \
+	init_test_file(__FILE__, __func__)
+
+/**
+ * @def INIT_TEST_FUNCTION()
+ * @brief Initialize the test function
+ * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
+ *
+ * @param __func__ preprocessor macro that provides the name of the current function
+ *
+ * @code
+ * INIT_TEST_FUNCTION();
+ * @endcode
+ */
+#define INIT_TEST_FUNCTION() \
+	init_test_function(__func__)
+
+#define DEFERRED_FILE_ERROR(nb_error) \
+	  printf("========== Deferred Error : %d\n", nb_error);
+
+#define DEFERRED_FUNCTION_ERROR(nb_error) \
+	  printf("       | Deferred Error : %d\n", nb_error);
+
 #define FMT_NULL(string) \
 	string = string ? string : "NULL"
 
diff --git a/tests/util.c b/tests/util.c
index eba4da3..2416049 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -2,10 +2,7 @@
 #include "small_test.h"
 
 
-int test_modulo_substraction()
-{
-    INIT_TEST_FUNCTION();
-    int nb_error = 0;
+TFUNCTION(test_modulo_substraction, {
     uint64_t previous = 0;
     uint64_t new = 0;
     uint64_t result = 0;
@@ -19,7 +16,7 @@ int test_modulo_substraction()
     // -- Run
     result = modulo_substraction(previous, new);
     // -- Verification
-    nb_error = TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
     // Test 2:
     // -- Setup
@@ -29,7 +26,7 @@ int test_modulo_substraction()
     // -- Run
     result = modulo_substraction(previous, new);
     // -- Verification
-    nb_error = TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
     // Test 3:
     // -- Setup
@@ -39,7 +36,7 @@ int test_modulo_substraction()
     // -- Run
     result = modulo_substraction(previous, new);
     // -- Verification
-    nb_error = TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
 
     // Test 4:
     // -- Setup
@@ -49,13 +46,9 @@ int test_modulo_substraction()
     // -- Run
     result = modulo_substraction(previous, new);
     // -- Verification
-    nb_error = TEST_UINT64_T(&result, &expected);
+    TEST_UINT64_T(&result, &expected);
+})
 
-    return nb_error;
-}
-int test_util()
-{
-    INIT_TEST_FILE();
-    int nb_error = test_modulo_substraction();
-    return nb_error;
-}
+TFILE_ENTRY_POINT(test_util, {
+    CALL_TFUNCTION(test_modulo_substraction);
+})
-- 
GitLab


From d3f4897ac40194204c35b55cf2ab2d579f607ab9 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 08:58:16 +0000
Subject: [PATCH 077/229] patch conversion

---
 src/amd_rapl.c   | 35 +++++++++++++++++++----------------
 tests/amd_rapl.c |  8 ++++----
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index eca6831..0eeb2d2 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -26,6 +26,7 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <assert.h>
+#include <math.h>
 
 #include "info_reader.h"
 #include "util.h"
@@ -108,19 +109,19 @@ uint64_t read_msr(int fd, uint64_t msr)
 
 uint64_t read_unit(int fd)
 {
-    u_int64_t unit = read_msr(fd, msr_rapl_power_unit);
+    uint64_t unit = read_msr(fd, msr_rapl_power_unit);
     return ((unit & amd_energy_unit_mask) >> 8);
 }
 
 uint64_t read_raw_core_energy(int fd)
 {
-    u_int64_t energy = read_msr(fd, energy_core_msr);
+    uint64_t energy = read_msr(fd, energy_core_msr);
     return energy & amd_energy_mask;
 }
 
 uint64_t read_raw_pkg_energy(int fd)
 {
-    u_int64_t energy = read_msr(fd, energy_pkg_msr);
+    uint64_t energy = read_msr(fd, energy_pkg_msr);
     return energy & amd_energy_mask;
 }
 
@@ -128,11 +129,12 @@ uint64_t read_raw_pkg_energy(int fd)
 
 uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
 {
-    static const uint64_t to_microjoule = 1000000UL;
+    static const double to_microjoule = 1000000.0;
+    double d_raw = (double) raw;
+    double d_unit = (double) unit;
     // raw * (1 / (unit^2)) -> Joule
     // Joule * 1000000 -> uJoule
-    uint64_t microjoule = (raw * to_microjoule) / (1UL << unit);
-    return microjoule;
+    return  ((d_raw * to_microjoule) / (d_unit * d_unit));
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
@@ -222,8 +224,8 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
         exit(127);
     }
 
-    u_int64_t raw_core_energy = read_raw_core_energy(fd);
-    u_int64_t raw_pkg_energy = read_raw_pkg_energy(fd);
+    uint64_t raw_core_energy = read_raw_core_energy(fd);
+    uint64_t raw_pkg_energy = read_raw_pkg_energy(fd);
 
     sensor->cpu_id = cpu_id;
     sensor->name = get_name(cpu_id);
@@ -233,22 +235,22 @@ void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
     sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
 }
 
-u_int64_t get_core_energy(cpu_sensor_t *sensor)
+uint64_t get_core_energy(cpu_sensor_t *sensor)
 {
-    u_int64_t raw_core_energy = read_raw_core_energy(sensor->fd);
-    u_int64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
+    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
+    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
 
-    u_int64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
+    uint64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
     sensor->core_energy = core_energy;
     return energy_consumed;
 }
 
-u_int64_t get_pkg_energy(cpu_sensor_t *sensor)
+uint64_t get_pkg_energy(cpu_sensor_t *sensor)
 {
-    u_int64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
-    u_int64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
+    uint64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
+    uint64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
 
-    u_int64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
+    uint64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
     sensor->pkg_energy = pkg_energy;
     return energy_consumed;
 }
@@ -328,6 +330,7 @@ void clean_amd_rapl(void *ptr)
 #ifdef DEBUG
 int main()
 {
+    s_round_to_uint64(1.0);
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
     unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 25408f1..3f97f32 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -10,8 +10,8 @@ TFUNCTION(test_raw_to_microjoule, {
     // Test 1:
     // -- Setup
     raw = 100;
-    unit = 0;
-    expected = 100000000;
+    unit = 1000;
+    expected = 100;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -21,7 +21,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 200;
     unit = 1;
-    expected = 100000000;
+    expected = 200000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -41,7 +41,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 1000;
     unit = 3;
-    expected = 125000000;
+    expected = 111111111;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-- 
GitLab


From 7235a17559222838681c350646667d3d87cd15fb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 10:13:55 +0000
Subject: [PATCH 078/229] fix: doc incompatible with definition

---
 src/amd_rapl.c |  4 ++--
 src/util.c     |  4 ++--
 src/util.h     |  4 ++--
 tests/util.c   | 40 ++++++++++++++++++++++++----------------
 4 files changed, 30 insertions(+), 22 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0eeb2d2..09ea7c0 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -240,7 +240,7 @@ uint64_t get_core_energy(cpu_sensor_t *sensor)
     uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
     uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
 
-    uint64_t energy_consumed = modulo_substraction(sensor->core_energy, core_energy);
+    uint64_t energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
     sensor->core_energy = core_energy;
     return energy_consumed;
 }
@@ -250,7 +250,7 @@ uint64_t get_pkg_energy(cpu_sensor_t *sensor)
     uint64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
     uint64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
 
-    uint64_t energy_consumed = modulo_substraction(sensor->pkg_energy, pkg_energy);
+    uint64_t energy_consumed = modulo_substraction(pkg_energy, sensor->pkg_energy);
     sensor->pkg_energy = pkg_energy;
     return energy_consumed;
 }
diff --git a/src/util.c b/src/util.c
index e473d01..5e835a7 100644
--- a/src/util.c
+++ b/src/util.c
@@ -23,6 +23,6 @@
 
 uint64_t modulo_substraction(const uint64_t lhs, const uint64_t rhs)
 {
-    return rhs >= lhs ? (rhs - lhs)
-           : (UINT64_MAX - lhs + 1) + rhs;
+    return lhs >= rhs ? (lhs - rhs)
+           : (UINT64_MAX - rhs + 1) + lhs;
 }
diff --git a/src/util.h b/src/util.h
index 6e510fb..23978c1 100644
--- a/src/util.h
+++ b/src/util.h
@@ -41,11 +41,11 @@
 
 /**
  * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,
- * meaning that if lhs is greater, rhs's value overflowed.
+ * meaning that if rhs is greater, lhs's value overflowed.
  * @param lhs
  * @param rhs
  * @return uint64_t
  */
-uint64_t modulo_substraction(const uint64_t l, const uint64_t r);
+uint64_t modulo_substraction(const uint64_t lhs, const uint64_t rhs);
 
 #endif
diff --git a/tests/util.c b/tests/util.c
index 2416049..a91c58f 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -3,50 +3,58 @@
 
 
 TFUNCTION(test_modulo_substraction, {
-    uint64_t previous = 0;
-    uint64_t new = 0;
+    uint64_t lhs = 0;
+    uint64_t rhs = 0;
     uint64_t result = 0;
     uint64_t expected = 0;
 
     // Test 1:
     // -- Setup
-    previous = 10;
-    new = 10;
+    lhs = 10;
+    rhs = 10;
     expected = 0;
     // -- Run
-    result = modulo_substraction(previous, new);
+    result = modulo_substraction(lhs, rhs);
     // -- Verification
     TEST_UINT64_T(&result, &expected);
 
     // Test 2:
     // -- Setup
-    previous = UINT64_MAX;
-    new = 0;
-    expected = 1;
+    lhs = UINT64_MAX;
+    rhs = 0;
+    expected = UINT64_MAX;
     // -- Run
-    result = modulo_substraction(previous, new);
+    result = modulo_substraction(lhs, rhs);
     // -- Verification
     TEST_UINT64_T(&result, &expected);
 
     // Test 3:
     // -- Setup
-    previous = 0;
-    new = UINT64_MAX;
-    expected = UINT64_MAX;
+    lhs = 0;
+    rhs = UINT64_MAX;
+    expected = 1;
     // -- Run
-    result = modulo_substraction(previous, new);
+    result = modulo_substraction(lhs, rhs);
     // -- Verification
     TEST_UINT64_T(&result, &expected);
 
     // Test 4:
     // -- Setup
-    previous = 20;
-    new = 10;
+    lhs = 10;
+    rhs = 20;
     expected = UINT64_MAX - 9;
     // -- Run
-    result = modulo_substraction(previous, new);
+    result = modulo_substraction(lhs, rhs);
     // -- Verification
     TEST_UINT64_T(&result, &expected);
+
+    // Test 5:
+    // -- Setup
+    lhs = 1000;
+    rhs = 1000;
+    expected = 0;
+    result = modulo_substraction(lhs, rhs);
+    TEST_UINT64_T(&result, &expected);
 })
 
 TFILE_ENTRY_POINT(test_util, {
-- 
GitLab


From 093e6696fb64b16f04d799170f9c1cb9059a1f4c Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 12:39:47 +0100
Subject: [PATCH 079/229] build: support for multiple options per captor

- Makefile now includes captors.mk which defines captor object files to
  build (the previous behaviour was to build all captors regardless of
  the captor selection during configuration)
- correct a bug in configure.sh : now properly detect amd cpu family
- configure.sh now print an error when 0 captors are selected
- configure.sh now do a `make clean` on successful configuration
---
 .gitignore        |  17 ++++----
 configure.sh      |  71 ++++++++++++++++++++++++--------
 makefile          |  14 +++----
 src/amd_rapl.h    |  16 ++++++--
 src/counters.h    |  29 +++++++++----
 src/infiniband.h  |  17 ++++++--
 src/load.h        |  16 ++++++--
 src/mojitos.c     | 101 ++++++++++++++++++++++++++++++----------------
 src/network.h     |  15 +++++--
 src/optparse.h    |   2 +
 src/rapl.h        |  16 ++++++--
 src/temperature.h |  16 ++++++--
 12 files changed, 232 insertions(+), 98 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8110229..095c70a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,9 @@
-src/counters_option.h
-src/captors.h
-tests/run
-bin
-obj
-*.swp
-*.swo
-.vscode
+tests/run
+src/counters_option.h
+src/captors.h
+captors.mk
+bin
+obj
+*.swp
+*.swo
+.vscode
diff --git a/configure.sh b/configure.sh
index 2d21bf5..49e1789 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,7 +20,8 @@ decho() {
 }
 
 debug=0
-target=src/captors.h
+target_hdr=src/captors.h
+target_mk=captors.mk
 
 noncaptor='counters_option|optparse|captors|util|info_reader'
 
@@ -41,8 +42,8 @@ ls_captors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
-	dprint hdr_blacklist
-	dprint hdr_whitelist
+	dprint hdr_blacklist >&2
+	dprint hdr_whitelist >&2
 
 	ls -1 *.h |
 		grep -xEv "($hdr_blacklist)\.h" |
@@ -50,31 +51,53 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
+# gen_captors_h(captors, nb_captors)
 gen_captors_h() {
-	captors=$(ls_captors)
-	nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
-	printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-	printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-	echo "$captors" >&2
-
-	[ -n "$captors" ] || return
+	captors=$1
+	nb_captors=$2
+	nb_captor_opts=$(
+		for captor in $captors; do
+			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+		done |
+			paste -s -d '+' |
+			bc
+	)
+
+	dprint captors >&2
+	dprint nb_captor_opts >&2
+	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
 
 	# gen includes
 	for captor in $captors; do
 		printf '#include "%s.h"\n' "$captor"
 	done
-	printf '\n#define NB_CAPTORS %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
 
 	# gen `init_captors()`
-	printf 'void init_captors(struct optparse_long *longopts, struct captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf '    int opt_idx = offset;\n'
 	for captor in $captors; do
-		printf '    longopts[offset + *nb_defined] = %s_opt;\n' "$captor"
-		printf '    captors[(*nb_defined)++] = %s;\n' "$captor"
+		cat <<-!
+		    for (int i = 0; i < ${captor}.nb_opt; i++) {
+		        longopts[opt_idx++] = ${captor}_opt[i];
+		    }
+		    captors[(*nb_defined)++] = ${captor};
+		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
+gen_captors_mk() {
+	captors=$1
+	printf 'CAPTOR_OBJ = '
+	for captor in $captors; do
+		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	done
+	printf '\n'
+}
+
 detect_caps() {
 	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
 	[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
@@ -92,7 +115,7 @@ detect_caps() {
 		hdr_whitelist="${hdr_whitelist}|rapl"
 		;;
 	*amd*)
-		family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
+		family=$(awk '/cpu[ \t]*family/ {print $4; exit}' /proc/cpuinfo)
 		if isnum "$family"; then
 			[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
 		fi
@@ -132,4 +155,20 @@ while [ "$1" ]; do
 	shift
 done
 
-gen_captors_h > "$target"
+captors=$(ls_captors)
+nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+
+if [ "$nb_captors" -eq 0 ]; then
+	printf -- '0 captors are selected. cannot build.\n' >&2
+	exit 1
+fi
+
+try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
+try gen_captors_mk "$captors" > "$target_mk"
+
+printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
+printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
+echo "$captors" >&2
+
+make clean >/dev/null
+
diff --git a/makefile b/makefile
index eabffaf..3f8a70b 100644
--- a/makefile
+++ b/makefile
@@ -8,15 +8,13 @@ TESTS_DIR = tests
 
 BIN = mojitos
 
+CAPTOR_OBJ =
+
+include ./captors.mk
+
 OBJ =  \
-	$(OBJ_DIR)/counters.o \
-	$(OBJ_DIR)/rapl.o \
-	$(OBJ_DIR)/network.o \
-	$(OBJ_DIR)/load.o \
-	$(OBJ_DIR)/infiniband.o \
-	$(OBJ_DIR)/temperature.o \
-	$(OBJ_DIR)/util.o \
-	$(OBJ_DIR)/amd_rapl.o 
+	$(CAPTOR_OBJ) \
+	$(OBJ_DIR)/util.o
 
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 4f375b9..90f6161 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,12 +23,20 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-struct optparse_long amd_rapl_opt = {"amd_rapl", 'a', OPTPARSE_NONE};
-struct captor amd_rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "AMD_RAPL",
+Captor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
     .label = label_amd_rapl,
+    .nb_opt = 1,
+};
+
+Optparse amd_rapl_opt[1] = {
+    {
+        .longname = "amd-rapl",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "AMD RAPL",
+    },
 };
diff --git a/src/counters.h b/src/counters.h
index 313feeb..a191e5a 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,17 +22,32 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
+void show_all_counters();
 
-struct optparse_long counters_opt = {"perf-list", 'p', OPTPARSE_REQUIRED};
-struct captor counters = {
-    .usage_arg = "<perf_list>",
-    .usage_msg = "performance counters\n"
-    "\tperf_list is a coma separated list of performance counters.\n"
-    "\tEx: instructions,cache_misses",
+Captor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
     .label = label_counters,
+    .nb_opt = 2,
+};
+
+Optparse counters_opt[2] = {
+    {
+        .longname = "perf-list",
+        .shortname = 'p',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<perf_list>",
+        .usage_msg = "performance counters\n"
+        "\tperf_list is a coma separated list of performance counters.\n"
+        "\tEx: instructions,cache_misses",
+    },
+    {
+        .longname = "list",
+        .shortname = 'l',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "list the possible performance counters and quit"
+    },
 };
 
-void show_all_counters();
diff --git a/src/infiniband.h b/src/infiniband.h
index 0f1ad11..285b2ba 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,12 +21,21 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-struct optparse_long infiniband_opt = {"monitor-infiniband", 'i', OPTPARSE_REQUIRED};
-struct captor infiniband = {
-    .usage_arg = "<infiniband_path>",
-    .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+Captor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
     .label = label_infiniband,
+    .nb_opt = 1,
 };
+
+Optparse infiniband_opt[1] = {
+    {
+        .longname = "monitor-infiniband",
+        .shortname = 'i',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<infiniband_path>",
+        .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+    },
+};
+
diff --git a/src/load.h b/src/load.h
index 366e448..c7c5575 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,12 +23,20 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-struct optparse_long load_opt = {"sysload", 'u', OPTPARSE_NONE};
-struct captor load = {
-    .usage_arg = NULL,
-    .usage_msg = "system load",
+Captor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
     .label = label_load,
+    .nb_opt = 1,
+};
+
+Optparse load_opt[1] = {
+    {
+        .longname = "sysload",
+        .shortname = 'u',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "system load",
+    },
 };
diff --git a/src/mojitos.c b/src/mojitos.c
index dc113fc..683bdfa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -37,44 +37,75 @@ typedef void (*labeler_t)(char **, void *);
 typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
-struct captor {
-    char *usage_arg;
-    char *usage_msg;
+typedef struct Opt Opt;
+typedef struct Captor Captor;
+/* optparse typedef */
+typedef struct optparse_long Optparse;
+
+struct Captor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
     labeler_t label;
+    int nb_opt;
 };
 
 int nb_defined_captors = 0;
 
 #include "captors.h"
 
-struct captor captors[NB_CAPTORS];
-
-#define NB_OPTS 6
-struct optparse_long longopts[NB_OPTS + NB_CAPTORS + 1] = {
-    {"overhead-stats", 's', OPTPARSE_NONE},
-    {"list", 'l', OPTPARSE_NONE},
-    {"freq", 'f', OPTPARSE_REQUIRED},
-    {"time", 't', OPTPARSE_REQUIRED},
-    {"exec", 'e', OPTPARSE_REQUIRED},
-    {"logfile", 'o', OPTPARSE_REQUIRED},
+Captor captors[NB_CAPTOR];
+
+#define NB_OPT 5
+Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+    {
+        .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<freq>",
+        .usage_msg = "specify frequency",
+    },
+    {
+        .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<time>",
+        .usage_msg = "specify time",
+    },
+    {
+        .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<cmd>",
+        .usage_msg = "specify a command",
+    },
+    {
+        .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<file>",
+        .usage_msg = "specify a log file",
+    },
+    {
+        .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "enable overhead statistics in nanoseconds",
+    },
 };
 
 
+void printopt(Optparse *opt)
+{
+    printf("-%c", opt->shortname);
+    printf("|--%s", opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" %s", opt->usage_arg);
+    }
+    printf("\n\t%s\n", opt->usage_msg);
+}
+
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...] [-o logfile] [-e cmd ...]\n"
-           "\nOPTIONS:\n"
-           "-t <time>\t\tspecify time\n"
-           "-f <freq>\t\tspecify frequency\n"
-           "-e <cmd>\t\tspecify a command\n"
-           "-l\t\tlist the possible performance counters and quit\n"
-           "-s\t\tenable overhead statistics in nanoseconds\n"
-           "if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n"
-           , argv[0]);
+    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+
+    printf("\nOPTIONS:\n");
+    for (int i = 0; i < NB_OPT; i++) {
+        printopt(&longopts[i]);
+    }
+    printf("if time==0 then loops infinitively\n"
+           "if -e is present, time and freq are not used\n");
 
     if (nb_defined_captors == 0) {
         // no captor to show
@@ -82,13 +113,8 @@ void usage(char **argv)
     }
 
     printf("\nCAPTORS:\n");
-
-    for (int i = 0; i < nb_defined_captors; i++) {
-        printf("-%c", longopts[NB_OPTS + i].shortname);
-        if (captors[i].usage_arg != NULL) {
-            printf(" %s", captors[i].usage_arg);
-        }
-        printf("\n\t%s\n", captors[i].usage_msg);
+    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
+        printopt(&longopts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -123,7 +149,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(struct captor *cpt, char *arg)
+void add_source(Captor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -160,7 +186,7 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPTS + NB_CAPTORS, NB_OPTS, &nb_defined_captors);
+    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
 
     if (argc == 1) {
         usage(argv);
@@ -207,10 +233,15 @@ int main(int argc, char **argv)
             break;
         default: {
             int ismatch = 0;
+            int opt_idx = NB_OPT;
             for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                if (opt == longopts[NB_OPTS + i].shortname) {
-                    ismatch = 1;
-                    add_source(&captors[i], options.optarg);
+                for (int j = 0; j < captors[i].nb_opt; j++) {
+                    if (opt == longopts[opt_idx].shortname) {
+                        ismatch = 1;
+                        add_source(&captors[i], options.optarg);
+                        break;
+                    }
+                    opt_idx++;
                 }
             }
             if (!ismatch) {
diff --git a/src/network.h b/src/network.h
index 3182587..82fcfc3 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,13 +23,20 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-struct optparse_long network_opt = {"net-dev", 'd', OPTPARSE_REQUIRED};
-struct captor network = {
-    .usage_arg = "<net_dev>",
-    .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+Captor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
     .label = label_network,
+    .nb_opt = 1,
 };
 
+Optparse network_opt[1] = {
+    {
+        .longname = "net-dev",
+        .shortname = 'd',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<net_dev>",
+        .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+    },
+};
diff --git a/src/optparse.h b/src/optparse.h
index 04e60f6..b1908d4 100644
--- a/src/optparse.h
+++ b/src/optparse.h
@@ -71,6 +71,8 @@ struct optparse_long {
     const char *longname;
     int shortname;
     enum optparse_argtype argtype;
+    char *usage_arg;
+    char *usage_msg;
 };
 
 /**
diff --git a/src/rapl.h b/src/rapl.h
index b8dc9a2..95f9fd4 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,13 +23,21 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-struct optparse_long rapl_opt = {"rapl", 'r', OPTPARSE_NONE};
-struct captor rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "RAPL",
+Captor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
     .label = label_rapl,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "rapl",
+        .shortname = 'r',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "RAPL",
+    },
 };
 
diff --git a/src/temperature.h b/src/temperature.h
index 5e8046e..ec2faef 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,12 +23,20 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-struct optparse_long temperature_opt = {"cpu-temp", 'c', OPTPARSE_NONE};
-struct captor temperature = {
-    .usage_arg = NULL,
-    .usage_msg = "processor temperature",
+Captor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
     .label = label_temperature,
+    .nb_opt = 1,
+};
+
+Optparse temperature_opt[1] = {
+    {
+        .longname = "cpu-temp",
+        .shortname = 'c',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "processor temperature"
+    },
 };
-- 
GitLab


From a334278f7599136ad24ef80da7388d2069ce2ae2 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 13:05:29 +0100
Subject: [PATCH 080/229] update documentation (doc/counter_ex.h)

---
 doc/counter_ex.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 4ab7915..5702adc 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,12 +7,20 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-struct optparse_long counters_opt = {"accumulator", 'a', OPTPARSE_NONE};
-struct captor counters = {
-    .usage_arg = NULL,
-    .usage_msg = "dumb accumulator\n"
+Captor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
     .label = label_acc,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "accumulator",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,		/* OPTPARSE_NONE / OPTPARSE_OPTIONAL / OPTPARSE_REQUIRED */
+        .usage_arg = NULL,
+        .usage_msg = "dumb accumulator",
+    },
 };
-- 
GitLab


From bc41b97dce02f936f0bdeff681941b3208b6fb9f Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 12:44:18 +0000
Subject: [PATCH 081/229] fix unit size

---
 src/amd_rapl.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 09ea7c0..31944b1 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -49,7 +49,7 @@ struct cpu_sensor_t {
     char *name;
 
     int fd;
-    uint64_t energy_units;
+    unsigned int energy_units;
     uint64_t core_energy;
     uint64_t pkg_energy;
 };
@@ -107,7 +107,7 @@ uint64_t read_msr(int fd, uint64_t msr)
     return data;
 }
 
-uint64_t read_unit(int fd)
+unsigned int read_unit(int fd)
 {
     uint64_t unit = read_msr(fd, msr_rapl_power_unit);
     return ((unit & amd_energy_unit_mask) >> 8);
@@ -127,14 +127,12 @@ uint64_t read_raw_pkg_energy(int fd)
 
 // ---------------------------------ENERGY
 
-uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
+uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
     static const double to_microjoule = 1000000.0;
-    double d_raw = (double) raw;
-    double d_unit = (double) unit;
     // raw * (1 / (unit^2)) -> Joule
     // Joule * 1000000 -> uJoule
-    return  ((d_raw * to_microjoule) / (d_unit * d_unit));
+    return (uint64_t) (((double) raw * to_microjoule) / (double)(1U << unit));
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
@@ -149,7 +147,7 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
-- 
GitLab


From c71479936bb423c408af3355a920d6691af72173 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 13:03:20 +0000
Subject: [PATCH 082/229] clear code

---
 src/amd_rapl.c   | 52 ------------------------------------------------
 tests/amd_rapl.c |  6 +++---
 2 files changed, 3 insertions(+), 55 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 31944b1..0d2ed29 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -165,20 +165,6 @@ void debug_print_amd_rapl(_amd_rapl_t *rapl)
     }
 }
 
-// typedef struct {
-//     size_t cpu_id;
-//     uint64_t *results;
-//     size_t capacity;
-// } CpuLogger;
-//
-// CpuLogger init_logger(size_t cpu_id, size_t capacity)
-// {
-//
-// }
-//
-// void log_value();
-
-
 #endif
 
 // ---------------------------AMD_RAPL_UTIL
@@ -321,41 +307,3 @@ void clean_amd_rapl(void *ptr)
     free(rapl->sensors);
     free(rapl);
 }
-
-// -----------------------------ENTRY_POINT
-
-#ifdef __TESTING_AMD__
-#ifdef DEBUG
-int main()
-{
-    s_round_to_uint64(1.0);
-    static const unsigned int time = 10;
-    _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
-
-    label_amd_rapl(labels, (void *) rapl);
-
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
-        printf("%s ", labels[i]);
-    }
-    printf("\n");
-
-    // -- Run
-
-    for (unsigned int i = 0; i < time; ++i) {
-        sleep(1);
-        get_amd_rapl(results, (void *)rapl);
-
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
-            printf("%ld ", results[j]);
-        }
-        printf("\n");
-    }
-
-    clean_amd_rapl(rapl);
-    return 0;
-}
-#endif
-#endif
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 3f97f32..ddf76ae 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -11,7 +11,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 100;
     unit = 1000;
-    expected = 100;
+    expected = 390625;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -21,7 +21,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 200;
     unit = 1;
-    expected = 200000000;
+    expected = 100000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -41,7 +41,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 1000;
     unit = 3;
-    expected = 111111111;
+    expected = 125000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-- 
GitLab


From 6eaf91e0c2641c2fdd58539b11d956e5ab3ee9d8 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 14:46:27 +0000
Subject: [PATCH 083/229] format

---
 tests/info_reader.c | 67 +++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 761d86a..9504631 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -84,28 +84,29 @@ TFUNCTION(test_start_with, {
     TEST_BOOLEAN(&result, &_false);
 })
 
-#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
-	do { 											\
-		key_finder = (KeyFinder) {					\
-			key,									\
-			delimiter,								\
-			0,										\
-			0										\
-		}; 											\
-	} while (0);
-
-#define DUMB_PARSER(parser, keys, nb_keys)  \
-	do {									\
-		parser = (Parser) {					\
-			0,			   					\
-			0,			   					\
-			0,			   					\
-			0,  							\
-			keys,			   				\
-			nb_keys, 		   				\
-			0								\
-		};							   		\
-	} while (0);
+#define NONE 0
+#define DUMMY_KEYFINDER(__key_finder, __key, __delimiter) \
+  do {                                                    \
+    __key_finder = (KeyFinder) {                          \
+      .key = __key,                                       \
+      .delimiter = __delimiter,                           \
+      .copy = NONE,                                       \
+      .set = NONE                                         \
+    };                                                    \
+  } while (0);
+
+#define DUMMY_PARSER(__parser, __keys, __nb_keys) \
+  do {                                            \
+    __parser = (Parser) {                         \
+      .storage = NONE,                            \
+      .nb_stored = NONE,                          \
+      .capacity = NONE,                           \
+      .storage_struct_size = NONE,                \
+      .keys = __keys,                             \
+      .nb_keys = __nb_keys,                       \
+      .file = NONE                                \
+    };                                            \
+  } while (0);
 
 
 TFUNCTION(test_match, {
@@ -121,8 +122,8 @@ TFUNCTION(test_match, {
 
     // Test 1:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -135,8 +136,8 @@ TFUNCTION(test_match, {
 
     // Test 2:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1)
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1)
     strcpy(line, "not a key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -149,8 +150,8 @@ TFUNCTION(test_match, {
 
     // Test 3:
     // -- Setup
-    DUMB_KEYFINDER(keys[0],"key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0],"key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key:value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -163,9 +164,9 @@ TFUNCTION(test_match, {
 
     // Test 4:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_KEYFINDER(keys[1], "second_key", ": ");
-    DUMB_PARSER(parser, keys, 2);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_KEYFINDER(keys[1], "second_key", ": ");
+    DUMMY_PARSER(parser, keys, 2);
     strcpy(line, "second_key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -178,8 +179,8 @@ TFUNCTION(test_match, {
 
     // Test 5:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "");
     found_key_finder = NULL;
     raw_value = NULL;
-- 
GitLab


From 847023900aa79ea95fea4b50be39d5e801c46c67 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 17:32:40 +0100
Subject: [PATCH 084/229] Add a generation system for README.md and
 doc/mojitos.1

- README.md can be updated via `make readme`
- doc/mojitos.1 can be generated via `make man`
- README.md is updated and doc/mojitos.1 generated on `make all`
- correct wrong translation "captor", to "sensor"
- update README.md build instructions
- mv src/optparse.h and src/info_reader.h to ./lib/
- add the possibility to execute an alternative function when parsing
  sensor options (other than `add_source()`)
---
 .gitignore                       |  5 +-
 README.md                        | 75 +++++++++++++-------------
 configure.sh                     | 91 ++++++++++++++++---------------
 doc/counter_ex.h                 |  2 +-
 doc/{mojitos.1 => mojitos.pre.1} | 41 +++-----------
 {src => lib}/info_reader.h       |  0
 {src => lib}/optparse.h          |  1 +
 makefile                         | 18 +++++--
 src/amd_rapl.h                   |  2 +-
 src/counters.c                   |  6 ++-
 src/counters.h                   |  7 +--
 src/infiniband.h                 |  2 +-
 src/load.h                       |  2 +-
 src/mojitos.c                    | 93 +++++++++++++++++++++-----------
 src/network.h                    |  2 +-
 src/rapl.h                       |  2 +-
 src/temperature.h                |  2 +-
 tools/update-readme-usage.sh     | 27 ++++++++++
 18 files changed, 214 insertions(+), 164 deletions(-)
 rename doc/{mojitos.1 => mojitos.pre.1} (69%)
 rename {src => lib}/info_reader.h (100%)
 rename {src => lib}/optparse.h (99%)
 create mode 100755 tools/update-readme-usage.sh

diff --git a/.gitignore b/.gitignore
index 095c70a..6f52a2a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,7 +1,8 @@
+doc/mojitos.1
 tests/run
 src/counters_option.h
-src/captors.h
-captors.mk
+src/sensors.h
+sensors.mk
 bin
 obj
 *.swp
diff --git a/README.md b/README.md
index 6422ce0..10f5aaf 100644
--- a/README.md
+++ b/README.md
@@ -6,51 +6,52 @@ MojitO/S runs on GNU/Linux
 ## Usage
 
 ```bash
-Usage : mojitos [-rsu] [-t time] [-f freq] [-p perf_list]  \
-                [-d network_device] [-o logfile] [-e command arguments...]
-        mojitos [-l]
-
-     -s      Enable overhead statistics (in nanoseconds).
-
-     -u      Enable system-level load monitoring.
-
-     -r      Enable RAPL.
-
-     -p perf_list
-             Enable performance counters.  The argument is a coma separated
-             list of performance counters.
-
-     -d net_device
-             Enable network monitoring.
-
-     -l      List the available performance counters and quit.
-
-     -t time
-             Set duration value (in seconds). If 0, then loops indefinitely.
-
-     -f freq
-             Set amount of measurements per second.
-
-     -e cmd ...
-             Execute a command with optional arguments.  If this option is
-             used, any usage of -t or -f is ignored.
+Usage : ./bin/mojitos [OPTIONS] [SENSOR ...] [-e <cmd> ...]
+
+OPTIONS:
+-f|--freq <freq>
+	set amount of measurements per second.
+-t|--time <time>
+	set duration value (seconds). If 0, then loops infinitely.
+-e|--exec <cmd> ...
+	Execute a command with optional arguments.
+	If this option is used, any usage of -t or -f is ignored.
+-o|--logfile <file>
+	specify a log file.
+-s|--overhead-stats
+	enable overhead statistics (nanoseconds).
+
+SENSORS:
+-p|--perf-list <perf_list>
+	performance counters
+	perf_list is a coma separated list of performance counters.
+	Ex: instructions,cache_misses
+-l|--list
+	list the available performance counters and quit
+-u|--sysload
+	system load
+-d|--net-dev <net_dev>
+	network monitoring (if network_device is X, tries to detect it automatically)
+-r|--rapl
+	RAPL
+-c|--cpu-temp
+	processor temperature
 ```
 
 ## Installation Instructions
 
-Dependencies
-```bash
-sudo apt install libpowercap0 libpowercap-dev powercap-utils python3
-```
 Download the source code
 ```bash
 git clone https://gitlab.irit.fr/sepia-pub/mojitos.git
 ```
-Compile the code
+The quickest way to compile the code is:
 ```bash
 cd mojitos
+./configure.sh
 make
 ```
+You may want to run `./configure.sh --help` to see configuration options.
+
 To execute mojitos without being root to monitor performance counters
 ```bash
 sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
@@ -65,7 +66,7 @@ sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
 
 RAPL values during 2 seconds with a frequency of 2 Hz
 ```bash
-$ ./mojitos -t 2 -f 2 -r
+$ ./bin/mojitos -t 2 -f 2 -r
 #timestamp package-00 core0 dram0
 1036389.135659868 10986 2869 1526
 1036389.500183551 1291440 255736 515562
@@ -75,7 +76,7 @@ $ ./mojitos -t 2 -f 2 -r
 Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
 
 ```bash
-$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
+$ ./bin/mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 #timestamp cpu_cycles cache_ll page_faults
 1036846.351749455 571199 1232 0
 1036847.001098880 348173344 2451387 872
@@ -85,7 +86,7 @@ $ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 
 Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
 ```bash
-$ ./mojitos -t 0 -f 1 -d enp0s25
+$ ./bin/mojitos -t 0 -f 1 -d enp0s25
 #timestamp rxp rxb txp txb
 1036559.277376027 0 0 0 0
 1036560.000161101 4 581 2 179
@@ -97,7 +98,7 @@ $ ./mojitos -t 0 -f 1 -d enp0s25
 
 Overhead of the monitoring for RAPL and cpu_cycle
 ```bash
-$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
+$ ./bin/mojitos -t 5 -f 1 -p cpu_cycles -r -s
 #timestamp cpu_cycles package-00 core0 dram0 overhead
 1036988.197227391 162214 19898 4944 1586 149612
 1036989.000151326 332613664 2513116 379577 1115171 739573
diff --git a/configure.sh b/configure.sh
index 49e1789..62f297a 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,25 +20,25 @@ decho() {
 }
 
 debug=0
-target_hdr=src/captors.h
-target_mk=captors.mk
+target_hdr=src/sensors.h
+target_mk=sensors.mk
 
-noncaptor='counters_option|optparse|captors|util|info_reader'
+nonsensor='counters_option|optparse|sensors|util|info_reader'
 
-hdr_blacklist=$noncaptor
+hdr_blacklist=$nonsensor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>] [-u <captor>]\n' "$(basename "$0")" >&2
-	printf -- '-e | --exclude      :   exclude captor, can be called multiple times\n' >&2
-	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
-	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
-	printf -- '-u | --unique       :   only include the specified captor\n' >&2
+	printf -- 'Usage: %s [-l] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
+	printf -- '-e | --exclude      :   exclude sensor, can be called multiple times\n' >&2
+	printf -- '-i | --include      :   include sensor, can be called multiple times\n' >&2
+	printf -- '-l | --list-sensors :   list all sensors and exit\n' >&2
+	printf -- '-u | --unique       :   only include the specified sensor\n' >&2
 	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
 	exit 1
 }
 
-ls_captors() {
+ls_sensors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
@@ -51,49 +51,52 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
-# gen_captors_h(captors, nb_captors)
-gen_captors_h() {
-	captors=$1
-	nb_captors=$2
-	nb_captor_opts=$(
-		for captor in $captors; do
-			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+# gen_sensors_h(sensor, nb_sensors)
+gen_sensors_h() {
+	sensors=$1
+	nb_sensors=$2
+	nb_sensor_opts=$(
+		for sensor in $sensors; do
+			sed -n 's/.*'"${sensor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${sensor}.h"
 		done |
 			paste -s -d '+' |
 			bc
 	)
 
-	dprint captors >&2
-	dprint nb_captor_opts >&2
-	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
+	dprint sensors >&2
+	dprint nb_sensor_opts >&2
+	isnum "$nb_sensor_opts" || die "could not get total number of sensors's command-line options"
 
 	# gen includes
-	for captor in $captors; do
-		printf '#include "%s.h"\n' "$captor"
+	for sensor in $sensors; do
+		printf '#include "%s.h"\n' "$sensor"
 	done
-	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
-	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
+	printf '\n'
+
+	printf '#define NB_SENSOR %d\n' "$nb_sensors"
+	printf '#define NB_SENSOR_OPT %d\n' "$nb_sensor_opts"
+	printf '\n'
 
-	# gen `init_captors()`
-	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	# gen `init_sensors()`
+	printf 'void init_sensors(Optparse *opts, Sensor *sensors, size_t len, size_t offset, int *nb_defined)\n{\n'
 	printf '    int opt_idx = offset;\n'
-	for captor in $captors; do
+	for sensor in $sensors; do
 		cat <<-!
-		    for (int i = 0; i < ${captor}.nb_opt; i++) {
-		        longopts[opt_idx++] = ${captor}_opt[i];
+		    for (int i = 0; i < ${sensor}.nb_opt; i++) {
+		        opts[opt_idx++] = ${sensor}_opt[i];
 		    }
-		    captors[(*nb_defined)++] = ${captor};
+		    sensors[(*nb_defined)++] = ${sensor};
 		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
-gen_captors_mk() {
-	captors=$1
+gen_sensors_mk() {
+	sensors=$1
 	printf 'CAPTOR_OBJ = '
-	for captor in $captors; do
-		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	for sensor in $sensors; do
+		printf '$(OBJ_DIR)/%s.o ' "$sensor"
 	done
 	printf '\n'
 }
@@ -140,8 +143,8 @@ while [ "$1" ]; do
 		shift; [ "$1" ] || usage
 		hdr_blacklist="${hdr_blacklist}|${1}"
 		;;
-	--list-captors|-l)
-		ls_captors
+	--list-sensors|-l)
+		ls_sensors
 		exit 0
 		;;
 	--unique|-u)
@@ -155,20 +158,20 @@ while [ "$1" ]; do
 	shift
 done
 
-captors=$(ls_captors)
-nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+sensors=$(ls_sensors)
+nb_sensors=$(echo "$sensors" | sed '/^$/d' | wc -l)
 
-if [ "$nb_captors" -eq 0 ]; then
-	printf -- '0 captors are selected. cannot build.\n' >&2
+if [ "$nb_sensors" -eq 0 ]; then
+	printf -- '0 sensors are selected. cannot build.\n' >&2
 	exit 1
 fi
 
-try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
-try gen_captors_mk "$captors" > "$target_mk"
+try gen_sensors_h "$sensors" "$nb_sensors" > "$target_hdr"
+try gen_sensors_mk "$sensors" > "$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-echo "$captors" >&2
+printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
+echo "$sensors" >&2
 
 make clean >/dev/null
 
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 5702adc..65fabf3 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,7 +7,7 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
diff --git a/doc/mojitos.1 b/doc/mojitos.pre.1
similarity index 69%
rename from doc/mojitos.1
rename to doc/mojitos.pre.1
index a7927e8..af9cb9b 100644
--- a/doc/mojitos.1
+++ b/doc/mojitos.pre.1
@@ -3,47 +3,18 @@
 .Os
 .Sh NAME
 .Nm mojitos
-.Nd An open source system, energy and network monitoring tool.
+.Nd An open source system monitoring tool.
 .Sh SYNOPSIS
 .Nm mojitos
-.Op Fl rsu
-.Op Fl t Ar time
-.Op Fl f Ar freq
-.Op Fl p Ar perf_list
-.Op Fl d Ar net_device
-.Op Fl o Ar logfile
+.Op Ar OPTIONS
+.Op Ar SENSOR ...
 .Op Fl e Ar cmd ...
-.Nm mojitos
-.Op Fl l
 .Sh DESCRIPTION
 .Nm
-enables monitoring the system, its energy comsumption and the network activity, at the OS level.
-It runs on GNU/Linux.
-.Pp
+is a monitoring tool with a multitude of sensors that does measurements at the OS level.
 .Nm
-supports the following options:
-.Bl -tag -width Ds
-.It Fl s
-Enable overhead statistics (in nanoseconds).
-.It Fl u
-Enable system-level load monitoring.
-.It Fl r
-Enable RAPL.
-.It Fl p Ar perf_list
-Enable performance counters.
-The argument is a coma separated list of performance counters.
-.It Fl d Ar net_device
-Enable network monitoring.
-.It Fl l
-List the available performance counters and quit.
-.It Fl t Ar time
-Set duration value (in seconds). If 0, then loops indefinitely.
-.It Fl f Ar freq
-Set amount of measurements per second.
-.It Fl e Ar cmd ...
-Execute a command with optional arguments.
-If this option is used, any usage of -t or -f is ignored.
-.El
+runs on GNU/Linux.
+USAGE
 .Sh EXIT STATUS
 .Ex
 .Sh EXAMPLES
diff --git a/src/info_reader.h b/lib/info_reader.h
similarity index 100%
rename from src/info_reader.h
rename to lib/info_reader.h
diff --git a/src/optparse.h b/lib/optparse.h
similarity index 99%
rename from src/optparse.h
rename to lib/optparse.h
index b1908d4..1925d73 100644
--- a/src/optparse.h
+++ b/lib/optparse.h
@@ -73,6 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
+    void *(*fn)(void *, size_t);
 };
 
 /**
diff --git a/makefile b/makefile
index 3f8a70b..d5d2d23 100644
--- a/makefile
+++ b/makefile
@@ -10,21 +10,21 @@ BIN = mojitos
 
 CAPTOR_OBJ =
 
-include ./captors.mk
+include ./sensors.mk
 
 OBJ =  \
 	$(CAPTOR_OBJ) \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
 CFLAGS = $(CPPFLAGS) -O3 -Werror
 LDFLAGS =
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-all: $(BIN)
+all: $(BIN) readme man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
@@ -48,7 +48,7 @@ $(BIN_DIR):
 	mkdir -p $(BIN_DIR)
 
 debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
-debug: all
+debug: $(BIN)
 
 tests:
 	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
@@ -64,4 +64,12 @@ clean:
 	\rm -f $(SRC_DIR)/counters_option.h
 	\rm -f $(TESTS_DIR)/run
 
-.PHONY: all clean mojitos debug format tests
+readme: $(BIN)
+	sh ./tools/update-readme-usage.sh
+
+man: $(BIN)
+	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
+		'/^USAGE/ { $$0=usage } 1' \
+		doc/mojitos.pre.1 > doc/mojitos.1 2>/dev/null
+
+.PHONY: all clean mojitos debug format tests readme man
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 90f6161..fef1109 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,7 +23,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-Captor amd_rapl = {
+Sensor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
diff --git a/src/counters.c b/src/counters.c
index 874e6fc..d42ceae 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -44,11 +44,15 @@ typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void show_all_counters()
+void *show_all_counters(void *none1, size_t none2)
 {
     for (unsigned int i = 0; i < nb_counter_option; i++) {
         printf("%s\n", perf_static_info[i].name);
     }
+    UNUSED(none1);
+    UNUSED(none2);
+    exit(EXIT_SUCCESS);
+    return NULL;	/* not reached */
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
diff --git a/src/counters.h b/src/counters.h
index a191e5a..0304a07 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,9 +22,9 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
-void show_all_counters();
+void *show_all_counters(void *, size_t);
 
-Captor counters = {
+Sensor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
@@ -47,7 +47,8 @@ Optparse counters_opt[2] = {
         .shortname = 'l',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "list the possible performance counters and quit"
+        .usage_msg = "list the available performance counters and quit",
+        .fn = show_all_counters,
     },
 };
 
diff --git a/src/infiniband.h b/src/infiniband.h
index 285b2ba..fac05f8 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,7 +21,7 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-Captor infiniband = {
+Sensor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
diff --git a/src/load.h b/src/load.h
index c7c5575..038b263 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,7 +23,7 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-Captor load = {
+Sensor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
diff --git a/src/mojitos.c b/src/mojitos.c
index 683bdfa..3ecf111 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -38,11 +38,11 @@ typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
 typedef struct Opt Opt;
-typedef struct Captor Captor;
+typedef struct Sensor Sensor;
 /* optparse typedef */
 typedef struct optparse_long Optparse;
 
-struct Captor {
+struct Sensor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
@@ -50,41 +50,70 @@ struct Captor {
     int nb_opt;
 };
 
-int nb_defined_captors = 0;
+int nb_defined_sensors = 0;
 
-#include "captors.h"
+#include "sensors.h"
 
-Captor captors[NB_CAPTOR];
+Sensor sensors[NB_SENSOR];
 
 #define NB_OPT 5
-Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+Optparse opts[NB_OPT + NB_SENSOR_OPT + 1] = {
     {
         .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<freq>",
-        .usage_msg = "specify frequency",
+        .usage_msg = "set amount of measurements per second.",
     },
     {
         .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<time>",
-        .usage_msg = "specify time",
+        .usage_msg = "set duration value (seconds). If 0, then loops infinitely.",
     },
     {
         .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
-        .usage_arg = "<cmd>",
-        .usage_msg = "specify a command",
+        .usage_arg = "<cmd> ...",
+        .usage_msg = "Execute a command with optional arguments.\n"
+        "\tIf this option is used, any usage of -t or -f is ignored.",
     },
     {
         .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<file>",
-        .usage_msg = "specify a log file",
+        .usage_msg = "specify a log file.",
     },
     {
         .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "enable overhead statistics in nanoseconds",
+        .usage_msg = "enable overhead statistics (nanoseconds).",
     },
 };
 
+void dumpopt(Optparse *opt)
+{
+    printf(".It Fl %c | Fl \\-%s", opt->shortname, opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" Ar %s", opt->usage_arg);
+    }
+    printf("\n");
+    printf("%s\n", opt->usage_msg);
+}
+
+void dumpopts(Optparse *opts, size_t nb_opt, size_t nb_sensor_opt)
+{
+    size_t i;
+
+    /* options */
+    printf(".Pp\nOPTIONS:\n.Bl -tag -width Ds\n");
+    for (i = 0; i < nb_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+
+    /* sensors */
+    printf(".Pp\nSENSORS:\n.Bl -tag -width Ds\n");
+    for (i++; i < nb_opt + nb_sensor_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+}
 
 void printopt(Optparse *opt)
 {
@@ -98,23 +127,21 @@ void printopt(Optparse *opt)
 
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+    printf("Usage : %s [OPTIONS] [SENSOR ...] [-e <cmd> ...]\n", argv[0]);
 
     printf("\nOPTIONS:\n");
     for (int i = 0; i < NB_OPT; i++) {
-        printopt(&longopts[i]);
+        printopt(&opts[i]);
     }
-    printf("if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n");
 
-    if (nb_defined_captors == 0) {
+    if (nb_defined_sensors == 0) {
         // no captor to show
         exit(EXIT_FAILURE);
     }
 
-    printf("\nCAPTORS:\n");
-    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
-        printopt(&longopts[NB_OPT + i]);
+    printf("\nSENSORS:\n");
+    for (int i = 0; i < NB_SENSOR_OPT; i++) {
+        printopt(&opts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -149,7 +176,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(Captor *cpt, char *arg)
+void add_source(Sensor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -186,12 +213,17 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
+    init_sensors(opts, sensors, NB_OPT + NB_SENSOR_OPT, NB_OPT, &nb_defined_sensors);
 
     if (argc == 1) {
         usage(argv);
     }
 
+    if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '1' && argv[1][2] == '\0') {
+        dumpopts(opts, NB_OPT, NB_SENSOR_OPT);
+        exit(EXIT_SUCCESS);
+    }
+
     output = stdout;
 
     atexit(flushexit);
@@ -202,7 +234,7 @@ int main(int argc, char **argv)
     options.permute = 0;
 
     optparse_init(&options, argv);
-    while ((opt = optparse_long(&options, longopts, NULL)) != -1 && application == NULL) {
+    while ((opt = optparse_long(&options, opts, NULL)) != -1 && application == NULL) {
         switch (opt) {
         case 'f':
             frequency = atoi(options.optarg);
@@ -218,9 +250,6 @@ int main(int argc, char **argv)
         case 's':
             stat_mode = 0;
             break;
-        case 'l':
-            show_all_counters();
-            exit(EXIT_SUCCESS);
         case 'o':
             if ((output = fopen(options.optarg, "wb")) == NULL) {
                 perror("fopen");
@@ -234,11 +263,15 @@ int main(int argc, char **argv)
         default: {
             int ismatch = 0;
             int opt_idx = NB_OPT;
-            for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                for (int j = 0; j < captors[i].nb_opt; j++) {
-                    if (opt == longopts[opt_idx].shortname) {
+            for (int i = 0; i < nb_defined_sensors && !ismatch; i++) {
+                for (int j = 0; j < sensors[i].nb_opt; j++) {
+                    if (opt == opts[opt_idx].shortname) {
                         ismatch = 1;
-                        add_source(&captors[i], options.optarg);
+                        if (opts[opt_idx].fn != NULL) {
+                            (void) opts[opt_idx].fn(NULL, 0);
+                        } else {
+                            add_source(&sensors[i], options.optarg);
+                        }
                         break;
                     }
                     opt_idx++;
diff --git a/src/network.h b/src/network.h
index 82fcfc3..994651a 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,7 +23,7 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-Captor network = {
+Sensor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
diff --git a/src/rapl.h b/src/rapl.h
index 95f9fd4..a02624d 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,7 +23,7 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
diff --git a/src/temperature.h b/src/temperature.h
index ec2faef..8609dba 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,7 +23,7 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-Captor temperature = {
+Sensor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
new file mode 100755
index 0000000..b9f16de
--- /dev/null
+++ b/tools/update-readme-usage.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+die() { yell "$*"; exit 111; }
+try() { "$@" || die "cannot $*"; }
+yell() { echo "$0: $*" >&2; }
+echo() { printf '%s\n' "$*"; }
+
+usage=$(./bin/mojitos)
+[ -n "$usage" ] || die 'empty usage. try to recompile mojitos.'
+
+try awk -v "usage=$usage" '
+	/^Usage/ {
+		print usage
+		del = 1
+	}
+	{
+		if (del == 1) {
+			if (match($0, "^```")) {
+				del = 0
+				print $0
+			}
+		} else {
+			print $0
+		}
+	}
+' README.md > README.tmp
+try mv README.tmp README.md
-- 
GitLab


From 3bb19b02e319a33b6c219c62b5a400553c3a0aa4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:03 +0000
Subject: [PATCH 085/229] modification of test api

---
 tests/amd_rapl.c   |  81 +++++++++++++++++++------------
 tests/main.c       |   2 +-
 tests/small_test.h | 115 ++++++++++++++++++++++++---------------------
 3 files changed, 115 insertions(+), 83 deletions(-)

diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index ddf76ae..262c1f8 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -85,25 +85,25 @@ TFUNCTION(test_get_name, {
 })
 
 #define NONE 0
-#define DUMB_SENSOR(sensor, cpu_id, name)	\
-	do {									\
-		sensor = (cpu_sensor_t) {			\
-			cpu_id,							\
-			NONE,							\
-			name,							\
-			NONE,							\
-			NONE,							\
-			NONE, 							\
-			NONE							\
-		}; 									\
+#define DUMMY_SENSOR(__sensor, __cpu_id, __name) \
+do {                                             \
+  __sensor = (cpu_sensor_t) {                    \
+    .cpu_id = __cpu_id,                          \
+    .package_id = NONE,                          \
+    .core_id = NONE,                             \
+    .name = __name,                              \
+    .fd = NONE,                                  \
+    .energy_units = NONE,                        \
+    .core_energy = NONE,                         \
+  };                                             \
 	} while(0);
 
-#define DUMB_RAPL(rapl, sensors, nb)		\
-	do {									\
-		rapl = (_amd_rapl_t) {				\
-			sensors,						\
-			nb								\
-		};									\
+#define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
+	do {                                                 \
+		__rapl = (_amd_rapl_t) {                           \
+			.sensors = __sensors,                            \
+			.sensor_count = __sensors_count                 \
+		};                                                 \
 	} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
@@ -116,8 +116,8 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 1:
     // -- Setup
     nb = 1;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
@@ -127,11 +127,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 2:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 1, "core1");
-    DUMB_SENSOR(sensors[2], 2, "core2");
-    DUMB_SENSOR(sensors[3], 3, "core3");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 1, "core1");
+    DUMMY_SENSOR(sensors[2], 2, "core2");
+    DUMMY_SENSOR(sensors[3], 3, "core3");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core1");
     strcpy(expecteds[2], "core2");
@@ -144,11 +144,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 3:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 3, "core3");
-    DUMB_SENSOR(sensors[2], 1, "core1");
-    DUMB_SENSOR(sensors[3], 2, "core2");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 3, "core3");
+    DUMMY_SENSOR(sensors[2], 1, "core1");
+    DUMMY_SENSOR(sensors[3], 2, "core2");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core3");
     strcpy(expecteds[2], "core1");
@@ -159,10 +159,33 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+TFUNCTION(test_init_cpu_sensor, {
+    static const unsigned int max_cpus = 10;
+    unsigned char cpus_map[max_cpus * max_cpus];
+    cpu_sensor_t sensor_t1;
+    unsigned int result;
+    unsigned int expected;
+
+    // Test 1:
+    // -- Setup
+    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
+    result = 0;
+    expected = 1;
+    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
+    sensor_t1.cpu_id = 1;
+    sensor_t1.core_id = 0;
+    sensor_t1.package_id = 0;
+    // -- Run
+    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+})
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/main.c b/tests/main.c
index a3a43cb..e48b56a 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -2,7 +2,7 @@
 #include "amd_rapl.c"
 #include "info_reader.c"
 
-TFILE_ENTRY_POINT(main, {
+TMAIN({
     CALL_TFUNCTION(test_util);
     CALL_TFUNCTION(test_amd_rapl);
     CALL_TFUNCTION(test_info_reader);
diff --git a/tests/small_test.h b/tests/small_test.h
index 0e39868..357479a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -9,10 +9,23 @@
 
 // ---------------------------API_INTERFACE
 
+
+
+#define TMAIN(code)                                              \
+  int main()                                                     \
+{                                                                \
+  unsigned int __indentation_level = 0;                          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
+  unsigned int __error_counter__ = 0;                            \
+  do code while (0);                                             \
+  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  return __error_counter__;                                      \
+}
+
 /**
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
- * It defines a function with the specified file_name that contains the test code specified in code.
+ * It defines a function with the specified __filename that contains the test code specified in code.
  *
  * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
@@ -20,17 +33,17 @@
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param file_name The name of the function that serves as the entry point for the test file.
- * @param code The test code to be executed in the function.
+ * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __code The test code to be executed in the function.
  */
-#define TFILE_ENTRY_POINT(file_name, code) \
-  int file_name() \
-{ \
-  INIT_TEST_FILE();\
-  int __error_counter__ = 0;\
-  do code while(0);\
-  DEFERRED_FILE_ERROR(__error_counter__); \
-  return __error_counter__;\
+#define TFILE_ENTRY_POINT(__filename, __code)       \
+  int __filename (unsigned int __indentation_level) \
+{                                                   \
+  INIT_TEST_FILE();                                 \
+  int __error_counter__ = 0;                        \
+  do __code while(0);                               \
+  DEFERRED_FILE_ERROR(__error_counter__);           \
+  return __error_counter__;                         \
 }
 
 /**
@@ -43,15 +56,15 @@
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
  *
- * @param function_name The name of the test function.
- * @param code The test code to be executed in the function.
+ * @param __function_name The name of the test function.
+ * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(function_name, code) \
-  int function_name() \
+#define TFUNCTION(__function_name, __code) \
+  int __function_name(unsigned int __indentation_level) \
 { \
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
-  do code while(0); \
+  do __code while(0); \
   DEFERRED_FUNCTION_ERROR(__error_counter__); \
   return __error_counter__; \
 }
@@ -65,7 +78,7 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name()
+  __error_counter__ += function_name(__indentation_level + 1)
 
 
 /**
@@ -82,7 +95,7 @@
  * @endcode
  */
 #define TEST_STR(result, expected) \
-	__error_counter__ += test_str(__FILE__, __LINE__, result, expected)
+    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_BOOLEAN(result, expected)
@@ -98,7 +111,7 @@
  * @endcode
  */
 #define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_PTR(result, expected)
@@ -116,7 +129,7 @@
  * @endcode
  */
 #define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
 
 
 /**
@@ -133,7 +146,7 @@
  * @endcode
  */
 #define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
@@ -161,6 +174,15 @@
 
 // --------------------------------API_CODE
 
+
+#define INDENTED_PRINT(__fmt, ...)                          \
+  do {                                                      \
+    for(unsigned int i = 0; i < __indentation_level; i++) { \
+      printf("|    ");                                       \
+    }                                                       \
+    printf(__fmt, ##__VA_ARGS__);                           \
+  } while(0)
+
 /**
  * @def INIT_TEST_FILE()
  * @brief Initialize the test file
@@ -173,8 +195,8 @@
  * INIT_TEST_FILE();
  * @endcode
  */
-#define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__)
+#define INIT_TEST_FILE()     \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 /**
  * @def INIT_TEST_FUNCTION()
@@ -188,13 +210,14 @@
  * @endcode
  */
 #define INIT_TEST_FUNCTION() \
-	init_test_function(__func__)
+  INDENTED_PRINT("%s()\n", __func__);
 
 #define DEFERRED_FILE_ERROR(nb_error) \
-	  printf("========== Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
+//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
-	  printf("       | Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 #define FMT_NULL(string) \
 	string = string ? string : "NULL"
@@ -252,65 +275,51 @@ char *uint64_t_format(char *buffer, uint64_t *value)
     return buffer;
 }
 
-void init_test_file(const char *file, const char *function)
-{
-    printf("========== TEST in %s -> %s()\n", file, function);
-}
-
-void init_test_function(const char *function)
-{
-    printf("|=> %s()\n", function);
-}
-
-int test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
 {
+    __indentation_level++;
     static char buffer_result[1000];
     static char buffer_expected[1000];
     int is_equal = compare(result, expected);
-    char c_result = is_equal ? 'V' : 'X';
-    printf("[%c]    | %s:%d: ", c_result, file, line);
 
+    char *fmt_result = format(buffer_result, expected);
+    char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        printf("failed, expected %s, got %s\n",
-               format(buffer_result, expected),
-               format(buffer_expected, result)
-              );
-    } else {
-        printf("passed\n");
+        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line, char *result, char *expected)
+int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
 {
     Comparator *compare = (Comparator *) string_compare;
     Formatter *format = (Formatter *) string_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_boolean(char *file, int line, bool *result, bool *expected)
+int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
 {
     Comparator *compare = (Comparator *) boolean_compare;
     Formatter *format = (Formatter *) boolean_format;
 
-    return test(file, line, (int *) result, (void *) expected, compare, format);
+    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
 }
 
-int test_ptr(char *file, int line, void *result, void *expected)
+int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) ptr_compare;
     Formatter *format = (Formatter *) ptr_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_uint64_t(char *file, int line, void *result, void *expected)
+int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) uint64_t_compare;
     Formatter *format = (Formatter *) uint64_t_format;
 
-    return test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
+    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
 }
 #endif
 
-- 
GitLab


From 823f32036b8e94e1543336d6a4045ac4d493f5ca Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:26 +0000
Subject: [PATCH 086/229] format

---
 src/amd_rapl.c | 136 +++++++++++++++++++++++++------------------------
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0d2ed29..2f20ea2 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,8 +25,6 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <math.h>
 
 #include "info_reader.h"
 #include "util.h"
@@ -38,59 +36,66 @@ static const uint64_t amd_energy_mask = 0xFFFFFFFF;
 static const uint64_t amd_energy_unit_mask = 0x01F00;
 static const uint64_t msr_rapl_power_unit = 0xC0010299;
 static const uint64_t energy_core_msr = 0xC001029A;
-static const uint64_t energy_pkg_msr = 0xC001029B;
 
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
 
 struct cpu_sensor_t {
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
+    unsigned int cpu_id;
+    unsigned int package_id;
+    unsigned int core_id;
 
+    char *name;
     int fd;
+
     unsigned int energy_units;
     uint64_t core_energy;
-    uint64_t pkg_energy;
 };
 typedef struct cpu_sensor_t cpu_sensor_t;
 
 struct _amd_rapl_t {
     cpu_sensor_t *sensors;
-    unsigned int nb;
+    unsigned int sensor_count;
 };
 typedef struct _amd_rapl_t _amd_rapl_t;
 
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-
 #warning "Must be modified before release"
 #define MAX_CPUS 64
-#define NB_KEYS 2
+#define NB_KEYS 3
 
 static const char *cpuinfo = "/proc/cpuinfo";
-static GenericPointer _size_t_allocator(char *s)
+
+static GenericPointer uint_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
 static void _set_cpu_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->cpu_id = (size_t) data;
+    cpu->cpu_id = (unsigned int) data;
 }
 
 static void _set_package_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->package_id = (size_t) data;
+    cpu->package_id = (unsigned int) data;
+}
+
+static void _set_core_id(GenericPointer storage, GenericPointer data)
+{
+    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    cpu->core_id = (unsigned int) data;
 }
 
 static KeyFinder keys[NB_KEYS] = {
-    {"processor", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_cpu_id},
-    {"physical id", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_package_id}
+    {"processor", ": ", uint_allocator, _set_cpu_id},
+    {"physical id", ": ", uint_allocator, _set_package_id},
+    {"core id", ": ", uint_allocator, _set_core_id}
 };
 #endif
 
@@ -119,13 +124,20 @@ uint64_t read_raw_core_energy(int fd)
     return energy & amd_energy_mask;
 }
 
+// -------------------------READ_PKG_ENERGY
+
+#ifdef __READ_PKG_ENERGY__
+// TODO: Verify if these functions are still useful (the package energy can be calculed)
+
+static const uint64_t energy_pkg_msr = 0xC001029B;
 uint64_t read_raw_pkg_energy(int fd)
 {
     uint64_t energy = read_msr(fd, energy_pkg_msr);
     return energy & amd_energy_mask;
 }
+#endif
 
-// ---------------------------------ENERGY
+// ----------------------------------ENERGY
 
 uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
@@ -147,20 +159,19 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
            sensor->core_energy,
-           sensor->pkg_energy
           );
 }
 
 void debug_print_amd_rapl(_amd_rapl_t *rapl)
 {
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         debug_print_sensor(&rapl->sensors[i]);
     }
 }
@@ -186,57 +197,46 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-char *get_name(size_t cpu_id)
+char *get_name(unsigned int cpu_id)
 {
-    static const char *base_name = "core%ld";
+    static const char *base_name = "core%d";
     static const size_t max_lenght = 20;
     char *name = (char *)calloc(max_lenght, sizeof(char));
     snprintf(name, max_lenght, base_name, cpu_id);
     return name;
 }
 
-void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
+void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
 {
+    sensor->energy_units = read_unit(sensor->fd);
+    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
+    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
+
+    *energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
+    sensor->core_energy = core_energy;
+}
+
+unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
+{
+    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
+        return 0;
+    }
+    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+
     static char filename[BUFFER_SIZE];
     sprintf(filename, base_str, cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, "open(");
         fprintf(stderr, base_str, cpu_id);
-        perror(")");
+        perror(":open()");
         exit(127);
     }
 
-    uint64_t raw_core_energy = read_raw_core_energy(fd);
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(fd);
-
     sensor->cpu_id = cpu_id;
     sensor->name = get_name(cpu_id);
     sensor->fd = fd;
-    sensor->energy_units = read_unit(fd);
-    sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-    sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-}
-
-uint64_t get_core_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
-    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
-    sensor->core_energy = core_energy;
-    return energy_consumed;
-}
-
-uint64_t get_pkg_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
-    uint64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(pkg_energy, sensor->pkg_energy);
-    sensor->pkg_energy = pkg_energy;
-    return energy_consumed;
+    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -258,41 +258,42 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     UNUSED(none);
     _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
-    unsigned int nb_cpu = get_nb_cpu();
-    if (nb_cpu == 0) {
-        fprintf(stderr, "open(");
-        fprintf(stderr, base_str,0);
-        perror(")");
+    unsigned int max_cpus = get_nb_cpu();
+    if (max_cpus == 0) {
+        fprintf(stderr, base_str, 0);
+        perror(":open()");
         exit(127);
     }
 
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
-
-    rapl->nb = nb_cpu;
+    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
+    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
     rapl->sensors = cpus;
 
-    for (unsigned int i = 0; i < nb_cpu; i++) {
-        init_cpu_sensor(&rapl->sensors[i], i);
+    unsigned int nb_cpu = 0;
+    for (unsigned int i = 0; i < max_cpus; i++) {
+        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
     }
+    rapl->sensor_count = nb_cpu;
 
     *ptr = (void *) rapl;
-    return rapl->nb;
+    free(cpus_map);
+    return rapl->sensor_count;
 }
 
 
 unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        results[i] = get_core_energy(&rapl->sensors[i]);
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
+        update_cpu_sensor(&rapl->sensors[i], &results[i]);
     }
-    return rapl->nb;
+    return rapl->sensor_count;
 }
 
 void label_amd_rapl(char **labels, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         labels[i] = rapl->sensors[i].name;
     }
 }
@@ -301,9 +302,10 @@ void clean_amd_rapl(void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         clean_cpu_sensor(&rapl->sensors[i]);
     }
     free(rapl->sensors);
     free(rapl);
 }
+
-- 
GitLab


From 213b5d9bd64122321164ec70d75b328cdce9dd77 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:32 +0000
Subject: [PATCH 087/229] format

---
 tests/info_reader.c | 157 ++++++++++++++++++++++++++++++--------------
 1 file changed, 106 insertions(+), 51 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 9504631..32734c9 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,54 +1,117 @@
 #include "small_test.h"
 
 TFUNCTION(test_replace_first, {
-    char test1[] = "This is my string";
-    replace_first(test1, 'i', 'I');
-    TEST_STR(test1, "ThIs is my string");
+    // useful variables :
+    char result[100];
+    char expected[100];
 
-    char test2[] = "This is my string";
-    replace_first(test2, 'x', 'X');
-    TEST_STR(test2, "This is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "ThIs is my string");
+    // -- Run
+    replace_first(result, 'i', 'I');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'x', 'X');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
-    char test3[] = "This is my string";
-    replace_first(test3, ' ', '_');
-    TEST_STR(test3, "This_is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'T', 'T');
+    // -- Verification
+    TEST_STR(result, expected);
 })
 
 TFUNCTION(test_split_on_delimiter, {
-    char test4[] = "key:value";
-    char *key;
-    char *value;
-
-    split_on_delimiter(test4, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test5[] = "key: value";
-    split_on_delimiter(test5, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value");
-
-    char test6[] = "key:value";
-    replace_first(test6, ':', ' ');
-    split_on_delimiter(test6, " ", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test7[] = "";
-    split_on_delimiter(test7, ":", &key, &value);
-    TEST_STR(key, NULL);
-    TEST_STR(value, NULL);
-
-    char test9[] = "key:value:extra";
-    split_on_delimiter(test9, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value:extra");
-
-    char test10[] = "key: value :extra";
-    split_on_delimiter(test10, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value :extra");
+    // Useful variables
+    char string[100];
+    char *result_key;
+    char *result_value;
+    char expected_key[100];
+    char expected_value[100];
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    replace_first(string, ':', ' ');
+    // Run
+    split_on_delimiter(string, " ", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, NULL);
+    TEST_STR(result_value, NULL);
+
+    // Setup
+    strcpy(string, "key:value:extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value:extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value :extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value :extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
 })
 
 TFUNCTION(test_start_with, {
@@ -110,7 +173,7 @@ TFUNCTION(test_start_with, {
 
 
 TFUNCTION(test_match, {
-    // usefull variable :
+    // useful variables :
     bool _true = true;
     bool _false = false;
     KeyFinder keys[10];
@@ -198,11 +261,3 @@ TFILE_ENTRY_POINT(test_info_reader, {
     CALL_TFUNCTION(test_match);
 })
 
-#ifdef __TESTING_INFO_READER__
-int main()
-{
-    test_info_reader();
-    return 0;
-}
-#endif
-
-- 
GitLab


From bf96f133e149a083b6145a72a9781bf4cec6d73e Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:47 +0000
Subject: [PATCH 088/229] print format

---
 tests/small_test.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 357479a..d1aae8a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -285,7 +285,7 @@ int test(char *file, int line, unsigned int __indentation_level, void *result, v
     char *fmt_result = format(buffer_result, expected);
     char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
-- 
GitLab


From 2742736d4fa0aa50202f4431863c8a0e34bcea84 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:35:26 +0000
Subject: [PATCH 089/229] remove the gcc dependence

---
 tests/small_test.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index d1aae8a..9ac572c 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -7,10 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-// ---------------------------API_INTERFACE
-
-
+#include "../src/util.h"
 
+// ---------------------------API_INTERFACE
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -236,9 +235,10 @@ int string_compare(char *string1, char *string2)
     }
 }
 
-char *string_format(__attribute__((unused)) char *buffer, char *string)
+char *string_format(char *buffer, char *string)
 {
-    return FMT_NULL(string);
+  UNUSED(buffer); 
+  return FMT_NULL(string);
 }
 
 
@@ -247,8 +247,9 @@ int boolean_compare(bool *boolean1, bool *boolean2)
     return *boolean1 == *boolean2;
 }
 
-char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
+char *boolean_format(char *buffer, bool *boolean)
 {
+    UNUSED(buffer);
     return *boolean ? "True" : "False";
 }
 
-- 
GitLab


From 356d49ed556835d24998f561e10fc447365505b0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:10 +0000
Subject: [PATCH 090/229] example of how to use src/nfo_reader.c

---
 .../info_reader_ex.c                          | 43 ++++++-------------
 1 file changed, 12 insertions(+), 31 deletions(-)
 rename tests/example_info_reader.c => doc/info_reader_ex.c (76%)

diff --git a/tests/example_info_reader.c b/doc/info_reader_ex.c
similarity index 76%
rename from tests/example_info_reader.c
rename to doc/info_reader_ex.c
index 1dd6464..38d948a 100644
--- a/tests/example_info_reader.c
+++ b/doc/info_reader_ex.c
@@ -1,23 +1,20 @@
 #include "info_reader.h"
 #include <stdint.h>
 
-#ifdef DEBUG
-#warning "PTR_TO_TPTR hide a cast warning"
-#endif
-
 #define MAX_PROCS 2
+#define NB_KEYS 6
 typedef struct {
-    size_t processor;
+    unsigned int processor;
     char *vendor_id;
-    size_t family;
-    size_t core_id;
-    size_t physical_id;
+    unsigned int family;
+    unsigned int core_id;
+    unsigned int physical_id;
     char *model_name;
 } Cpu;
 
 GenericPointer int_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
@@ -59,19 +56,6 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-struct cpu_sensor_t {
-    //TODO: check the reset of the msr registers
-#warning "Check the reset of the msr registers"
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
-
-    int *fd;
-    uint64_t energy_units;
-    uint64_t core_energy;
-    uint64_t pkg_energy;
-};
-
 int main(int argc, char const *argv[])
 {
     Cpu cpus[MAX_PROCS];
@@ -91,7 +75,7 @@ int main(int argc, char const *argv[])
                      .capacity = MAX_PROCS,
                      .storage_struct_size = sizeof(Cpu),
                      .keys = keys,
-                     .nb_keys = 6,
+                     .nb_keys = NB_KEYS,
                      .file = fopen("/proc/cpuinfo", "r")
                     };
 
@@ -99,19 +83,16 @@ int main(int argc, char const *argv[])
 
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
-        printf("Processor: %ld\n", cpus[i].processor);
+        printf("Processor: %u\n", cpus[i].processor);
         printf("Vendor ID: %s\n", cpus[i].vendor_id);
-        printf("Family: %ld\n", cpus[i].family);
-        printf("Core ID: %ld\n", cpus[i].core_id);
-        printf("Physical ID: %ld\n", cpus[i].physical_id);
+        printf("Family: %u\n", cpus[i].family);
+        printf("Core ID: %u\n", cpus[i].core_id);
+        printf("Physical ID: %u\n", cpus[i].physical_id);
         printf("Model Name: %s\n", cpus[i].model_name);
-        printf("==============================\n");
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-
-    printf("size = %ld\n", sizeof (struct cpu_sensor_t));
-
+        printf("==============================\n");
     return 0;
 }
 
-- 
GitLab


From 3ce5385641cc8028ae457ad87c302cfe65fbcad2 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:44 +0000
Subject: [PATCH 091/229] format

---
 doc/info_reader_ex.c | 2 +-
 tests/small_test.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 38d948a..6b284a5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -92,7 +92,7 @@ int main(int argc, char const *argv[])
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-        printf("==============================\n");
+    printf("==============================\n");
     return 0;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index 9ac572c..33c34c6 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -237,8 +237,8 @@ int string_compare(char *string1, char *string2)
 
 char *string_format(char *buffer, char *string)
 {
-  UNUSED(buffer); 
-  return FMT_NULL(string);
+    UNUSED(buffer);
+    return FMT_NULL(string);
 }
 
 
-- 
GitLab


From 97a59e920a7b8df268c7419eed3dae6f8082c791 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 09:00:30 +0000
Subject: [PATCH 092/229] cleanup

---
 doc/info_reader_ex.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 6b284a5..23ee7d5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -1,8 +1,30 @@
-#include "info_reader.h"
-#include <stdint.h>
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+
+// ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
+#include "./../src/info_reader.h"
 
 #define MAX_PROCS 2
 #define NB_KEYS 6
+
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -56,7 +78,7 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-int main(int argc, char const *argv[])
+int main()
 {
     Cpu cpus[MAX_PROCS];
     KeyFinder keys[] = {
-- 
GitLab


From a71438bff16c46aa926086065929c51c119ccd86 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:21 +0000
Subject: [PATCH 093/229] add test example

---
 doc/test_file_ex.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
 doc/test_main_ex   | Bin 0 -> 17416 bytes
 doc/test_main_ex.c |  35 ++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 doc/test_file_ex.c
 create mode 100755 doc/test_main_ex
 create mode 100644 doc/test_main_ex.c

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
new file mode 100644
index 0000000..44ebc2c
--- /dev/null
+++ b/doc/test_file_ex.c
@@ -0,0 +1,112 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+// Include of the test library
+#include "./../tests/small_test.h"
+
+// -- A simple function that should pass
+TFUNCTION(test_should_pass, {
+    char *result = "It's going to pass";
+    char *expected = "It's going to pass";
+    TEST_STR(result, expected);
+})
+
+// -- A simple function that should fail
+TFUNCTION(test_should_fail, {
+    char *result = "a fail";
+    char *expected = "a nice fail";
+    TEST_STR(result, expected);
+})
+
+// -- Add a new type in the test framework
+
+typedef struct {
+    int simple_int;
+    char simple_str[20];
+} UserType;
+
+
+// -- Implemet the interface
+int usertype_compare(void *ptr1, void *ptr2)
+{
+    return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
+}
+
+char *usertype_format(char buffer[1000], void *ptr)
+{
+    UserType *x = (UserType *) ptr;
+    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    return buffer;
+}
+
+// Create a variable which contains the functions
+static const TestInterface usertype_interface = {
+    .compare = usertype_compare,
+    .format = usertype_format
+};
+
+// -- Create the test macro to call
+#define TEST_USER_TYPE(__result, __expected) \
+    TEST_INTERFACE(__result, __expected, &usertype_interface);
+
+// -- Create a macro setter
+#define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
+    do {                                                    \
+      __user = (UserType) {                                 \
+          .simple_int = __simple_int,                       \
+          .simple_str = __simple_str                        \
+    };                                                      \
+} while (0);
+
+// -- Compare two usertype
+TFUNCTION(test_user_type, {
+    UserType x1;
+    UserType x2;
+
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    TEST_USER_TYPE(&x1, &x2);
+})
+
+
+// -- Compare an array of usetype
+TFUNCTION(test_array_user_type, {
+    UserType *results[1];
+    UserType *expecteds[1];
+
+    UserType x1;
+    UserType x2;
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    results[0] = &x1;
+    expecteds[0] = &x2;
+
+    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+})
+
+// Define the entry point of a test file
+TFILE_ENTRY_POINT(test_file_ex, {
+    CALL_TFUNCTION(test_should_pass);
+    CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_user_type);
+    CALL_TFUNCTION(test_array_user_type);
+})
diff --git a/doc/test_main_ex b/doc/test_main_ex
new file mode 100755
index 0000000000000000000000000000000000000000..0ab7870283c6ba20a50b3761a1c009eb89f3ac20
GIT binary patch
literal 17416
zcmb<-^>JfjWMqH=W(GS35buEiM8p9?F>u&G84L^z4h$9yybKNu3JmfLYzzzxEMPH+
zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`%Rtq^XpoygLLeGsABc?&8$d09(F{<3fb_9~
zG(h<<aTx8&4U%MFfYC5<kUp?|3J`e)G+G2~C<6nGM%D)k8wXv8J_lP=8WtWexFF&%
zeW2h1>01ERw*aaSMt=Y~h=G9tMnk;|jsuW8Eui6vP8&e2fzjytGNAg<X&0zI7!9%m
zBozF#Bn8Aqw+F_D*#o0t_60!o^(cZ&VPHU~_dtXhU^K`MkWk>$k`z$5fY`)fSTqMg
z?ZXuh2S5SNz`y{bp~1_bpOcwnW}=^yqMMVMS6ZQ4VPU3gW};V|uV)0d9^@`iQUFE2
zyI&{+69dBmkQg)=8JHR%e3*G4IS~d1aJmPnpJ)5Nb?@T%=MPt`vFmpAvMSud+Xhkt
zayLj1NDas$ka<uig18`i7(ht|qy`cmjbL$*7>IE(^;|B9#)U!V3t^EgVPJqKZDeT+
z1_lOf>J4#-YvK@B!XZ8ZhrOV5gU#OgIMjo}17ruX+rjMk_~eSj__WNt#GK5kREGHY
zoXn);_~MepqLTRB#LPT~;*z4|+yaK&)Lal%Tu_vmSCYmM4^onx9iN<$9iNt%nZp3m
z28w<&26rD%C+B!0JtI9+INJoyGB#m|_YCokPf0CGP0uVYNi7QTb<WApOASd($^qG*
zo|~TsGQ6lHJ|3bJt3n0_1||kZ24)5pFl1z4VSr#}22TbCSaHEnDwW9zDuIKcVj`KD
zyr5JT59M!}IE@WtQYJVs7#LvX5G+3)5QIp0K+74Jcmq^C08RWPR6GJr+yoj~325R;
zQ1J{j@mWyu0yOdSQ1J>h@%K>i1~hREVTk)X(8Lp=;uFxsW5poqXP}8shKh4QD=t_#
z!1w}a;{QRJpMinlf<44MP+kP3K?sk5;Rcd8a{hgQB+d>~%)r3#0!f?`N&EwnI4qBY
zq*p-2L1uu;2#^>EZ$J_Ul_wxE5Z-|#4l1)iVjz3~NgU({kQfM`KoW<A1xS1pkA}c#
z2#kinXb6mkz-R~z{Sf%fFZau%`3;9hH|s@x1_qDT10_uVFL*Q`;W!NT+<(&|eFlb4
z|5c0i85sEG89?eYKr)|RKK%dx{{%1})bRQA@*<oMYVdq|c@WMAHBdgi+z97`8YZ7!
zE`;$v{Z~x|o9@B@HviLqRbDhcD;oc=9>_Ha^<UBWZ;|<iZ#_FN#(8u;@@RhYAt1!n
z@POe-k6znoP6memqNnv37`~+G@yoY>e8u3=Ys&}<hhElSdJGI6mOn~FJ-S)ff!M7F
zN;v;N;FoUzDLf3NJ$h{~f+TxQPk|`Se;%D5JPy9I_c-{2*@N+z$HjjoA|BnWwIIpX
z10@{)AEfciyD%`o^n=2$!FH-10|P^;cBn_QZ4`*<(fPE5$D`XeO^<=$#m#^J|G!B2
z|Ns9n)?7UX2FBRK{PHOJUzY#>{~u&fs7L2hkLEWD9-Xx>JUUAscyznI@aS~?;L+{+
zz@yXkhevbm2ZmBUkLKDR45jQlK+*Qv04!L-4if}<?zOZ>cjym~Zr2YUo!2}%kH47q
z@BjbS1N>7C@NYYC@-W;ggf%eZe=wA=d33w}c+Kw7&ALICfgu)~YE(ycyMEx`CIHgK
zzm37-5X2U&`XIJ+yZ+$c#?W%0gwvy!)rXgX;WfKQFRKSHnq@ycI!i%5|KVZn`T@hx
z<~IT!owZOkp%8VwyqvrY3?7~5JUWl>0ENSgb$|c=2RRI@pD}#l(GB*6M>m6qC8jq}
z;|1;&h^7}Fy}bQAsFoW-EPsJydGnh9kIvc~ouyYgLoaxA`kwIVbUonH>AR!Z^#Y?u
zx9bj%ZVr#`&;uUbt|uT-_y1z2>l=tn0Eb7n>j96>V;;S%t~wyQj{m;|O&&Wuy1~*X
zAku0E2<acqwQm?ogO0nt00qfw36EaZm)u}!NEk)^`TxJ!^#x<M>kDhw3q=n+x<SG2
z`=dMbibuEW4bRRG5HoinYf=Sis(r%%i5C<f8g$m)Iqv!dZdnbozPG<YmOWwYc70;)
zdZ*}tM=z@vIM_g*YCu+b`1k++$6eomjPdAY%?3-ke(>mJO@J_ecy#;z@aPWx(CvE1
zr<d17gMq=b^Mps|#m+<fKph^BURF=A%HuC;|NZ~Z==ugZ1fFvtg+K(@QP2>$Q}m$Q
z^$j?Xr6Bqt!DRgV|Nm~+H+a1|5!qBGu&F3stp^(j^6FG%l{bDNdv!Nh3hdSG5GI;e
zBh`_-%Fn>S;L*z(2UdCf#iYL&Uj4&~<kj3?pzz1^sy;+N#H${^FujVD+kC;fZI=Yd
zW^i76q5cbN@q#PI^m?#>G9@^-z3}KYeSqx3-#@`w7B$x-bk?p(@#tnz)c{-S`or+R
zan~)Nv;j`flE?;h{RDY&3uCwI7Hiiv;3Osw_8lnPWsy}T`~-zNc%<^U>j6+{>aoKs
zKO;}UB|mi+$Z(HN*CQUCp=XY}UIB5ByFLIb>U4eL(HZ*Yxa${?s7J5w1CQR&1KqA`
ze0q8Rs3JuUXpF+6m-QeAI0jyP{SAtoJ;z<a!3=hJJVXjC@Z!P`kjr;4cDwEXyS&?V
z4>%o8LRPf;2Pks(fC~5&4{Z@}h?KCtX!-H~KXTeU($HDkgArsiKn@05{EQv!CWyu1
zV2fukcDv57cI^QN84Ea|Ktc8jS*7j|P>{_58ADN!fyy!06&}6ddTqmT*99OGU)y%O
zF7W8~Il2K%ha6qe?b_qh%ez7aDNKDqDWI1%7vicH3x9#abWXGD0><Xr1q>y7kGn1b
zn*}Q87$J%vo-Fzf3f(1)-L6Z(p6qs=0}fpiWJSK;L7_VbJ#^K+qlWGqh0a=7{DXsY
zIvY}Oa)536!r1Nl#oF}^I5^LOEji@T%en=u5)`n)U@>S-b>$l<VE=%e-tGFP`2b_*
z@fXX%e)|LGH-Xa+f`9uD$nOaLKXB&%bKLa@$QZD@{<9*vtKb_b1b#4fyZ!*XtK0Pt
zI0Pnwodk7=_cu@o{6S7jZv>!59(Vl!H+d<t$zouWKQMN?ez11^0rv3=u%RFydxBXY
zA1i`cP>UXYMe^|vh>vH1OX@$+oCWrQEwVl9zJh!J4cQ-{k{aTJ^T>)izoPp9-cWG;
z;i2vNA@(q&oeFL@!&}NApN-<t5Eu=C(GVCqA;1WpQAD^mq^LBN!7VYTIF&)QfI&5<
zl%YmJK|z5*wb)8E#YzD*6_%Q!qmWurkeXbQnxbH%T5PAIke*)xW^pm77Hep7F?g1!
z7b~RaXXd3Vl;kTEBo-Gl=;@cF7MH}QW#**Dr&j1CGt|Vpq^6}76{V&qxE2-V7b#dN
zsHSi+B!cZ=NL0wnOiqQcL9PoePAv+lEJ#(TF3!v?$VrXQ%qszD&{2T$i%W{E6jY0A
z!7eT4!fJde7X#Q4pm{%tBm6>rd_cy-F<8DhBfm5!B_8Z<xD14WEDs6{h$sWZ+|uII
zqWF@^f>f9&R6Mb$D6ujgMHXxhG%y%I?qOhHV3cOI2DLRnQ&Cgi{r?Z@ynK20|Gx+$
z0|U$Z|NnIu85ly||NjqaOxk|<|KEj?fnmjm|Nm1M85pj8`2W9!k%58l<NyCl7#SFx
zKmPxJgpq+E`Q!ipPZ${(=6wABpM{Bm;p)f#|5cb67$iUa|L?-Y!0`Li|NkjW3=Gdc
z|Nq~@#K3Uz%m4pNm>3w?zyAM!go%N{|Lgz%PnZ}On!f%2&%(^W@ZkIZ|0>K34Cj9Q
z|L?-gz%b$G|Nkk>3=E*TZIG`StAZF9D+Cy&dDuB7FhayZYd9+2{r|59QsBZ4nu2Cf
zVPIe|VPIfb@b>@z1duqNfE%BL7e9A7M+1Ysl$DmT3V1pfWNr)t1H+BC|NnzEg48lV
z%mvL^UwHffe*jbrM1kz;VPIhR`0oGzY><E}pFkUvGcOxc5)V5E0|Q8Y4Fdy%&HMlV
zK_e{;F!@xlG+6!&0|SHC`~UwzbKh|Je1tqGUXtGb|8I(HehxyOhmnDy{QZB(6d}y~
zaD+T49zpV!$odNq@;;0V3=`h}|Bp*PhmnC{<@^8t!D}*L=2s*1_b@UroPGcQ|087c
znQnp=fc?+Nz|jBU|Nqx0@{i#1XBZh6qCVo5f5XVYp!(_me=}tLxnS+!@Z(`(V6gu5
z|Gx*ad_6*5hlzn9`P2XZ#-QF1%>B$-j35;t_xUg}FqD1%|33~zJ`^sW!^FU_<;(y7
z?~u)BdJ57Gw!a6IUcdhTe+Wf>CtQ9F69a?FxBvg8kmUox(jbvhJQ@O{Aut*OqaiRF
z0;3@?8UlDj0JeS(wq6dlJ`T1X4z~Ucw%!f4z74jX4Yqy_wq6akJ`J`W4b%hzIRLcg
z4@C2T2oQ!ghIv731_lNTX$V6SLc!PhL4_GWQyL&CaGM7-1PU5kW`MMZLE<p^umAq%
zgZLXjbG8f&46wCg4?uIa3=9mgHDWiQ@~|~&J3*Ql7#N_-s2M<``ye4v5P^iD+88E4
z*O!5&ib2v9AOhO12QfkG+Ca28h+tq~*Z~!QQVbuU4uiS-1T>&vYv*A0%R%+S)cyVs
z@gE}tBuM^2`5U0-{fF|Q#xZ<=@@GNie?s|uP;;qG!Pa@Bn`;1#ZwDwH0HqV4bODq`
z*GDWLw$2gKX<=Y+cXqZ?&<IT`%_}KYFf`ON)-%vGECq87>x_)_3`{hk!uV|fg(C~Y
z$N%W6K=A}x&)Ne`5YXk644`G3*wlmKk%>WoK>)h`6lNYsA4uE*P289PwCYuW0hTXe
z>OuL4kwKb40lJ<O<UWvGD5(F<AjSY&2MZDd;TotpuzU^@1K|#^dQo^j1Brp~a`3(e
zO#f~JtCwOxUq^ZnEH2IfTW1T4#`92d*m_!+_&umNY~3tO9MmUeWDsY7t&fF?{{pL*
zW^jP|_XRY(L48zEI5>bikqitlaT!Ji21W)U1_9{$d|0rmL&Xiy#Ern>;ta5LwlI5L
z!Qw&;9#Hk5c}7t91VF_TpyIIdAsQ-P0TqXpYiUsNR;V~M8!{Av#ze5BD_rTP0&I>5
zgMcc?6{r|ndTRr#mta88kNw~TBMjfS05fS3SiK~?T!V>&7Fh@}2r$6PdvKqgfq~&L
zBWPW{00XStheiX#Ij}fPH-di6h<$y29ur7h3bZK)p_qYzft?9rKCHe0<r9zsVJ6Vp
zaVZ7~XnFvNfv^-vJ(D239s!AgumVUN#6ZJg%pmj81Q{3@tikF97;>N$5x9>Is&Am;
zMbHQbk3BFjFhqjIG0g$>@dX$#{Z)xWJ*dwQ^CPlpvzZte1ev55VC5T3ZUsmjw6g)K
z30l1|YzLb!zyPbi!DB=W3=D^$;;{N1JhsHZz;F&6p3)2&;K2@<=?n~)q3Umg2J;vg
z7{Fs43=9lKP;uD)D)5*X0|Ub&s5q?NhZ*+?Dh_KWz|zk@sJ-a%$OVoU0fs1OMGqbW
zVPIh3hl<16A>gqq1_lOcs5q?M0Upy~U|`UJit|A$Qt(&|0|SF2R9ptyuz*^_5DFGY
z_#ei~WQK%4x;sn3>IE2J?IZA58v_GF6Ei41!*nC)IZ*ZOpaDS!1_oIAS<B4803Ikr
zC<U`lfYdYbfD${H4<pWj#2Ew_mVycjP`JY+f|H9%4E6FE;^PyOGUH1U(;1SBN{UNL
z)6(>k84#N};!ASllR?`#iW%bLQ}W}}bMliCbK+A<@{5Y&6H6-?lJh~s(<P}XdIs24
zfcBzf#zTgLQ}arSDjCv>5_41IQ%ZAlD;eVBk$CZ$d6^|BO2Na%py6W3@O5!XQG8x$
zPL7@hXd4S?OgyzHEipNjAt^sU2Z>uyQiQ}SH8VltC6%V7r544*M)dW}8K5FXsl}x^
zC3<EcH<jik$H(iLBA6x&py6!LST~YU@$qR8g~kYlMhK=Mf@#1|T9TQgm&_0!?-u0f
z>l*Ls=Mo>!5bqM{=jiL{%n%>%?iU*G>H(GYa0z0FclYska`cJ!cXJDN4T%qNbn<bH
zX8`#uEx#x?v4jESEhrOXmyZK%(++{{IUwUeF_>7C$`GHLl30?+0FEz={XlR7O&~-6
zu%Uc#1VQHy!1Du;eMNBPpiM*Z@gRdCdw@XkmYiFFCXc#DC_be)KRzQdF9o!J$kRW*
zxFjVr4>X;S0@581^)o0fAe^3;0&y28mLO9SAQm{jpz1-v1y>)RR9p;o5GZv)(hp2w
zacU7*BTO~ekB|fmG8AHbZhlH>PJVoGX;N`XQDSmQW_}(6bTbv2=R$m)q0tRar7%;$
zyQZ*ig#z0L4O8%(4C<aPRO3Ne2JCeP2EF3S+>*p32EF2vA_$!UV`b)*q!tx0=;h^?
zr0S*TmFg7~<rjdwi6oR%nwgWLo0$R?a&+?41r-Zm<r#^^84P+Um3hULxe&Ufhyg59
zmReK{@;fpozKB7uC^aV$qyfq*$SGma1G`nPAg4qxJ->tj%qUJxX3#51ttes8OUum5
zWY8<h2PGB;z0?e7$&is!gy2EUhzCaoL<fuw(gm_quP7hvz{K3lWClHuD1%-SXg)4E
zKQ}iu4>X4YD*`E@LDd1MX$0%f;o8p&vje0S#s<;Kpf(G*tqtNaFu?Ya!e|4CFr0+-
z=U@V$dJEJygxQb2j}<iE1XBy5Vf8(T4Z@&)0kVErzXV1@n+YJLV2rLmoPmMi+yDRh
zF#BQsXBZ8$AJ%_HcYh+Z?+nuq>tDlY4rqXZ+z4XA^h2v>2GIUKP}3f!AJ$)o(XjqG
z*zw>#0gMHq3mF&~Kz(1Bepr7OMnju1@cutc9gMDHU|<0CrD1$ne;P)^nw#kEhuF@*
z&<pN2f%<F^5m^5oM#K8|=-~(R|8%H+Cx~|VcmZtOpaLom(hq8yqKDr?XqbTH!AfBr
z87K`(-(Yblfgb;$C2gR1f$3L(>VwhXIZmiv5CxTn@8bmZ8<F)lKo!7fC>Nv^jA48j
zy#dYr6QB|>8hMTsWB^neZa*k}AlnaXpTg)c*gy|RGjwk$lnJKxquCD|kAl&#{v22_
zG_GK55PcM?AC`XLn~|XzuM6ZjkU}VixgW}9IE$tq*S>O?di40aji%oN+NgxlXW$Nl
zm;g&Z5FP`=Qw9bG(3lV?4}!#C`)pzR&e7Gw_%Qk-sErQY9}dzF8;9_Ko&x|=2a*F}
z7#~Leg}NVRKWsc90IDBX{DaH_VJ=3<*d9zjtltYehX8io04V>0)WhtB#lvbe`(fjI
z6ZAo<85qEOMj%Wu3DXawg~9!2(9UJBG@?HXE%;&i94ZSLyn}HV7#Jj>19~v`!^U?c
zp!zvr7D4qulNFT5z#s>;AF3QK4%4p<7lANf$q|`GOCn%}9#8`hKnn)YI2LFq1Lho<
zzc`WN9;^{caF|0Fmth`*aKUGEK$&0)G){x21T22r3QRG8#%~}j2nlmHgvY=D0FOXj
A`~Uy|

literal 0
HcmV?d00001

diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
new file mode 100644
index 0000000..0aa86b9
--- /dev/null
+++ b/doc/test_main_ex.c
@@ -0,0 +1,35 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+// ~/mojitos/doc$ gcc -Wall -Wextra -Wpedantic -o test_main_ex test_main_ex.c ./../src/util.c
+// Include of the test library
+#include "./../tests/small_test.h"
+
+// Include the *.c files that contain the tests
+#include "./test_file_ex.c"
+// #include "./test_another_test_file.c"
+
+// Define the entry point of the programme
+TMAIN({
+    // Must contain the call to the entry point functions of each file
+    // USE CALL_TFUNCTION(my_function) instead of my_function()
+    CALL_TFUNCTION(test_file_ex);
+    // CALL_TFUNCTION(another_file_entry_point_function);
+})
-- 
GitLab


From 852c1ba361755510cb83e1e13b5aad5158c58458 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:43 +0000
Subject: [PATCH 094/229] add licence

---
 src/amd_rapl.c      |   2 +-
 src/amd_rapl.h      |   2 +-
 tests/amd_rapl.c    |  20 ++++
 tests/info_reader.c |  40 ++++++--
 tests/main.c        |  20 ++++
 tests/small_test.h  | 216 +++++++++++++++++++++++++-------------------
 tests/util.c        |  20 ++++
 7 files changed, 215 insertions(+), 105 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 2f20ea2..51df298 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 4f375b9..f16ed4f 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 262c1f8..39214fc 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "small_test.h"
 #include "../src/amd_rapl.c"
 
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 32734c9..b2a8c6f 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "small_test.h"
 
 TFUNCTION(test_replace_first, {
@@ -124,27 +144,27 @@ TFUNCTION(test_start_with, {
     prefix = "Hello";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = "Goodbye";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello World";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = NULL;
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 })
 
 #define NONE 0
@@ -193,7 +213,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[0]);
     TEST_STR(raw_value, "value");
 
@@ -207,7 +227,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -221,7 +241,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -236,7 +256,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[1]);
     TEST_STR(raw_value, "value");
 
@@ -249,7 +269,7 @@ TFUNCTION(test_match, {
     raw_value = NULL;
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 })
diff --git a/tests/main.c b/tests/main.c
index e48b56a..3246f04 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "util.c"
 #include "amd_rapl.c"
 #include "info_reader.c"
diff --git a/tests/small_test.h b/tests/small_test.h
index 33c34c6..9f6a6d9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #ifndef __SMALL_TEST_H
 #define __SMALL_TEST_H
 
@@ -77,49 +97,48 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name(__indentation_level + 1)
-
+  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
 
 /**
  * @def TEST_STR(result, expected)
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `result`, which is the string to be tested, and `expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
  * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the string to be tested
- * @param expected the expected value of the string
+ * @param __result the string to be tested
+ * @param __expected the expected value of the string
  *
  * @code
  * TEST_STR("Hello", "Hello");
  * @endcode
  */
-#define TEST_STR(result, expected) \
-    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_STR(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &str_interface);} while(0)
 
 /**
- * @def TEST_BOOLEAN(result, expected)
- * @brief Test booleans
- * This macro is used to test booleans. It takes two arguments: `result`, which is the boolean to be tested, and `expected`, which is the expected value of the boolean.
- * The macro uses the `test_boolean()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ * @def TEST_BOOL(__result, __expected)
+ * @brief Test bools
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the boolean to be tested
- * @param expected the expected value of the boolean
+ * @param __result the bool to be tested
+ * @param __expected the expected value of the bool
  *
  * @code
- * TEST_BOOLEAN(1 == 1, true);
+ * TEST_BOOL(1 == 1, true);
  * @endcode
  */
-#define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_BOOL(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
 /**
- * @def TEST_PTR(result, expected)
+ * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `result`, which is the pointer to be tested, and `expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
  * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the pointer to be tested
- * @param expected the expected value of the pointer
+ * @param __result the pointer to be tested
+ * @param __expected the expected value of the pointer
  *
  * @code
  * int x = 5;
@@ -127,47 +146,48 @@
  * TEST_PTR(ptr, &x);
  * @endcode
  */
-#define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_PTR(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &ptr_interface);} while(0)
 
 
 /**
- * @def TEST_UINT64_T(result, expected)
+ * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `result`, which is the integer to be tested, and `expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
  * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the integer to be tested
- * @param expected the expected value of the integer
+ * @param __result the integer to be tested
+ * @param __expected the expected value of the integer
  *
  * @code
  * TEST_UINT64_T(5, 5);
  * @endcode
  */
-#define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_UINT64_T(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+
+#define TEST_INTERFACE(__result, __expected, __interface) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element,
- * adding any errors to the nb_error variable.
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
- * @param function the test function to be used on each element of the array
- * @param nb_error the number of errors encountered during the test
- * @param size the number of elements in the array
- * @param results the array of elements to be tested
- * @param expecteds the array of expected values
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, errors, 3, results, expecteds);
+ * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(function, size, results, expecteds)	\
-	for (unsigned int i = 0; i < size; i++) {						\
-		function(results[i], expecteds[i]);				\
+#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+	for (unsigned int i = 0; i < __array_size; i++) {                       \
+      __test_macro(__results[i], __expecteds[i]);                         \
 	}
 
 
@@ -213,46 +233,71 @@
 
 #define DEFERRED_FILE_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
-#define FMT_NULL(string) \
-	string = string ? string : "NULL"
-
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
 
-int string_compare(char *string1, char *string2)
+typedef struct {
+    Comparator *compare;
+    Formatter *format;
+} TestInterface;
+
+//  ---------------------------str_interface
+
+int str_compare(void *ptr1, void *ptr2)
 {
-    if (string1 == NULL && string2 == NULL) {
+    char *str1 = (char *) ptr1;
+    char *str2 = (char *) ptr2;
+
+    if (str1 == NULL && str2 == NULL) {
         return 1;
-    } else if (string1 == NULL || string2 == NULL) {
+    } else if (str1 == NULL || str2 == NULL) {
         return 0;
     } else {
-        return (strcmp(string1, string2) == 0);
+        return (strcmp(str1, str2) == 0);
     }
 }
 
-char *string_format(char *buffer, char *string)
+char *str_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return FMT_NULL(string);
+    static char *str_null = "NULL";
+    char *str = (char *) ptr;
+    return str ? str : str_null;
 }
 
+static const TestInterface str_interface = {
+    .compare = str_compare,
+    .format = str_format
+};
+
+//  --------------------------bool_interface
 
-int boolean_compare(bool *boolean1, bool *boolean2)
+
+int bool_compare(void *ptr1, void *ptr2)
 {
-    return *boolean1 == *boolean2;
+    bool *bool1 = (bool *) ptr1;
+    bool *bool2 = (bool *) ptr2;
+    return *bool1 == *bool2;
 }
 
-char *boolean_format(char *buffer, bool *boolean)
+char *bool_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return *boolean ? "True" : "False";
+    bool *_bool = (bool *) ptr;
+    return *_bool ? "True" : "False";
 }
 
+static const TestInterface bool_interface = {
+    .compare = bool_compare,
+    .format = bool_format
+};
+
+// ---------------------------ptr_interface
+
 int ptr_compare(void *ptr1, void *ptr2)
 {
     return ptr1 == ptr2;
@@ -264,63 +309,48 @@ char *ptr_format(char *buffer, void *ptr)
     return buffer;
 }
 
+static const TestInterface ptr_interface = {
+    .compare = ptr_compare,
+    .format = ptr_format
+};
+
+// ---------------------------u64_interface
 
-int uint64_t_compare(uint64_t *value1, uint64_t *value2)
+int u64_compare(void *ptr1, void *ptr2)
 {
-    return *value1 == *value2;
+    uint64_t *v1 = (uint64_t *) ptr1;
+    uint64_t *v2 = (uint64_t *) ptr2;
+    return *v1 == *v2;
 }
 
-char *uint64_t_format(char *buffer, uint64_t *value)
+char *u64_format(char *buffer, void *ptr)
 {
-    sprintf(buffer, "%"PRIu64"", *value);
+    uint64_t *v = (uint64_t *) ptr;
+    sprintf(buffer, "%"PRIu64"", *v);
     return buffer;
 }
 
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
+static const TestInterface u64_interface = {
+    .compare = u64_compare,
+    .format = u64_format
+};
+
+// ---------------------------test_function
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
-    __indentation_level++;
+    __indentation_level += 1;
     static char buffer_result[1000];
     static char buffer_expected[1000];
-    int is_equal = compare(result, expected);
+    int is_equal = interface->compare(result, expected);
 
-    char *fmt_result = format(buffer_result, expected);
-    char *fmt_expected = format(buffer_expected, result);
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
     if  (!is_equal) {
         INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
-{
-    Comparator *compare = (Comparator *) string_compare;
-    Formatter *format = (Formatter *) string_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
-{
-    Comparator *compare = (Comparator *) boolean_compare;
-    Formatter *format = (Formatter *) boolean_format;
-
-    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
-}
-
-int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) ptr_compare;
-    Formatter *format = (Formatter *) ptr_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) uint64_t_compare;
-    Formatter *format = (Formatter *) uint64_t_format;
-
-    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
-}
 #endif
 
diff --git a/tests/util.c b/tests/util.c
index a91c58f..69941bf 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "../src/util.h"
 #include "small_test.h"
 
-- 
GitLab


From 84c35c0d19b073bd1be75b9b7f899b873a7887c5 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:26:23 +0000
Subject: [PATCH 095/229] add informations

---
 tests/small_test.h | 31 ++++++++-----------------------
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 9f6a6d9..aedc685 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -30,6 +30,11 @@
 #include "../src/util.h"
 
 // ---------------------------API_INTERFACE
+/**
+ * @brief Define the entry point of the tests
+ * It initializes each useful variables.
+ */
+
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -169,6 +174,7 @@
 #define TEST_INTERFACE(__result, __expected, __interface) \
 	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
+
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
@@ -192,6 +198,7 @@
 
 
 // --------------------------------API_CODE
+// These functions should not be used, only use the previous macros.
 
 
 #define INDENTED_PRINT(__fmt, ...)                          \
@@ -202,32 +209,10 @@
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
-/**
- * @def INIT_TEST_FILE()
- * @brief Initialize the test file
- * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
- *
- * @param __FILE__ preprocessor macro that provides the name of the current file
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FILE();
- * @endcode
- */
+
 #define INIT_TEST_FILE()     \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
-/**
- * @def INIT_TEST_FUNCTION()
- * @brief Initialize the test function
- * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
- *
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FUNCTION();
- * @endcode
- */
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-- 
GitLab


From 467b5b929468cf768471dad5ea1808aaa79b805d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:27:51 +0000
Subject: [PATCH 096/229] remove bin

---
 doc/test_main_ex | Bin 17416 -> 0 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100755 doc/test_main_ex

diff --git a/doc/test_main_ex b/doc/test_main_ex
deleted file mode 100755
index 0ab7870283c6ba20a50b3761a1c009eb89f3ac20..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 17416
zcmb<-^>JfjWMqH=W(GS35buEiM8p9?F>u&G84L^z4h$9yybKNu3JmfLYzzzxEMPH+
zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`%Rtq^XpoygLLeGsABc?&8$d09(F{<3fb_9~
zG(h<<aTx8&4U%MFfYC5<kUp?|3J`e)G+G2~C<6nGM%D)k8wXv8J_lP=8WtWexFF&%
zeW2h1>01ERw*aaSMt=Y~h=G9tMnk;|jsuW8Eui6vP8&e2fzjytGNAg<X&0zI7!9%m
zBozF#Bn8Aqw+F_D*#o0t_60!o^(cZ&VPHU~_dtXhU^K`MkWk>$k`z$5fY`)fSTqMg
z?ZXuh2S5SNz`y{bp~1_bpOcwnW}=^yqMMVMS6ZQ4VPU3gW};V|uV)0d9^@`iQUFE2
zyI&{+69dBmkQg)=8JHR%e3*G4IS~d1aJmPnpJ)5Nb?@T%=MPt`vFmpAvMSud+Xhkt
zayLj1NDas$ka<uig18`i7(ht|qy`cmjbL$*7>IE(^;|B9#)U!V3t^EgVPJqKZDeT+
z1_lOf>J4#-YvK@B!XZ8ZhrOV5gU#OgIMjo}17ruX+rjMk_~eSj__WNt#GK5kREGHY
zoXn);_~MepqLTRB#LPT~;*z4|+yaK&)Lal%Tu_vmSCYmM4^onx9iN<$9iNt%nZp3m
z28w<&26rD%C+B!0JtI9+INJoyGB#m|_YCokPf0CGP0uVYNi7QTb<WApOASd($^qG*
zo|~TsGQ6lHJ|3bJt3n0_1||kZ24)5pFl1z4VSr#}22TbCSaHEnDwW9zDuIKcVj`KD
zyr5JT59M!}IE@WtQYJVs7#LvX5G+3)5QIp0K+74Jcmq^C08RWPR6GJr+yoj~325R;
zQ1J{j@mWyu0yOdSQ1J>h@%K>i1~hREVTk)X(8Lp=;uFxsW5poqXP}8shKh4QD=t_#
z!1w}a;{QRJpMinlf<44MP+kP3K?sk5;Rcd8a{hgQB+d>~%)r3#0!f?`N&EwnI4qBY
zq*p-2L1uu;2#^>EZ$J_Ul_wxE5Z-|#4l1)iVjz3~NgU({kQfM`KoW<A1xS1pkA}c#
z2#kinXb6mkz-R~z{Sf%fFZau%`3;9hH|s@x1_qDT10_uVFL*Q`;W!NT+<(&|eFlb4
z|5c0i85sEG89?eYKr)|RKK%dx{{%1})bRQA@*<oMYVdq|c@WMAHBdgi+z97`8YZ7!
zE`;$v{Z~x|o9@B@HviLqRbDhcD;oc=9>_Ha^<UBWZ;|<iZ#_FN#(8u;@@RhYAt1!n
z@POe-k6znoP6memqNnv37`~+G@yoY>e8u3=Ys&}<hhElSdJGI6mOn~FJ-S)ff!M7F
zN;v;N;FoUzDLf3NJ$h{~f+TxQPk|`Se;%D5JPy9I_c-{2*@N+z$HjjoA|BnWwIIpX
z10@{)AEfciyD%`o^n=2$!FH-10|P^;cBn_QZ4`*<(fPE5$D`XeO^<=$#m#^J|G!B2
z|Ns9n)?7UX2FBRK{PHOJUzY#>{~u&fs7L2hkLEWD9-Xx>JUUAscyznI@aS~?;L+{+
zz@yXkhevbm2ZmBUkLKDR45jQlK+*Qv04!L-4if}<?zOZ>cjym~Zr2YUo!2}%kH47q
z@BjbS1N>7C@NYYC@-W;ggf%eZe=wA=d33w}c+Kw7&ALICfgu)~YE(ycyMEx`CIHgK
zzm37-5X2U&`XIJ+yZ+$c#?W%0gwvy!)rXgX;WfKQFRKSHnq@ycI!i%5|KVZn`T@hx
z<~IT!owZOkp%8VwyqvrY3?7~5JUWl>0ENSgb$|c=2RRI@pD}#l(GB*6M>m6qC8jq}
z;|1;&h^7}Fy}bQAsFoW-EPsJydGnh9kIvc~ouyYgLoaxA`kwIVbUonH>AR!Z^#Y?u
zx9bj%ZVr#`&;uUbt|uT-_y1z2>l=tn0Eb7n>j96>V;;S%t~wyQj{m;|O&&Wuy1~*X
zAku0E2<acqwQm?ogO0nt00qfw36EaZm)u}!NEk)^`TxJ!^#x<M>kDhw3q=n+x<SG2
z`=dMbibuEW4bRRG5HoinYf=Sis(r%%i5C<f8g$m)Iqv!dZdnbozPG<YmOWwYc70;)
zdZ*}tM=z@vIM_g*YCu+b`1k++$6eomjPdAY%?3-ke(>mJO@J_ecy#;z@aPWx(CvE1
zr<d17gMq=b^Mps|#m+<fKph^BURF=A%HuC;|NZ~Z==ugZ1fFvtg+K(@QP2>$Q}m$Q
z^$j?Xr6Bqt!DRgV|Nm~+H+a1|5!qBGu&F3stp^(j^6FG%l{bDNdv!Nh3hdSG5GI;e
zBh`_-%Fn>S;L*z(2UdCf#iYL&Uj4&~<kj3?pzz1^sy;+N#H${^FujVD+kC;fZI=Yd
zW^i76q5cbN@q#PI^m?#>G9@^-z3}KYeSqx3-#@`w7B$x-bk?p(@#tnz)c{-S`or+R
zan~)Nv;j`flE?;h{RDY&3uCwI7Hiiv;3Osw_8lnPWsy}T`~-zNc%<^U>j6+{>aoKs
zKO;}UB|mi+$Z(HN*CQUCp=XY}UIB5ByFLIb>U4eL(HZ*Yxa${?s7J5w1CQR&1KqA`
ze0q8Rs3JuUXpF+6m-QeAI0jyP{SAtoJ;z<a!3=hJJVXjC@Z!P`kjr;4cDwEXyS&?V
z4>%o8LRPf;2Pks(fC~5&4{Z@}h?KCtX!-H~KXTeU($HDkgArsiKn@05{EQv!CWyu1
zV2fukcDv57cI^QN84Ea|Ktc8jS*7j|P>{_58ADN!fyy!06&}6ddTqmT*99OGU)y%O
zF7W8~Il2K%ha6qe?b_qh%ez7aDNKDqDWI1%7vicH3x9#abWXGD0><Xr1q>y7kGn1b
zn*}Q87$J%vo-Fzf3f(1)-L6Z(p6qs=0}fpiWJSK;L7_VbJ#^K+qlWGqh0a=7{DXsY
zIvY}Oa)536!r1Nl#oF}^I5^LOEji@T%en=u5)`n)U@>S-b>$l<VE=%e-tGFP`2b_*
z@fXX%e)|LGH-Xa+f`9uD$nOaLKXB&%bKLa@$QZD@{<9*vtKb_b1b#4fyZ!*XtK0Pt
zI0Pnwodk7=_cu@o{6S7jZv>!59(Vl!H+d<t$zouWKQMN?ez11^0rv3=u%RFydxBXY
zA1i`cP>UXYMe^|vh>vH1OX@$+oCWrQEwVl9zJh!J4cQ-{k{aTJ^T>)izoPp9-cWG;
z;i2vNA@(q&oeFL@!&}NApN-<t5Eu=C(GVCqA;1WpQAD^mq^LBN!7VYTIF&)QfI&5<
zl%YmJK|z5*wb)8E#YzD*6_%Q!qmWurkeXbQnxbH%T5PAIke*)xW^pm77Hep7F?g1!
z7b~RaXXd3Vl;kTEBo-Gl=;@cF7MH}QW#**Dr&j1CGt|Vpq^6}76{V&qxE2-V7b#dN
zsHSi+B!cZ=NL0wnOiqQcL9PoePAv+lEJ#(TF3!v?$VrXQ%qszD&{2T$i%W{E6jY0A
z!7eT4!fJde7X#Q4pm{%tBm6>rd_cy-F<8DhBfm5!B_8Z<xD14WEDs6{h$sWZ+|uII
zqWF@^f>f9&R6Mb$D6ujgMHXxhG%y%I?qOhHV3cOI2DLRnQ&Cgi{r?Z@ynK20|Gx+$
z0|U$Z|NnIu85ly||NjqaOxk|<|KEj?fnmjm|Nm1M85pj8`2W9!k%58l<NyCl7#SFx
zKmPxJgpq+E`Q!ipPZ${(=6wABpM{Bm;p)f#|5cb67$iUa|L?-Y!0`Li|NkjW3=Gdc
z|Nq~@#K3Uz%m4pNm>3w?zyAM!go%N{|Lgz%PnZ}On!f%2&%(^W@ZkIZ|0>K34Cj9Q
z|L?-gz%b$G|Nkk>3=E*TZIG`StAZF9D+Cy&dDuB7FhayZYd9+2{r|59QsBZ4nu2Cf
zVPIe|VPIfb@b>@z1duqNfE%BL7e9A7M+1Ysl$DmT3V1pfWNr)t1H+BC|NnzEg48lV
z%mvL^UwHffe*jbrM1kz;VPIhR`0oGzY><E}pFkUvGcOxc5)V5E0|Q8Y4Fdy%&HMlV
zK_e{;F!@xlG+6!&0|SHC`~UwzbKh|Je1tqGUXtGb|8I(HehxyOhmnDy{QZB(6d}y~
zaD+T49zpV!$odNq@;;0V3=`h}|Bp*PhmnC{<@^8t!D}*L=2s*1_b@UroPGcQ|087c
znQnp=fc?+Nz|jBU|Nqx0@{i#1XBZh6qCVo5f5XVYp!(_me=}tLxnS+!@Z(`(V6gu5
z|Gx*ad_6*5hlzn9`P2XZ#-QF1%>B$-j35;t_xUg}FqD1%|33~zJ`^sW!^FU_<;(y7
z?~u)BdJ57Gw!a6IUcdhTe+Wf>CtQ9F69a?FxBvg8kmUox(jbvhJQ@O{Aut*OqaiRF
z0;3@?8UlDj0JeS(wq6dlJ`T1X4z~Ucw%!f4z74jX4Yqy_wq6akJ`J`W4b%hzIRLcg
z4@C2T2oQ!ghIv731_lNTX$V6SLc!PhL4_GWQyL&CaGM7-1PU5kW`MMZLE<p^umAq%
zgZLXjbG8f&46wCg4?uIa3=9mgHDWiQ@~|~&J3*Ql7#N_-s2M<``ye4v5P^iD+88E4
z*O!5&ib2v9AOhO12QfkG+Ca28h+tq~*Z~!QQVbuU4uiS-1T>&vYv*A0%R%+S)cyVs
z@gE}tBuM^2`5U0-{fF|Q#xZ<=@@GNie?s|uP;;qG!Pa@Bn`;1#ZwDwH0HqV4bODq`
z*GDWLw$2gKX<=Y+cXqZ?&<IT`%_}KYFf`ON)-%vGECq87>x_)_3`{hk!uV|fg(C~Y
z$N%W6K=A}x&)Ne`5YXk644`G3*wlmKk%>WoK>)h`6lNYsA4uE*P289PwCYuW0hTXe
z>OuL4kwKb40lJ<O<UWvGD5(F<AjSY&2MZDd;TotpuzU^@1K|#^dQo^j1Brp~a`3(e
zO#f~JtCwOxUq^ZnEH2IfTW1T4#`92d*m_!+_&umNY~3tO9MmUeWDsY7t&fF?{{pL*
zW^jP|_XRY(L48zEI5>bikqitlaT!Ji21W)U1_9{$d|0rmL&Xiy#Ern>;ta5LwlI5L
z!Qw&;9#Hk5c}7t91VF_TpyIIdAsQ-P0TqXpYiUsNR;V~M8!{Av#ze5BD_rTP0&I>5
zgMcc?6{r|ndTRr#mta88kNw~TBMjfS05fS3SiK~?T!V>&7Fh@}2r$6PdvKqgfq~&L
zBWPW{00XStheiX#Ij}fPH-di6h<$y29ur7h3bZK)p_qYzft?9rKCHe0<r9zsVJ6Vp
zaVZ7~XnFvNfv^-vJ(D239s!AgumVUN#6ZJg%pmj81Q{3@tikF97;>N$5x9>Is&Am;
zMbHQbk3BFjFhqjIG0g$>@dX$#{Z)xWJ*dwQ^CPlpvzZte1ev55VC5T3ZUsmjw6g)K
z30l1|YzLb!zyPbi!DB=W3=D^$;;{N1JhsHZz;F&6p3)2&;K2@<=?n~)q3Umg2J;vg
z7{Fs43=9lKP;uD)D)5*X0|Ub&s5q?NhZ*+?Dh_KWz|zk@sJ-a%$OVoU0fs1OMGqbW
zVPIh3hl<16A>gqq1_lOcs5q?M0Upy~U|`UJit|A$Qt(&|0|SF2R9ptyuz*^_5DFGY
z_#ei~WQK%4x;sn3>IE2J?IZA58v_GF6Ei41!*nC)IZ*ZOpaDS!1_oIAS<B4803Ikr
zC<U`lfYdYbfD${H4<pWj#2Ew_mVycjP`JY+f|H9%4E6FE;^PyOGUH1U(;1SBN{UNL
z)6(>k84#N};!ASllR?`#iW%bLQ}W}}bMliCbK+A<@{5Y&6H6-?lJh~s(<P}XdIs24
zfcBzf#zTgLQ}arSDjCv>5_41IQ%ZAlD;eVBk$CZ$d6^|BO2Na%py6W3@O5!XQG8x$
zPL7@hXd4S?OgyzHEipNjAt^sU2Z>uyQiQ}SH8VltC6%V7r544*M)dW}8K5FXsl}x^
zC3<EcH<jik$H(iLBA6x&py6!LST~YU@$qR8g~kYlMhK=Mf@#1|T9TQgm&_0!?-u0f
z>l*Ls=Mo>!5bqM{=jiL{%n%>%?iU*G>H(GYa0z0FclYska`cJ!cXJDN4T%qNbn<bH
zX8`#uEx#x?v4jESEhrOXmyZK%(++{{IUwUeF_>7C$`GHLl30?+0FEz={XlR7O&~-6
zu%Uc#1VQHy!1Du;eMNBPpiM*Z@gRdCdw@XkmYiFFCXc#DC_be)KRzQdF9o!J$kRW*
zxFjVr4>X;S0@581^)o0fAe^3;0&y28mLO9SAQm{jpz1-v1y>)RR9p;o5GZv)(hp2w
zacU7*BTO~ekB|fmG8AHbZhlH>PJVoGX;N`XQDSmQW_}(6bTbv2=R$m)q0tRar7%;$
zyQZ*ig#z0L4O8%(4C<aPRO3Ne2JCeP2EF3S+>*p32EF2vA_$!UV`b)*q!tx0=;h^?
zr0S*TmFg7~<rjdwi6oR%nwgWLo0$R?a&+?41r-Zm<r#^^84P+Um3hULxe&Ufhyg59
zmReK{@;fpozKB7uC^aV$qyfq*$SGma1G`nPAg4qxJ->tj%qUJxX3#51ttes8OUum5
zWY8<h2PGB;z0?e7$&is!gy2EUhzCaoL<fuw(gm_quP7hvz{K3lWClHuD1%-SXg)4E
zKQ}iu4>X4YD*`E@LDd1MX$0%f;o8p&vje0S#s<;Kpf(G*tqtNaFu?Ya!e|4CFr0+-
z=U@V$dJEJygxQb2j}<iE1XBy5Vf8(T4Z@&)0kVErzXV1@n+YJLV2rLmoPmMi+yDRh
zF#BQsXBZ8$AJ%_HcYh+Z?+nuq>tDlY4rqXZ+z4XA^h2v>2GIUKP}3f!AJ$)o(XjqG
z*zw>#0gMHq3mF&~Kz(1Bepr7OMnju1@cutc9gMDHU|<0CrD1$ne;P)^nw#kEhuF@*
z&<pN2f%<F^5m^5oM#K8|=-~(R|8%H+Cx~|VcmZtOpaLom(hq8yqKDr?XqbTH!AfBr
z87K`(-(Yblfgb;$C2gR1f$3L(>VwhXIZmiv5CxTn@8bmZ8<F)lKo!7fC>Nv^jA48j
zy#dYr6QB|>8hMTsWB^neZa*k}AlnaXpTg)c*gy|RGjwk$lnJKxquCD|kAl&#{v22_
zG_GK55PcM?AC`XLn~|XzuM6ZjkU}VixgW}9IE$tq*S>O?di40aji%oN+NgxlXW$Nl
zm;g&Z5FP`=Qw9bG(3lV?4}!#C`)pzR&e7Gw_%Qk-sErQY9}dzF8;9_Ko&x|=2a*F}
z7#~Leg}NVRKWsc90IDBX{DaH_VJ=3<*d9zjtltYehX8io04V>0)WhtB#lvbe`(fjI
z6ZAo<85qEOMj%Wu3DXawg~9!2(9UJBG@?HXE%;&i94ZSLyn}HV7#Jj>19~v`!^U?c
zp!zvr7D4qulNFT5z#s>;AF3QK4%4p<7lANf$q|`GOCn%}9#8`hKnn)YI2LFq1Lho<
zzc`WN9;^{caF|0Fmth`*aKUGEK$&0)G){x21T22r3QRG8#%~}j2nlmHgvY=D0FOXj
A`~Uy|

-- 
GitLab


From 3cea2c76469572799d4055b594ab75f5304e0a91 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:29:11 +0000
Subject: [PATCH 097/229] ignore new bin

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 8110229..dd136f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ obj
 *.swp
 *.swo
 .vscode
+doc/test_main_ex
+doc/info_reader_ex
-- 
GitLab


From 178fe4489ae2b09c831b4066f9059818c540db48 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 6 Feb 2023 10:43:08 +0100
Subject: [PATCH 098/229] small changes

---
 lib/optparse.h |  2 +-
 makefile       | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/optparse.h b/lib/optparse.h
index 1925d73..ee7dcb6 100644
--- a/lib/optparse.h
+++ b/lib/optparse.h
@@ -73,7 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
-    void *(*fn)(void *, size_t);
+    void *(*fn)(void *, size_t);	/* SUBJECT TO CHANGE */
 };
 
 /**
diff --git a/makefile b/makefile
index d5d2d23..950028c 100644
--- a/makefile
+++ b/makefile
@@ -55,14 +55,14 @@ tests:
 	$(TESTS_DIR)/run
 
 format:
-	$(ASTYLE) $(SRC_DIR)/*.[ch]
-	$(ASTYLE) $(DOC_DIR)/*.[ch]
-	$(ASTYLE) $(TESTS_DIR)/*.[ch]
+	$(ASTYLE) $(SRC_DIR)/*.[ch] \
+		$(DOC_DIR)/*.[ch] \
+		$(TESTS_DIR)/*.[ch]
 
 clean:
-	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-	\rm -f $(SRC_DIR)/counters_option.h
-	\rm -f $(TESTS_DIR)/run
+	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
+		$(SRC_DIR)/counters_option.h \
+		$(TESTS_DIR)/run
 
 readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
-- 
GitLab


From a4e986e16dbd6df538feffafb379a83fc54ed8ea Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:04:56 +0000
Subject: [PATCH 099/229] fix: NB_MAX cpu

---
 doc/info_reader_ex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 23ee7d5..5cfa5f4 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 2
+#define MAX_PROCS 64 
 #define NB_KEYS 6
 
 typedef struct {
-- 
GitLab


From c0fa12bc47039fdeeebcda32f042c5d493f6b62c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:05:38 +0000
Subject: [PATCH 100/229] core: amd_rapl.c

---
 src/amd_rapl.c   | 92 ++++++++++++++++++++++++++++++++++++------------
 tests/amd_rapl.c | 34 +++---------------
 2 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 51df298..f6eff43 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -30,6 +30,7 @@
 #include "util.h"
 
 #define BUFFER_SIZE 64
+#define __READ_CPUINFO__
 
 // ---------------------------MSR_REGISTERS
 static const uint64_t amd_energy_mask = 0xFFFFFFFF;
@@ -62,11 +63,9 @@ typedef struct _amd_rapl_t _amd_rapl_t;
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-#warning "Must be modified before release"
-#define MAX_CPUS 64
 #define NB_KEYS 3
 
-static const char *cpuinfo = "/proc/cpuinfo";
+static char *cpuinfo = "/proc/cpuinfo";
 
 static GenericPointer uint_allocator(char *s)
 {
@@ -97,6 +96,21 @@ static KeyFinder keys[NB_KEYS] = {
     {"physical id", ": ", uint_allocator, _set_package_id},
     {"core id", ": ", uint_allocator, _set_core_id}
 };
+
+
+static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+    Parser parser = {
+        .storage = (GenericPointer) storage,
+        .nb_stored = 0,
+        .capacity = capacity,
+        .storage_struct_size = sizeof(cpu_sensor_t),
+        .keys = keys,
+        .nb_keys = NB_KEYS,
+        .file = fopen(cpuinfo, "r")
+    };
+    return parse(&parser);
+}
+
 #endif
 
 // --------------------------------READ_MSR
@@ -159,13 +173,14 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
+           sensor->core_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
-           sensor->core_energy,
+           sensor->core_energy
           );
 }
 
@@ -197,6 +212,22 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
+void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, cpu_sensor_t *sensors, unsigned int nb_sensor)
+{
+    unsigned int nb_package = 0;
+    unsigned int nb_core = 0;
+    for (unsigned int i = 0; i < nb_sensor; i++) {
+        if (sensors[i].package_id > nb_package) {
+            nb_package = sensors[i].package_id;
+        }
+        if (sensors[i].core_id > nb_core) {
+            nb_core = sensors[i].core_id;
+        }
+    }
+    *ret_nb_package = nb_package + 1;
+    *ret_nb_core = nb_core + 1;
+}
+
 char *get_name(unsigned int cpu_id)
 {
     static const char *base_name = "core%d";
@@ -216,27 +247,29 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
-{
-    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
-        return 0;
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+        return 1;
     }
-    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    return 0;
+}
 
+void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
+{
     static char filename[BUFFER_SIZE];
-    sprintf(filename, base_str, cpu_id);
+    snprintf(filename,BUFFER_SIZE, base_str, cpu_info->cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, base_str, cpu_id);
+        fprintf(stderr, base_str, cpu_info->cpu_id);
         perror(":open()");
         exit(127);
     }
 
-    sensor->cpu_id = cpu_id;
-    sensor->name = get_name(cpu_id);
+    memcpy(sensor, cpu_info, sizeof(cpu_sensor_t));
+    sensor->name = get_name(sensor->cpu_id);
     sensor->fd = fd;
-    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -256,7 +289,6 @@ void free_amd_rapl(_amd_rapl_t *rapl)
 unsigned int init_amd_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
     unsigned int max_cpus = get_nb_cpu();
     if (max_cpus == 0) {
@@ -265,18 +297,32 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
-    rapl->sensors = cpus;
+    cpu_sensor_t *cpu_information = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    if (parse_cpuinfo(cpu_information, max_cpus)) {
+        free(cpu_information);
+        PANIC(1, "cpuinfo");
+    }
 
-    unsigned int nb_cpu = 0;
+    unsigned int nb_package;
+    unsigned int nb_core;
+    get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
+
+    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+
+    unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
+        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+            init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
+            sensor_count += 1;
+        }
     }
-    rapl->sensor_count = nb_cpu;
+    free(cpu_information);
 
+    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+    rapl->sensors = sensors;
+    rapl->sensor_count = sensor_count;
     *ptr = (void *) rapl;
-    free(cpus_map);
     return rapl->sensor_count;
 }
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 39214fc..2425287 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -179,48 +179,24 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
-TFUNCTION(test_init_cpu_sensor, {
-    static const unsigned int max_cpus = 10;
-    unsigned char cpus_map[max_cpus * max_cpus];
-    cpu_sensor_t sensor_t1;
-    unsigned int result;
-    unsigned int expected;
-
-    // Test 1:
-    // -- Setup
-    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
-    result = 0;
-    expected = 1;
-    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
-    sensor_t1.cpu_id = 1;
-    sensor_t1.core_id = 0;
-    sensor_t1.package_id = 0;
-    // -- Run
-    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-})
-
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
-    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
 int main()
 {
-    test_amd_rapl();
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
+    unsigned int count_cpu = init_amd_rapl(NULL, (void **) &rapl);
+    uint64_t results[count_cpu];
+    char *labels[count_cpu];
 
     label_amd_rapl(labels, (void *) rapl);
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         printf("%s ", labels[i]);
     }
     printf("\n");
@@ -231,7 +207,7 @@ int main()
         sleep(1);
         get_amd_rapl(results, (void *)rapl);
 
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
+        for (unsigned int j = 0; j < rapl->sensor_count; ++j) {
             printf("%ld ", results[j]);
         }
         printf("\n");
-- 
GitLab


From 49e40f735fa71393d1102a73df6c782fbacc9dbb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 11:47:35 +0000
Subject: [PATCH 101/229] core: small_test modification of the api

---
 doc/info_reader_ex.c |   2 +-
 doc/test_file_ex.c   |  31 ++++++++----
 src/amd_rapl.c       |  14 +++---
 tests/amd_rapl.c     | 116 ++++++++++++++++++++++++++++++++++++++----
 tests/small_test.h   | 117 +++++++++++++++++++++++++++++++++++--------
 5 files changed, 231 insertions(+), 49 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 5cfa5f4..f672d98 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 64 
+#define MAX_PROCS 64
 #define NB_KEYS 6
 
 typedef struct {
diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 44ebc2c..4e3a093 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -35,6 +35,20 @@ TFUNCTION(test_should_fail, {
     TEST_STR(result, expected);
 })
 
+// -- A simple test of array
+TFUNCTION(test_array, {
+    static unsigned int size = 10;
+    int array[10];
+    TEST_ARRAY(TEST_INT, size, array, array);
+})
+
+// -- A simple test of array of pointer
+TFUNCTION(test_ptr_array, {
+    static unsigned int size = 10;
+    void *array[10];
+    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
+})
+
 // -- Add a new type in the test framework
 
 typedef struct {
@@ -89,24 +103,21 @@ TFUNCTION(test_user_type, {
 
 // -- Compare an array of usetype
 TFUNCTION(test_array_user_type, {
-    UserType *results[1];
-    UserType *expecteds[1];
-
-    UserType x1;
-    UserType x2;
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    UserType results[1];
+    UserType expecteds[1];
 
-    results[0] = &x1;
-    expecteds[0] = &x2;
+    DUMMY_USER_TYPE(results[0], 1, "John Doe");
+    DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
 })
 
 // Define the entry point of a test file
 TFILE_ENTRY_POINT(test_file_ex, {
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_array);
+    CALL_TFUNCTION(test_ptr_array);
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index f6eff43..1d9bc37 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -98,7 +98,8 @@ static KeyFinder keys[NB_KEYS] = {
 };
 
 
-static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+static unsigned int parse_cpuinfo(cpu_sensor_t *storage, unsigned int capacity)
+{
     Parser parser = {
         .storage = (GenericPointer) storage,
         .nb_stored = 0,
@@ -247,12 +248,13 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+{
     if (map[sensor->core_id * nb_core + sensor->package_id]) {
-        return 1;
+        return 0;
     }
     map[sensor->core_id * nb_core + sensor->package_id] += 1;
-    return 0;
+    return 1;
 }
 
 void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
@@ -307,8 +309,8 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
-    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 2425287..1857a6a 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -116,15 +116,15 @@ do {                                             \
     .energy_units = NONE,                        \
     .core_energy = NONE,                         \
   };                                             \
-	} while(0);
+} while(0);
 
 #define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
-	do {                                                 \
-		__rapl = (_amd_rapl_t) {                           \
-			.sensors = __sensors,                            \
-			.sensor_count = __sensors_count                 \
-		};                                                 \
-	} while(0);
+do {                                                   \
+    __rapl = (_amd_rapl_t) {                           \
+        .sensors = __sensors,                          \
+        .sensor_count = __sensors_count                \
+    };                                                 \
+} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
     cpu_sensor_t sensors[100];
@@ -142,7 +142,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 2:
     // -- Setup
@@ -159,7 +159,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 3:
     // -- Setup
@@ -176,13 +176,109 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+
+#define DUMMY_CPUINFO(__sensor, __cpu_id, __package_id, __core_id) \
+do {                                                               \
+    __sensor = (cpu_sensor_t) {                                    \
+        .cpu_id = __cpu_id,                                        \
+        .package_id = __package_id,                                \
+        .core_id = __core_id,                                      \
+        .name = NULL,                                              \
+        .fd = NONE,                                                \
+        .energy_units = NONE,                                      \
+        .core_energy = NONE                                        \
+    };                                                             \
+} while (0);
+
+TFUNCTION(test_is_duplicate, {
+    static const unsigned int nb_core = 4;
+    static const unsigned int nb_package = 2;
+    static const unsigned int max_cpu = 10;
+
+    unsigned char map[nb_core * nb_package];
+    cpu_sensor_t cpu_information[max_cpu];
+    unsigned int results[2];
+    unsigned int expecteds[2];
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+})
+
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    CALL_TFUNCTION(test_is_duplicate);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/small_test.h b/tests/small_test.h
index aedc685..ef9d90b 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,15 +33,17 @@
 /**
  * @brief Define the entry point of the tests
  * It initializes each useful variables.
+ *
+ * @param __code The code that contains the calls to the test functions
  */
 
-#define TMAIN(code)                                              \
+#define TMAIN(__code)                                              \
   int main()                                                     \
 {                                                                \
   unsigned int __indentation_level = 0;                          \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
-  do code while (0);                                             \
+  do __code while (0);                                             \
   DEFERRED_FILE_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
@@ -108,7 +110,6 @@
  * @def TEST_STR(result, expected)
  * @brief Test strings
  * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
- * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the string to be tested
  * @param __expected the expected value of the string
@@ -124,23 +125,43 @@
  * @def TEST_BOOL(__result, __expected)
  * @brief Test bools
  * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
- * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the bool to be tested
- * @param __expected the expected value of the bool
+ * @param __result the pointer to bool to be tested
+ * @param __expected the pointer to the expected value of the bool
  *
  * @code
- * TEST_BOOL(1 == 1, true);
+ * bool x = true;
+ * bool y = false;
+ * TEST_BOOL(&x, &y);
  * @endcode
  */
 #define TEST_BOOL(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
+/**
+ * @def TEST_INT(__result, __expected)
+ * @brief Test ints
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ *
+ * @param __result the pointer to int to be tested
+ * @param __expected the pointer to expected value of the int
+ *
+ * @code
+ * int x = 1;
+ * int y = 1;
+ * TEST_INT(&x, &y)
+ * @endcode
+ */
+#define TEST_INT(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
+
+
+
+
 /**
  * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
  * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
- * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the pointer to be tested
  * @param __expected the expected value of the pointer
@@ -159,24 +180,38 @@
  * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
  * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
- * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the integer to be tested
- * @param __expected the expected value of the integer
+ * @param __result the pointer to integer to be tested
+ * @param __expected the pointer to expected value of the integer
  *
  * @code
- * TEST_UINT64_T(5, 5);
+ * uint64_t x = 5;
+ * uint64_t y = 5;
+ * TEST_UINT64_T(&x, &y);
  * @endcode
  */
 #define TEST_UINT64_T(__result, __expected) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
 
+/**
+ * @def TEST_INTERFACE(__result, __expected, __interface)
+ * @brief Define a macro on a usertype with the given __interface
+ * This macro is used by the user to define a new test macro on a usertype.
+ *
+ * @param __result
+ * @param __expected
+ * @param __interface the usertype interface
+ *
+ * @code
+ * #define TEST_USERTYPE(__result, __expected)
+ * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * @endcode
+ */
 #define TEST_INTERFACE(__result, __expected, __interface) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
-
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
- * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
+ * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
  * @brief Test arrays of data
  * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
@@ -188,15 +223,33 @@
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
+ * TEST_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-	for (unsigned int i = 0; i < __array_size; i++) {                       \
-      __test_macro(__results[i], __expecteds[i]);                         \
-	}
+#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
+    for (unsigned i = 0; i < __array_size; i++) {                      \
+        __test_macro(&__results[i], &__expecteds[i]);                   \
+    }
 
+/**
+ * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
+ * @brief Test arrays of pointer
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
+ *
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
+ * @code
+ * void* array[3];
+ * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
+ * @endcode
+*/
+#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+    for (unsigned int i = 0; i < __array_size; i++) {                     \
+      __test_macro(__results[i], __expecteds[i]);                         \
+    }
 // --------------------------------API_CODE
 // These functions should not be used, only use the previous macros.
 
@@ -261,7 +314,6 @@ static const TestInterface str_interface = {
 
 //  --------------------------bool_interface
 
-
 int bool_compare(void *ptr1, void *ptr2)
 {
     bool *bool1 = (bool *) ptr1;
@@ -281,6 +333,27 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
+// ---------------------------int_interface
+
+int int_compare(void *ptr1, void *ptr2)
+{
+    int *int1 = (int *) ptr1;
+    int *int2 = (int *) ptr2;
+    return *int1 == *int2;
+}
+
+char *int_format(char buffer[1000], void *ptr)
+{
+    int *_int = (int *) ptr;
+    snprintf(buffer, 1000, "%d", *_int);
+    return buffer;
+}
+
+static const TestInterface int_interface = {
+    .compare = int_compare,
+    .format = int_format
+};
+
 // ---------------------------ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
-- 
GitLab


From 1616952d1be622d88232b46a90cd9bc97583d5fe Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:09:00 +0000
Subject: [PATCH 102/229] fix: is_duplicate

---
 src/amd_rapl.c   |  2 +-
 tests/amd_rapl.c | 24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 1d9bc37..0c363af 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 1857a6a..f2d13ef 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -200,8 +200,8 @@ TFUNCTION(test_is_duplicate, {
 
     unsigned char map[nb_core * nb_package];
     cpu_sensor_t cpu_information[max_cpu];
-    unsigned int results[2];
-    unsigned int expecteds[2];
+    unsigned int results[max_cpu];
+    unsigned int expecteds[max_cpu];
 
     // -- Setup
     memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
@@ -271,6 +271,26 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
+    
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[2], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[3], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[4], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[5], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[6], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[7], 0, 1, 1);
+    memset(expecteds, 1, sizeof(unsigned int) * 4);
+    memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
+    // -- Run
+    for (unsigned int i = 0; i < 8; i++) {
+        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+    }
+    // -- Verification
+    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
 })
 
 
-- 
GitLab


From a0b7dafae59bbbecb53dac6976c350cb77e3c739 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:15:20 +0000
Subject: [PATCH 103/229] fix: init_amd_rapl

---
 src/amd_rapl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0c363af..888df5a 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
-- 
GitLab


From f05faa31487b1c86ae104331a02e157e0410a3db Mon Sep 17 00:00:00 2001
From: Floreal Risso <frisso@grue-2.nancy.grid5000.fr>
Date: Mon, 6 Feb 2023 13:54:44 +0100
Subject: [PATCH 104/229] fix is_duplicate

---
 src/amd_rapl.c   | 11 ++++++-----
 tests/amd_rapl.c | 36 ++++++++++++++++++------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 888df5a..805e698 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -248,12 +248,12 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
 {
-    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+    if (map[sensor->core_id][sensor->package_id] == 1) {
         return 0;
     }
-    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    map[sensor->core_id][sensor->package_id] += 1;
     return 1;
 }
 
@@ -309,12 +309,13 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    unsigned char cpu_map[nb_core][nb_package];
+    memset(cpu_map, 0, sizeof(cpu_map));
     cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], nb_core, nb_package, cpu_map) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index f2d13ef..09ac0d9 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -198,82 +198,82 @@ TFUNCTION(test_is_duplicate, {
     static const unsigned int nb_package = 2;
     static const unsigned int max_cpu = 10;
 
-    unsigned char map[nb_core * nb_package];
+    unsigned char map[nb_core][nb_package];
     cpu_sensor_t cpu_information[max_cpu];
     unsigned int results[max_cpu];
     unsigned int expecteds[max_cpu];
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
+    results[1] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
     
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
@@ -287,7 +287,7 @@ TFUNCTION(test_is_duplicate, {
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
     for (unsigned int i = 0; i < 8; i++) {
-        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+        results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
     TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
-- 
GitLab


From eab8f8bf862f796b589374803af9d501d7a7ef08 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 6 Feb 2023 14:09:22 +0100
Subject: [PATCH 105/229] Add dev name to labels

plus some other changes, in particular:
- index --> strchr
- sprintf --> snprintf
---
 src/network.c | 34 ++++++++++++++++++++--------------
 1 file changed, 20 insertions(+), 14 deletions(-)

diff --git a/src/network.c b/src/network.c
index 543a053..aee5659 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,10 +28,17 @@
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
+char *_labels_network[NB_SENSOR] = {
+    "%s:rxp",
+    "%s:rxb",
+    "%s:txp",
+    "%s:txb",
+};
 struct network_t {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
+    char labels[NB_SENSOR][128];
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
@@ -54,8 +61,6 @@ unsigned int _get_network(uint64_t *results, int *sources)
     return NB_SENSOR;
 }
 
-
-
 unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
@@ -79,25 +84,27 @@ unsigned int init_network(char *dev, void **ptr)
             exit(1);
         }
 
-        char *start_of_dev = index(buffer, '\n') + 1;
-        char *end_of_dev = index(start_of_dev, '\t');
+        char *start_of_dev = strchr(buffer, '\n') + 1;
+        char *end_of_dev = strchr(start_of_dev, '\t');
         *end_of_dev = '\0';
         dev = start_of_dev;
         close(fd);
     }
 
-    char *filenames[] = {"/sys/class/net/%s/statistics/rx_packets",
-                         "/sys/class/net/%s/statistics/rx_bytes",
-                         "/sys/class/net/%s/statistics/tx_packets",
-                         "/sys/class/net/%s/statistics/tx_bytes"
-                        };
+    char *filenames[] = {
+        "/sys/class/net/%s/statistics/rx_packets",
+        "/sys/class/net/%s/statistics/rx_bytes",
+        "/sys/class/net/%s/statistics/tx_packets",
+        "/sys/class/net/%s/statistics/tx_bytes",
+    };
 
     struct network_t *state = malloc(sizeof(struct network_t));
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, filenames[i], dev);
+        snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
+        snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
     *ptr = (void *) state;
@@ -134,12 +141,11 @@ void clean_network(void *ptr)
     free(state);
 }
 
-char *_labels_network[NB_SENSOR] = {"rxp", "rxb", "txp", "txb"};
-void label_network(char **labels, void *none)
+void label_network(char **labels, void *ptr)
 {
-    UNUSED(none);
+    struct network_t *state = (struct network_t *) ptr;
 
     for (int i = 0; i < NB_SENSOR; i++) {
-        labels[i] = _labels_network[i];
+        labels[i] = state->labels[i];
     }
 }
-- 
GitLab


From 60dee1581ae9b8b5e15fbe6f8428b9f72d4c4fe5 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:39:07 +0000
Subject: [PATCH 106/229] fix: add ifndef

---
 src/info_reader.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/info_reader.h b/src/info_reader.h
index 1696ede..e83b2c3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -1,3 +1,26 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+#ifndef _INFO_READER_H
+#define _INFO_READER_
+
 #include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -216,3 +239,5 @@ static bool start_with(const char *prefix, const char *string)
     }
 }
 
+#endif
+
-- 
GitLab


From d68b9ca54bae21fce331367b6195517b541eb01c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:49:39 +0000
Subject: [PATCH 107/229] fix: add safety

---
 doc/test_file_ex.c |  4 ++--
 tests/small_test.h | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 4e3a093..13e1f48 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -63,10 +63,10 @@ int usertype_compare(void *ptr1, void *ptr2)
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
-char *usertype_format(char buffer[1000], void *ptr)
+char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
-    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    snprintf(buffer, FMT_BUFFER_SIZE, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
     return buffer;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index ef9d90b..eddbdb0 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -29,6 +29,8 @@
 
 #include "../src/util.h"
 
+#define FMT_BUFFER_SIZE 1000
+
 // ---------------------------API_INTERFACE
 /**
  * @brief Define the entry point of the tests
@@ -276,7 +278,7 @@
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
-typedef char *(Formatter) (char *, void *);
+typedef char *(Formatter) (char[FMT_BUFFER_SIZE], void *);
 
 typedef struct {
     Comparator *compare;
@@ -299,7 +301,7 @@ int str_compare(void *ptr1, void *ptr2)
     }
 }
 
-char *str_format(char *buffer, void *ptr)
+char *str_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     static char *str_null = "NULL";
@@ -321,7 +323,7 @@ int bool_compare(void *ptr1, void *ptr2)
     return *bool1 == *bool2;
 }
 
-char *bool_format(char *buffer, void *ptr)
+char *bool_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     bool *_bool = (bool *) ptr;
@@ -342,10 +344,10 @@ int int_compare(void *ptr1, void *ptr2)
     return *int1 == *int2;
 }
 
-char *int_format(char buffer[1000], void *ptr)
+char *int_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     int *_int = (int *) ptr;
-    snprintf(buffer, 1000, "%d", *_int);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%d", *_int);
     return buffer;
 }
 
@@ -361,9 +363,9 @@ int ptr_compare(void *ptr1, void *ptr2)
     return ptr1 == ptr2;
 }
 
-char *ptr_format(char *buffer, void *ptr)
+char *ptr_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
-    sprintf(buffer, "%p", ptr);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%p", ptr);
     return buffer;
 }
 
@@ -381,10 +383,10 @@ int u64_compare(void *ptr1, void *ptr2)
     return *v1 == *v2;
 }
 
-char *u64_format(char *buffer, void *ptr)
+char *u64_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     uint64_t *v = (uint64_t *) ptr;
-    sprintf(buffer, "%"PRIu64"", *v);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%"PRIu64"", *v);
     return buffer;
 }
 
@@ -398,8 +400,8 @@ static const TestInterface u64_interface = {
 int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
     __indentation_level += 1;
-    static char buffer_result[1000];
-    static char buffer_expected[1000];
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
     int is_equal = interface->compare(result, expected);
 
     char *fmt_result = interface->format(buffer_expected, expected);
-- 
GitLab


From 864213f5cfb7b9bfb3baedc31f572aa94baaac9c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:55:33 +0000
Subject: [PATCH 108/229] fix: documentation

---
 doc/test_file_ex.c |  93 +++++++++++++++--------
 doc/test_main_ex.c |   3 +-
 tests/amd_rapl.c   |  26 +++++--
 tests/small_test.h | 183 +++++++++++++++++++--------------------------
 4 files changed, 163 insertions(+), 142 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 13e1f48..95baaa7 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,49 +20,70 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
+// Include the file that contains the function you want to test 
+// #include "a_file.c"
 
-// -- A simple function that should pass
+// This example is divided into three parts:
+// 1. SOME SIMPLE EXAMPLES
+// 2. A MORE COMPLEX EXAMPLE
+// 3. FILE ENTRY POINT
+
+//  -----------------1. SOME SIMPLE EXAMPLES
+
+// A simple function that should pass
+// test_should_pass is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_pass, {
-    char *result = "It's going to pass";
-    char *expected = "It's going to pass";
-    TEST_STR(result, expected);
+    int result = 42;
+    int expected = 42;
+    TEST_INT(&result, &expected);
 })
 
-// -- A simple function that should fail
+// A simple function that should pass
+// test_should_fail is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_fail, {
     char *result = "a fail";
     char *expected = "a nice fail";
     TEST_STR(result, expected);
 })
 
-// -- A simple test of array
+// A simple test on an array
+// test_array is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_array, {
     static unsigned int size = 10;
-    int array[10];
-    TEST_ARRAY(TEST_INT, size, array, array);
+    int results[10] = {0};
+    int expecteds[10] = {0};
+    for (unsigned int i = 0; i < size; i++) {
+        TEST_INT(&results[i], &expecteds[i]);
+    }
 })
 
-// -- A simple test of array of pointer
-TFUNCTION(test_ptr_array, {
-    static unsigned int size = 10;
-    void *array[10];
-    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
-})
+// See "TFILE_ENTRY_POINT" for how to call these functions.
 
-// -- Add a new type in the test framework
+// ------------2. THE MORE COMPLEX EXAMPLE
+// This example shows how to add a new type to the framework
 
+// The type that you want to add :
 typedef struct {
     int simple_int;
     char simple_str[20];
 } UserType;
 
 
-// -- Implemet the interface
+// The test framework needs two functions :
+
+// A function that compares two values.
 int usertype_compare(void *ptr1, void *ptr2)
 {
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
+// A function to format a value.
 char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
@@ -70,17 +91,18 @@ char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
     return buffer;
 }
 
-// Create a variable which contains the functions
+// Store the functions in the interface type.
 static const TestInterface usertype_interface = {
     .compare = usertype_compare,
     .format = usertype_format
 };
 
-// -- Create the test macro to call
+// Create a macro that implements the interface by passing the interface created to the TEST_INTERFACE macro.
 #define TEST_USER_TYPE(__result, __expected) \
-    TEST_INTERFACE(__result, __expected, &usertype_interface);
+    TEST_INTERFACE(__result, __expected, &usertype_interface)
 
-// -- Create a macro setter
+
+// Creating a constructor is recommended (C can have problems parsing macros where "," is used).
 #define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
     do {                                                    \
       __user = (UserType) {                                 \
@@ -89,19 +111,22 @@ static const TestInterface usertype_interface = {
     };                                                      \
 } while (0);
 
-// -- Compare two usertype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_user_type, {
-    UserType x1;
-    UserType x2;
+    UserType result;
+    UserType expected;
 
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    DUMMY_USER_TYPE(result, 1, "John Doe");
+    DUMMY_USER_TYPE(expected, 1, "John Doe");
 
-    TEST_USER_TYPE(&x1, &x2);
+    TEST_USER_TYPE(&result, &expected);
 })
 
-
-// -- Compare an array of usetype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_array_user_type, {
     UserType results[1];
     UserType expecteds[1];
@@ -109,15 +134,23 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
+    for (unsigned int i = 0; i < 1; i++) {
+        TEST_USER_TYPE(&results[i], &expecteds[i]);
+    }
 })
 
+// ---------------------3. FILE ENTRY POINT
+
 // Define the entry point of a test file
+// Use the macro "CALL_TFUNCTION" where the name of a function is defined with the macro "TFUNCTION".
 TFILE_ENTRY_POINT(test_file_ex, {
+    // Call the simple examples
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
     CALL_TFUNCTION(test_array);
-    CALL_TFUNCTION(test_ptr_array);
+
+    // Call the more complex example
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
+
diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
index 0aa86b9..a5e7841 100644
--- a/doc/test_main_ex.c
+++ b/doc/test_main_ex.c
@@ -22,7 +22,7 @@
 // Include of the test library
 #include "./../tests/small_test.h"
 
-// Include the *.c files that contain the tests
+// Include the *.c files containing the tests
 #include "./test_file_ex.c"
 // #include "./test_another_test_file.c"
 
@@ -33,3 +33,4 @@ TMAIN({
     CALL_TFUNCTION(test_file_ex);
     // CALL_TFUNCTION(another_file_entry_point_function);
 })
+
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 09ac0d9..0485099 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -142,7 +142,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 
     // Test 2:
     // -- Setup
@@ -159,8 +162,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
-
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
     // Test 3:
     // -- Setup
     nb = 4;
@@ -176,7 +181,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 })
 
 
@@ -271,7 +279,7 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
-    
+
     // -- Setup
     memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
@@ -286,11 +294,15 @@ TFUNCTION(test_is_duplicate, {
     memset(expecteds, 1, sizeof(unsigned int) * 4);
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
-    for (unsigned int i = 0; i < 8; i++) {
+    for (unsigned int i = 0; i < 8; i++)
+    {
         results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
-    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
+    for(unsigned int i = 0; i < 8; i++)
+    {
+        TEST_BOOL(&results[i], &expecteds[i]);
+    }
 })
 
 
diff --git a/tests/small_test.h b/tests/small_test.h
index eddbdb0..abae768 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,10 +33,10 @@
 
 // ---------------------------API_INTERFACE
 /**
- * @brief Define the entry point of the tests
- * It initializes each useful variables.
+ * @brief Define the entry point for the tests.
+ * It initialises any useful variables and acts as the main one.
  *
- * @param __code The code that contains the calls to the test functions
+ * @param __code The code that contains the calls to the test functions.
  */
 
 #define TMAIN(__code)                                              \
@@ -46,22 +46,24 @@
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
   do __code while (0);                                             \
-  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  DEFERRED_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
 
 /**
+ * @def TFILE_ENTRY_POINT(__filename, __code)
+ *
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
  * It defines a function with the specified __filename that contains the test code specified in code.
  *
- * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
+ * When the function is called, it initialises the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __filename The name of the function to be used as an entry point for the test file.
  * @param __code The test code to be executed in the function.
  */
 #define TFILE_ENTRY_POINT(__filename, __code)       \
@@ -70,16 +72,18 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_FILE_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);           \
   return __error_counter__;                         \
 }
 
 /**
+ * @def TFUNCTION(__function_name, __code)
+ *
  * @brief Define a test function within a test file.
  * This macro is used to define a test function within a test file.
- * It defines a function with the specified function_name that contains the test code specified in code.
+ * It defines a function with the given __function_name containing the test code specified in __code.
  *
- * When the function is called, it initializes the test function using the INIT_TEST_FUNCTION macro,
+ * When the function is called, it initialises the test function using the INIT_TEST_FUNCTION macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
@@ -93,28 +97,32 @@
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
   do __code while(0); \
-  DEFERRED_FUNCTION_ERROR(__error_counter__); \
+  DEFERRED_ERROR(__error_counter__); \
   return __error_counter__; \
 }
 
 /**
+ * @def CALL_TFUNCTION(__function_name)
+ *
  * @brief Call a test function within a test file.
  * This macro is used to call a test function within a test file.
- * It calls the function specified by function_name and adds the return value to the __error_counter__ variable.
+ * It calls the function specified by __function_name and adds the return value to the __error_counter__ variable.
  * This allows multiple test functions to be executed and their error count to be accumulated.
  *
- * @param function_name The name of the test function to be called.
+ * @param __function_name The name of the test function to be called.
  */
-#define CALL_TFUNCTION(function_name) \
-  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
+#define CALL_TFUNCTION(__function_name) \
+  do {__error_counter__ += __function_name(__indentation_level + 1);} while(0)
 
 /**
- * @def TEST_STR(result, expected)
+ * @def TEST_STR(__result, __expected)
+ *
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to test, and `__expected`,
+ * which is the expected value of the string.
  *
- * @param __result the string to be tested
- * @param __expected the expected value of the string
+ * @param __result the string to test.
+ * @param __expected the expected value of the string.
  *
  * @code
  * TEST_STR("Hello", "Hello");
@@ -125,15 +133,17 @@
 
 /**
  * @def TEST_BOOL(__result, __expected)
+ *
  * @brief Test bools
- * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to test, and `__expected`,
+ * which is the expected value of the bool.
  *
- * @param __result the pointer to bool to be tested
- * @param __expected the pointer to the expected value of the bool
+ * @param __result the pointer to bool to test.
+ * @param __expected the pointer to the expected value of the bool.
  *
  * @code
  * bool x = true;
- * bool y = false;
+ * bool y = true;
  * TEST_BOOL(&x, &y);
  * @endcode
  */
@@ -142,11 +152,13 @@
 
 /**
  * @def TEST_INT(__result, __expected)
+ *
  * @brief Test ints
- * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be test, and `__expected`,
+ * which is the expected value of the int.
  *
- * @param __result the pointer to int to be tested
- * @param __expected the pointer to expected value of the int
+ * @param __result the pointer to int to test.
+ * @param __expected the pointer to expected value of the int.
  *
  * @code
  * int x = 1;
@@ -157,16 +169,15 @@
 #define TEST_INT(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
 
-
-
-
 /**
  * @def TEST_PTR(__result, __expected)
+ *
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to test, and `__expected`,
+ * which is the expected value of the pointer.
  *
- * @param __result the pointer to be tested
- * @param __expected the expected value of the pointer
+ * @param __result the pointer to test.
+ * @param __expected the expected value of the pointer.
  *
  * @code
  * int x = 5;
@@ -180,11 +191,13 @@
 
 /**
  * @def TEST_UINT64_T(__result, __expected)
+ *
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`,
+ * which is the integer to test, and `__expected`, which is the expected value of the integer.
  *
- * @param __result the pointer to integer to be tested
- * @param __expected the pointer to expected value of the integer
+ * @param __result the pointer to integer to test.
+ * @param __expected the pointer to expected value of the integer.
  *
  * @code
  * uint64_t x = 5;
@@ -197,64 +210,28 @@
 
 /**
  * @def TEST_INTERFACE(__result, __expected, __interface)
- * @brief Define a macro on a usertype with the given __interface
+ *
+ * @brief Define a macro on a usertype with the given __interface.
  * This macro is used by the user to define a new test macro on a usertype.
  *
  * @param __result
  * @param __expected
- * @param __interface the usertype interface
+ * @param __interface the interface of the usertype.
  *
  * @code
- * #define TEST_USERTYPE(__result, __expected)
- * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * TestInterface usertype_interface = {.compare = ..., .format = ...};
+ * #define TEST_USERTYPE(__result, __expected) \
+ * TEST_INTERFACE(__result, __expected, &usertype_interface)
  * @endcode
  */
 #define TEST_INTERFACE(__result, __expected, __interface) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
-/**
- * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
- * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
-
- * @code
- * int results[3] = {1, 2, 3};
- * int expecteds[3] = {1, 2, 3};
- * TEST_ARRAY(TEST_INT, 3, results, expecteds);
- * @endcode
-*/
-#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
-    for (unsigned i = 0; i < __array_size; i++) {                      \
-        __test_macro(&__results[i], &__expecteds[i]);                   \
-    }
 
-/**
- * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
- * @brief Test arrays of pointer
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
 
- * @code
- * void* array[3];
- * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
- * @endcode
-*/
-#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-    for (unsigned int i = 0; i < __array_size; i++) {                     \
-      __test_macro(__results[i], __expecteds[i]);                         \
-    }
-// --------------------------------API_CODE
-// These functions should not be used, only use the previous macros.
 
+// ------------------------------------CODE
+// These functions should not be in use, only the previous macros should be in use.
 
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
@@ -271,10 +248,7 @@
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-#define DEFERRED_FILE_ERROR(nb_error) \
-    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-
-#define DEFERRED_FUNCTION_ERROR(nb_error) \
+#define DEFERRED_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
@@ -285,8 +259,26 @@ typedef struct {
     Formatter *format;
 } TestInterface;
 
-//  ---------------------------str_interface
+// ---------------------------TEST FUNCTION
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
+{
+    __indentation_level += 1;
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
+    int is_equal = interface->compare(result, expected);
+
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
+    if  (!is_equal) {
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
+    }
+    return !is_equal;
+}
+
+// ------------------------------INTERFACES
 
+// -- str_interface
 int str_compare(void *ptr1, void *ptr2)
 {
     char *str1 = (char *) ptr1;
@@ -314,7 +306,7 @@ static const TestInterface str_interface = {
     .format = str_format
 };
 
-//  --------------------------bool_interface
+// -- bool_interface
 
 int bool_compare(void *ptr1, void *ptr2)
 {
@@ -335,7 +327,7 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
-// ---------------------------int_interface
+// -- int_interface
 
 int int_compare(void *ptr1, void *ptr2)
 {
@@ -356,7 +348,7 @@ static const TestInterface int_interface = {
     .format = int_format
 };
 
-// ---------------------------ptr_interface
+// -- ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
 {
@@ -374,7 +366,7 @@ static const TestInterface ptr_interface = {
     .format = ptr_format
 };
 
-// ---------------------------u64_interface
+// -- u64_interface
 
 int u64_compare(void *ptr1, void *ptr2)
 {
@@ -395,22 +387,5 @@ static const TestInterface u64_interface = {
     .format = u64_format
 };
 
-// ---------------------------test_function
-
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
-{
-    __indentation_level += 1;
-    static char buffer_result[FMT_BUFFER_SIZE];
-    static char buffer_expected[FMT_BUFFER_SIZE];
-    int is_equal = interface->compare(result, expected);
-
-    char *fmt_result = interface->format(buffer_expected, expected);
-    char *fmt_expected = interface->format(buffer_result, result);
-    if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
-    }
-    return !is_equal;
-}
-
 #endif
 
-- 
GitLab


From 7c42bf0b1a5816d231182b8f5ba5e6394252188d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:58:49 +0000
Subject: [PATCH 109/229] format

---
 doc/test_file_ex.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 95baaa7..0595e9a 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,7 +20,7 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
-// Include the file that contains the function you want to test 
+// Include the file that contains the function you want to test
 // #include "a_file.c"
 
 // This example is divided into three parts:
@@ -58,7 +58,8 @@ TFUNCTION(test_array, {
     static unsigned int size = 10;
     int results[10] = {0};
     int expecteds[10] = {0};
-    for (unsigned int i = 0; i < size; i++) {
+    for (unsigned int i = 0; i < size; i++)
+    {
         TEST_INT(&results[i], &expecteds[i]);
     }
 })
@@ -134,7 +135,8 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    for (unsigned int i = 0; i < 1; i++) {
+    for (unsigned int i = 0; i < 1; i++)
+    {
         TEST_USER_TYPE(&results[i], &expecteds[i]);
     }
 })
-- 
GitLab


From dae6da3cbd9951709bb3a2a4a294b13bc1224ea1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:59:19 +0000
Subject: [PATCH 110/229] fix: use a const

---
 src/load.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/load.c b/src/load.c
index 6dcf2b0..1c049ce 100644
--- a/src/load.c
+++ b/src/load.c
@@ -26,11 +26,12 @@
 #include "util.h"
 
 #define LOAD_BUFFER_SIZE 1024
+#define LOAD_VALUES_SIZE 10
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid = -1;
-static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t tmp_load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
@@ -46,8 +47,8 @@ void _get_load(uint64_t *results)
         pos++;
     }
 
-    for (int i = 0; i < 10; i++) {
-        results[i] = strtoull(buffer + pos, NULL, 10);
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
+        results[i] = strtoull(buffer + pos, NULL, LOAD_VALUES_SIZE);
 
         while (buffer[pos] <= '9' && buffer[pos] >= '0') {
             pos++;
@@ -71,7 +72,7 @@ unsigned int init_load(char *argument, void **state)
     }
 
     _get_load(load_values);
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 unsigned int get_load(uint64_t *results, void *state)
@@ -79,12 +80,12 @@ unsigned int get_load(uint64_t *results, void *state)
     UNUSED(state);
     _get_load(tmp_load_values);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         results[i] = tmp_load_values[i] - load_values[i];
     }
 
     memcpy(load_values, tmp_load_values, sizeof(load_values));
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 void clean_load(void *state)
@@ -93,14 +94,15 @@ void clean_load(void *state)
     close(load_fid);
 }
 
-char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
-                     "softirq", "steal", "guest", "guest_nice"
-                    };
+char *_labels[LOAD_VALUES_SIZE] = {
+    "user", "nice", "system", "idle", "iowait", "irq",
+    "softirq", "steal", "guest", "guest_nice"
+};
 void label_load(char **labels, void *none)
 {
     UNUSED(none);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         labels[i] = _labels[i];
     }
 }
-- 
GitLab


From 189f9fc703b62d4ccfe7233bd0ee3271d696ceb0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:17:33 +0000
Subject: [PATCH 111/229] cleanup

---
 doc/info_reader_ex.c | 54 ++++++++++++++++++++++++++++++--------------
 src/info_reader.h    |  8 +++----
 2 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index f672d98..2e76251 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -23,8 +23,8 @@
 #include "./../src/info_reader.h"
 
 #define MAX_PROCS 64
-#define NB_KEYS 6
 
+// -----------------------------The storage
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -34,12 +34,16 @@ typedef struct {
     char *model_name;
 } Cpu;
 
+// --------------IMPLEMENTING THE INTERFACE
+
+// -- Define the behaviour if the attempted value is an int
 GenericPointer int_allocator(char *s)
 {
     unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
+// -- Define the behaviour if the attempted value is a string
 GenericPointer string_allocator(char *s)
 {
     char *value = malloc(strlen(s) + 1);
@@ -47,31 +51,42 @@ GenericPointer string_allocator(char *s)
     return (GenericPointer) value;
 }
 
+// -- Define the processor setter
 void set_processor(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->processor = data;
 }
+
+// -- Define the vendor_id setter
 void set_vendor_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->vendor_id = (char *) data;
 }
+
+// -- Define the family setter
 void set_family(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->family = data;
 }
+
+// -- Define the core_id setter
 void set_core_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->core_id = data;
 }
+
+// -- Define the physical_id setter
 void set_physical_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->physical_id = data;
 }
+
+// -- Define the model_name setter
 void set_model_name(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
@@ -81,28 +96,33 @@ void set_model_name(GenericPointer storage, GenericPointer data)
 int main()
 {
     Cpu cpus[MAX_PROCS];
+
+    // -- Define the setter, the allocator for each key / separator.
     KeyFinder keys[] = {
-        {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
-        {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
-        {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
-        {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
-        {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
-        {
-            "model name", ": ", (CopyAllocator *) string_allocator,
-            (Setter *)set_model_name
-        }
+        {.key = "processor", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_processor},
+        {.key = "vendor_id", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_vendor_id},
+        {.key = "cpu family", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_family},
+        {.key = "core id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_core_id},
+        {.key = "physical id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_physical_id},
+        {.key = "model name", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_model_name}
     };
 
-    Parser parser = {.storage = (GenericPointer) cpus,
-                     .capacity = MAX_PROCS,
-                     .storage_struct_size = sizeof(Cpu),
-                     .keys = keys,
-                     .nb_keys = NB_KEYS,
-                     .file = fopen("/proc/cpuinfo", "r")
-                    };
+    size_t nb_keys = sizeof(keys)/sizeof(KeyFinder);
+
+    // -- Init the parser
+    Parser parser = {
+        .storage = (GenericPointer) cpus,
+        .capacity = MAX_PROCS,
+        .storage_struct_size = sizeof(Cpu),
+        .keys = keys,
+        .nb_keys = nb_keys,
+        .file = fopen("/proc/cpuinfo", "r")
+    };
 
+    // -- Parse the file
     parse(&parser);
 
+    // Print and free the results
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
         printf("Processor: %u\n", cpus[i].processor);
diff --git a/src/info_reader.h b/src/info_reader.h
index e83b2c3..0d694d3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -96,10 +96,10 @@ static bool start_with(const char *prefix, const char *string);
 /**
  * @brief Matches a line of text to a key in the parser's list of keys.
  *
- * @param parser Pointer to the Parser struct.
- * @param line Line of text to match.
- * @param key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
- * @param raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
+ * @param[in] parser Pointer to the Parser struct.
+ * @param[in] line Line of text to match.
+ * @param[out] key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
+ * @param[out] raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
  *
  * @return Returns 1 if a key is matched, 0 otherwise.
  */
-- 
GitLab


From 0c9216eda1457ada2805f1cdf023c26dbfd2aeed Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:25:30 +0000
Subject: [PATCH 112/229] format

---
 tests/small_test.h | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index abae768..bf0ca10 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -39,15 +39,15 @@
  * @param __code The code that contains the calls to the test functions.
  */
 
-#define TMAIN(__code)                                              \
-  int main()                                                     \
-{                                                                \
-  unsigned int __indentation_level = 0;                          \
-  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
-  unsigned int __error_counter__ = 0;                            \
-  do __code while (0);                                             \
-  DEFERRED_ERROR(__error_counter__);                        \
-  return __error_counter__;                                      \
+#define TMAIN(__code)                            \
+  int main()                                     \
+{                                                \
+  unsigned int __indentation_level = 0;          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__); \
+  unsigned int __error_counter__ = 0;            \
+  do __code while (0);                           \
+  DEFERRED_ERROR(__error_counter__);             \
+  return __error_counter__;                      \
 }
 
 /**
@@ -72,7 +72,7 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);                \
   return __error_counter__;                         \
 }
 
@@ -91,14 +91,14 @@
  * @param __function_name The name of the test function.
  * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(__function_name, __code) \
+#define TFUNCTION(__function_name, __code)              \
   int __function_name(unsigned int __indentation_level) \
-{ \
-  INIT_TEST_FUNCTION(); \
-  int __error_counter__ = 0; \
-  do __code while(0); \
-  DEFERRED_ERROR(__error_counter__); \
-  return __error_counter__; \
+{                                                       \
+  INIT_TEST_FUNCTION();                                 \
+  int __error_counter__ = 0;                            \
+  do __code while(0);                                   \
+  DEFERRED_ERROR(__error_counter__);                    \
+  return __error_counter__;                             \
 }
 
 /**
@@ -236,13 +236,13 @@
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
     for(unsigned int i = 0; i < __indentation_level; i++) { \
-      printf("|    ");                                       \
+      printf("|    ");                                      \
     }                                                       \
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
 
-#define INIT_TEST_FILE()     \
+#define INIT_TEST_FILE() \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 #define INIT_TEST_FUNCTION() \
-- 
GitLab


From 971ab6da9ffc4fcb071df8ff7e50e1ed0f3cd743 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:26:24 +0000
Subject: [PATCH 113/229] doc

---
 tests/small_test.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/small_test.h b/tests/small_test.h
index bf0ca10..66c4de9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,6 +33,8 @@
 
 // ---------------------------API_INTERFACE
 /**
+ * @def TMAIN(__code)
+ *
  * @brief Define the entry point for the tests.
  * It initialises any useful variables and acts as the main one.
  *
-- 
GitLab


From 644f97f5df56c63f9b5c0260e447c6bc2c599350 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:35:54 +0000
Subject: [PATCH 114/229] fix: header

---
 src/info_reader.h   | 2 +-
 tests/info_reader.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/info_reader.h b/src/info_reader.h
index 0d694d3..ec28db6 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -19,7 +19,7 @@
 *******************************************************/
 
 #ifndef _INFO_READER_H
-#define _INFO_READER_
+#define _INFO_READER_H
 
 #include <string.h>
 #include <stdbool.h>
diff --git a/tests/info_reader.c b/tests/info_reader.c
index b2a8c6f..19d9c0a 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -19,6 +19,7 @@
 *******************************************************/
 
 #include "small_test.h"
+#include "./../src/info_reader.h"
 
 TFUNCTION(test_replace_first, {
     // useful variables :
-- 
GitLab


From 72ae8099f4559689c3d8a30957a5933b695101a6 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 12:44:18 +0000
Subject: [PATCH 115/229] fix unit size

---
 src/amd_rapl.c | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 09ea7c0..31944b1 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -49,7 +49,7 @@ struct cpu_sensor_t {
     char *name;
 
     int fd;
-    uint64_t energy_units;
+    unsigned int energy_units;
     uint64_t core_energy;
     uint64_t pkg_energy;
 };
@@ -107,7 +107,7 @@ uint64_t read_msr(int fd, uint64_t msr)
     return data;
 }
 
-uint64_t read_unit(int fd)
+unsigned int read_unit(int fd)
 {
     uint64_t unit = read_msr(fd, msr_rapl_power_unit);
     return ((unit & amd_energy_unit_mask) >> 8);
@@ -127,14 +127,12 @@ uint64_t read_raw_pkg_energy(int fd)
 
 // ---------------------------------ENERGY
 
-uint64_t raw_to_microjoule(uint64_t raw, uint64_t unit)
+uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
     static const double to_microjoule = 1000000.0;
-    double d_raw = (double) raw;
-    double d_unit = (double) unit;
     // raw * (1 / (unit^2)) -> Joule
     // Joule * 1000000 -> uJoule
-    return  ((d_raw * to_microjoule) / (d_unit * d_unit));
+    return (uint64_t) (((double) raw * to_microjoule) / (double)(1U << unit));
 }
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
@@ -149,7 +147,7 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %ld, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
-- 
GitLab


From ae734b928303fa5690dd1c51b83bc1f1e25751b1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 13:03:20 +0000
Subject: [PATCH 116/229] clear code

---
 src/amd_rapl.c   | 52 ------------------------------------------------
 tests/amd_rapl.c |  6 +++---
 2 files changed, 3 insertions(+), 55 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 31944b1..0d2ed29 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -165,20 +165,6 @@ void debug_print_amd_rapl(_amd_rapl_t *rapl)
     }
 }
 
-// typedef struct {
-//     size_t cpu_id;
-//     uint64_t *results;
-//     size_t capacity;
-// } CpuLogger;
-//
-// CpuLogger init_logger(size_t cpu_id, size_t capacity)
-// {
-//
-// }
-//
-// void log_value();
-
-
 #endif
 
 // ---------------------------AMD_RAPL_UTIL
@@ -321,41 +307,3 @@ void clean_amd_rapl(void *ptr)
     free(rapl->sensors);
     free(rapl);
 }
-
-// -----------------------------ENTRY_POINT
-
-#ifdef __TESTING_AMD__
-#ifdef DEBUG
-int main()
-{
-    s_round_to_uint64(1.0);
-    static const unsigned int time = 10;
-    _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
-
-    label_amd_rapl(labels, (void *) rapl);
-
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
-        printf("%s ", labels[i]);
-    }
-    printf("\n");
-
-    // -- Run
-
-    for (unsigned int i = 0; i < time; ++i) {
-        sleep(1);
-        get_amd_rapl(results, (void *)rapl);
-
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
-            printf("%ld ", results[j]);
-        }
-        printf("\n");
-    }
-
-    clean_amd_rapl(rapl);
-    return 0;
-}
-#endif
-#endif
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 3f97f32..ddf76ae 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -11,7 +11,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 100;
     unit = 1000;
-    expected = 100;
+    expected = 390625;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -21,7 +21,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 200;
     unit = 1;
-    expected = 200000000;
+    expected = 100000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
@@ -41,7 +41,7 @@ TFUNCTION(test_raw_to_microjoule, {
     // -- Setup
     raw = 1000;
     unit = 3;
-    expected = 111111111;
+    expected = 125000000;
     // -- Run
     result = raw_to_microjoule(raw, unit);
     // -- Verification
-- 
GitLab


From 5d63d39b713348c4596905f0cebaba9a127dfd3b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 31 Jan 2023 14:46:27 +0000
Subject: [PATCH 117/229] format

---
 tests/info_reader.c | 67 +++++++++++++++++++++++----------------------
 1 file changed, 34 insertions(+), 33 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 761d86a..9504631 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -84,28 +84,29 @@ TFUNCTION(test_start_with, {
     TEST_BOOLEAN(&result, &_false);
 })
 
-#define DUMB_KEYFINDER(key_finder, key, delimiter)  \
-	do { 											\
-		key_finder = (KeyFinder) {					\
-			key,									\
-			delimiter,								\
-			0,										\
-			0										\
-		}; 											\
-	} while (0);
-
-#define DUMB_PARSER(parser, keys, nb_keys)  \
-	do {									\
-		parser = (Parser) {					\
-			0,			   					\
-			0,			   					\
-			0,			   					\
-			0,  							\
-			keys,			   				\
-			nb_keys, 		   				\
-			0								\
-		};							   		\
-	} while (0);
+#define NONE 0
+#define DUMMY_KEYFINDER(__key_finder, __key, __delimiter) \
+  do {                                                    \
+    __key_finder = (KeyFinder) {                          \
+      .key = __key,                                       \
+      .delimiter = __delimiter,                           \
+      .copy = NONE,                                       \
+      .set = NONE                                         \
+    };                                                    \
+  } while (0);
+
+#define DUMMY_PARSER(__parser, __keys, __nb_keys) \
+  do {                                            \
+    __parser = (Parser) {                         \
+      .storage = NONE,                            \
+      .nb_stored = NONE,                          \
+      .capacity = NONE,                           \
+      .storage_struct_size = NONE,                \
+      .keys = __keys,                             \
+      .nb_keys = __nb_keys,                       \
+      .file = NONE                                \
+    };                                            \
+  } while (0);
 
 
 TFUNCTION(test_match, {
@@ -121,8 +122,8 @@ TFUNCTION(test_match, {
 
     // Test 1:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -135,8 +136,8 @@ TFUNCTION(test_match, {
 
     // Test 2:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1)
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1)
     strcpy(line, "not a key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -149,8 +150,8 @@ TFUNCTION(test_match, {
 
     // Test 3:
     // -- Setup
-    DUMB_KEYFINDER(keys[0],"key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0],"key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "key:value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -163,9 +164,9 @@ TFUNCTION(test_match, {
 
     // Test 4:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_KEYFINDER(keys[1], "second_key", ": ");
-    DUMB_PARSER(parser, keys, 2);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_KEYFINDER(keys[1], "second_key", ": ");
+    DUMMY_PARSER(parser, keys, 2);
     strcpy(line, "second_key: value");
     found_key_finder = NULL;
     raw_value = NULL;
@@ -178,8 +179,8 @@ TFUNCTION(test_match, {
 
     // Test 5:
     // -- Setup
-    DUMB_KEYFINDER(keys[0], "key", ": ");
-    DUMB_PARSER(parser, keys, 1);
+    DUMMY_KEYFINDER(keys[0], "key", ": ");
+    DUMMY_PARSER(parser, keys, 1);
     strcpy(line, "");
     found_key_finder = NULL;
     raw_value = NULL;
-- 
GitLab


From e052fe6b71eb27213afbf631d6c25407e449aa24 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:03 +0000
Subject: [PATCH 118/229] modification of test api

---
 tests/amd_rapl.c   |  81 +++++++++++++++++++------------
 tests/main.c       |   2 +-
 tests/small_test.h | 115 ++++++++++++++++++++++++---------------------
 3 files changed, 115 insertions(+), 83 deletions(-)

diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index ddf76ae..262c1f8 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -85,25 +85,25 @@ TFUNCTION(test_get_name, {
 })
 
 #define NONE 0
-#define DUMB_SENSOR(sensor, cpu_id, name)	\
-	do {									\
-		sensor = (cpu_sensor_t) {			\
-			cpu_id,							\
-			NONE,							\
-			name,							\
-			NONE,							\
-			NONE,							\
-			NONE, 							\
-			NONE							\
-		}; 									\
+#define DUMMY_SENSOR(__sensor, __cpu_id, __name) \
+do {                                             \
+  __sensor = (cpu_sensor_t) {                    \
+    .cpu_id = __cpu_id,                          \
+    .package_id = NONE,                          \
+    .core_id = NONE,                             \
+    .name = __name,                              \
+    .fd = NONE,                                  \
+    .energy_units = NONE,                        \
+    .core_energy = NONE,                         \
+  };                                             \
 	} while(0);
 
-#define DUMB_RAPL(rapl, sensors, nb)		\
-	do {									\
-		rapl = (_amd_rapl_t) {				\
-			sensors,						\
-			nb								\
-		};									\
+#define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
+	do {                                                 \
+		__rapl = (_amd_rapl_t) {                           \
+			.sensors = __sensors,                            \
+			.sensor_count = __sensors_count                 \
+		};                                                 \
 	} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
@@ -116,8 +116,8 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 1:
     // -- Setup
     nb = 1;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
@@ -127,11 +127,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 2:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 1, "core1");
-    DUMB_SENSOR(sensors[2], 2, "core2");
-    DUMB_SENSOR(sensors[3], 3, "core3");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 1, "core1");
+    DUMMY_SENSOR(sensors[2], 2, "core2");
+    DUMMY_SENSOR(sensors[3], 3, "core3");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core1");
     strcpy(expecteds[2], "core2");
@@ -144,11 +144,11 @@ TFUNCTION(test_label_amd_rapl, {
     // Test 3:
     // -- Setup
     nb = 4;
-    DUMB_SENSOR(sensors[0], 0, "core0");
-    DUMB_SENSOR(sensors[1], 3, "core3");
-    DUMB_SENSOR(sensors[2], 1, "core1");
-    DUMB_SENSOR(sensors[3], 2, "core2");
-    DUMB_RAPL(rapl, sensors, nb);
+    DUMMY_SENSOR(sensors[0], 0, "core0");
+    DUMMY_SENSOR(sensors[1], 3, "core3");
+    DUMMY_SENSOR(sensors[2], 1, "core1");
+    DUMMY_SENSOR(sensors[3], 2, "core2");
+    DUMMY_RAPL(rapl, sensors, nb);
     strcpy(expecteds[0], "core0");
     strcpy(expecteds[1], "core3");
     strcpy(expecteds[2], "core1");
@@ -159,10 +159,33 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+TFUNCTION(test_init_cpu_sensor, {
+    static const unsigned int max_cpus = 10;
+    unsigned char cpus_map[max_cpus * max_cpus];
+    cpu_sensor_t sensor_t1;
+    unsigned int result;
+    unsigned int expected;
+
+    // Test 1:
+    // -- Setup
+    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
+    result = 0;
+    expected = 1;
+    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
+    sensor_t1.cpu_id = 1;
+    sensor_t1.core_id = 0;
+    sensor_t1.package_id = 0;
+    // -- Run
+    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
+    // -- Verification
+    TEST_UINT64_T(&result, &expected);
+})
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/main.c b/tests/main.c
index a3a43cb..e48b56a 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -2,7 +2,7 @@
 #include "amd_rapl.c"
 #include "info_reader.c"
 
-TFILE_ENTRY_POINT(main, {
+TMAIN({
     CALL_TFUNCTION(test_util);
     CALL_TFUNCTION(test_amd_rapl);
     CALL_TFUNCTION(test_info_reader);
diff --git a/tests/small_test.h b/tests/small_test.h
index 0e39868..357479a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -9,10 +9,23 @@
 
 // ---------------------------API_INTERFACE
 
+
+
+#define TMAIN(code)                                              \
+  int main()                                                     \
+{                                                                \
+  unsigned int __indentation_level = 0;                          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
+  unsigned int __error_counter__ = 0;                            \
+  do code while (0);                                             \
+  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  return __error_counter__;                                      \
+}
+
 /**
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
- * It defines a function with the specified file_name that contains the test code specified in code.
+ * It defines a function with the specified __filename that contains the test code specified in code.
  *
  * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
@@ -20,17 +33,17 @@
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param file_name The name of the function that serves as the entry point for the test file.
- * @param code The test code to be executed in the function.
+ * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __code The test code to be executed in the function.
  */
-#define TFILE_ENTRY_POINT(file_name, code) \
-  int file_name() \
-{ \
-  INIT_TEST_FILE();\
-  int __error_counter__ = 0;\
-  do code while(0);\
-  DEFERRED_FILE_ERROR(__error_counter__); \
-  return __error_counter__;\
+#define TFILE_ENTRY_POINT(__filename, __code)       \
+  int __filename (unsigned int __indentation_level) \
+{                                                   \
+  INIT_TEST_FILE();                                 \
+  int __error_counter__ = 0;                        \
+  do __code while(0);                               \
+  DEFERRED_FILE_ERROR(__error_counter__);           \
+  return __error_counter__;                         \
 }
 
 /**
@@ -43,15 +56,15 @@
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
  *
- * @param function_name The name of the test function.
- * @param code The test code to be executed in the function.
+ * @param __function_name The name of the test function.
+ * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(function_name, code) \
-  int function_name() \
+#define TFUNCTION(__function_name, __code) \
+  int __function_name(unsigned int __indentation_level) \
 { \
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
-  do code while(0); \
+  do __code while(0); \
   DEFERRED_FUNCTION_ERROR(__error_counter__); \
   return __error_counter__; \
 }
@@ -65,7 +78,7 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name()
+  __error_counter__ += function_name(__indentation_level + 1)
 
 
 /**
@@ -82,7 +95,7 @@
  * @endcode
  */
 #define TEST_STR(result, expected) \
-	__error_counter__ += test_str(__FILE__, __LINE__, result, expected)
+    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_BOOLEAN(result, expected)
@@ -98,7 +111,7 @@
  * @endcode
  */
 #define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_PTR(result, expected)
@@ -116,7 +129,7 @@
  * @endcode
  */
 #define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
 
 
 /**
@@ -133,7 +146,7 @@
  * @endcode
  */
 #define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, result, expected)
+	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
@@ -161,6 +174,15 @@
 
 // --------------------------------API_CODE
 
+
+#define INDENTED_PRINT(__fmt, ...)                          \
+  do {                                                      \
+    for(unsigned int i = 0; i < __indentation_level; i++) { \
+      printf("|    ");                                       \
+    }                                                       \
+    printf(__fmt, ##__VA_ARGS__);                           \
+  } while(0)
+
 /**
  * @def INIT_TEST_FILE()
  * @brief Initialize the test file
@@ -173,8 +195,8 @@
  * INIT_TEST_FILE();
  * @endcode
  */
-#define INIT_TEST_FILE() \
-	init_test_file(__FILE__, __func__)
+#define INIT_TEST_FILE()     \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 /**
  * @def INIT_TEST_FUNCTION()
@@ -188,13 +210,14 @@
  * @endcode
  */
 #define INIT_TEST_FUNCTION() \
-	init_test_function(__func__)
+  INDENTED_PRINT("%s()\n", __func__);
 
 #define DEFERRED_FILE_ERROR(nb_error) \
-	  printf("========== Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
+//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
-	  printf("       | Deferred Error : %d\n", nb_error);
+    INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 #define FMT_NULL(string) \
 	string = string ? string : "NULL"
@@ -252,65 +275,51 @@ char *uint64_t_format(char *buffer, uint64_t *value)
     return buffer;
 }
 
-void init_test_file(const char *file, const char *function)
-{
-    printf("========== TEST in %s -> %s()\n", file, function);
-}
-
-void init_test_function(const char *function)
-{
-    printf("|=> %s()\n", function);
-}
-
-int test(char *file, int line, void *result, void *expected, Comparator *compare, Formatter *format)
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
 {
+    __indentation_level++;
     static char buffer_result[1000];
     static char buffer_expected[1000];
     int is_equal = compare(result, expected);
-    char c_result = is_equal ? 'V' : 'X';
-    printf("[%c]    | %s:%d: ", c_result, file, line);
 
+    char *fmt_result = format(buffer_result, expected);
+    char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        printf("failed, expected %s, got %s\n",
-               format(buffer_result, expected),
-               format(buffer_expected, result)
-              );
-    } else {
-        printf("passed\n");
+        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line, char *result, char *expected)
+int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
 {
     Comparator *compare = (Comparator *) string_compare;
     Formatter *format = (Formatter *) string_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_boolean(char *file, int line, bool *result, bool *expected)
+int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
 {
     Comparator *compare = (Comparator *) boolean_compare;
     Formatter *format = (Formatter *) boolean_format;
 
-    return test(file, line, (int *) result, (void *) expected, compare, format);
+    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
 }
 
-int test_ptr(char *file, int line, void *result, void *expected)
+int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) ptr_compare;
     Formatter *format = (Formatter *) ptr_format;
 
-    return test(file, line, result, expected, compare, format);
+    return test(file, line, __indentation_level, result, expected, compare, format);
 }
 
-int test_uint64_t(char *file, int line, void *result, void *expected)
+int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
 {
     Comparator *compare = (Comparator *) uint64_t_compare;
     Formatter *format = (Formatter *) uint64_t_format;
 
-    return test(file, line, (uint64_t *)result, (uint64_t *)expected, compare, format);
+    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
 }
 #endif
 
-- 
GitLab


From 49943ea17c5bdcb96cd808454e3044c15d984b55 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sat, 4 Feb 2023 15:18:26 +0000
Subject: [PATCH 119/229] format

---
 src/amd_rapl.c | 136 +++++++++++++++++++++++++------------------------
 1 file changed, 69 insertions(+), 67 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0d2ed29..2f20ea2 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,8 +25,6 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
-#include <assert.h>
-#include <math.h>
 
 #include "info_reader.h"
 #include "util.h"
@@ -38,59 +36,66 @@ static const uint64_t amd_energy_mask = 0xFFFFFFFF;
 static const uint64_t amd_energy_unit_mask = 0x01F00;
 static const uint64_t msr_rapl_power_unit = 0xC0010299;
 static const uint64_t energy_core_msr = 0xC001029A;
-static const uint64_t energy_pkg_msr = 0xC001029B;
 
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
 
 struct cpu_sensor_t {
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
+    unsigned int cpu_id;
+    unsigned int package_id;
+    unsigned int core_id;
 
+    char *name;
     int fd;
+
     unsigned int energy_units;
     uint64_t core_energy;
-    uint64_t pkg_energy;
 };
 typedef struct cpu_sensor_t cpu_sensor_t;
 
 struct _amd_rapl_t {
     cpu_sensor_t *sensors;
-    unsigned int nb;
+    unsigned int sensor_count;
 };
 typedef struct _amd_rapl_t _amd_rapl_t;
 
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-
 #warning "Must be modified before release"
 #define MAX_CPUS 64
-#define NB_KEYS 2
+#define NB_KEYS 3
 
 static const char *cpuinfo = "/proc/cpuinfo";
-static GenericPointer _size_t_allocator(char *s)
+
+static GenericPointer uint_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
 static void _set_cpu_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->cpu_id = (size_t) data;
+    cpu->cpu_id = (unsigned int) data;
 }
 
 static void _set_package_id(GenericPointer storage, GenericPointer data)
 {
     cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
-    cpu->package_id = (size_t) data;
+    cpu->package_id = (unsigned int) data;
+}
+
+static void _set_core_id(GenericPointer storage, GenericPointer data)
+{
+    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    cpu->core_id = (unsigned int) data;
 }
 
 static KeyFinder keys[NB_KEYS] = {
-    {"processor", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_cpu_id},
-    {"physical id", ": ", (CopyAllocator *) _size_t_allocator, (Setter *) _set_package_id}
+    {"processor", ": ", uint_allocator, _set_cpu_id},
+    {"physical id", ": ", uint_allocator, _set_package_id},
+    {"core id", ": ", uint_allocator, _set_core_id}
 };
 #endif
 
@@ -119,13 +124,20 @@ uint64_t read_raw_core_energy(int fd)
     return energy & amd_energy_mask;
 }
 
+// -------------------------READ_PKG_ENERGY
+
+#ifdef __READ_PKG_ENERGY__
+// TODO: Verify if these functions are still useful (the package energy can be calculed)
+
+static const uint64_t energy_pkg_msr = 0xC001029B;
 uint64_t read_raw_pkg_energy(int fd)
 {
     uint64_t energy = read_msr(fd, energy_pkg_msr);
     return energy & amd_energy_mask;
 }
+#endif
 
-// ---------------------------------ENERGY
+// ----------------------------------ENERGY
 
 uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
 {
@@ -147,20 +159,19 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %ld, package_id : %ld, name : %s, fd: %d,  energy_units : %d, core_energy: %ld, pkg_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
            sensor->core_energy,
-           sensor->pkg_energy
           );
 }
 
 void debug_print_amd_rapl(_amd_rapl_t *rapl)
 {
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         debug_print_sensor(&rapl->sensors[i]);
     }
 }
@@ -186,57 +197,46 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-char *get_name(size_t cpu_id)
+char *get_name(unsigned int cpu_id)
 {
-    static const char *base_name = "core%ld";
+    static const char *base_name = "core%d";
     static const size_t max_lenght = 20;
     char *name = (char *)calloc(max_lenght, sizeof(char));
     snprintf(name, max_lenght, base_name, cpu_id);
     return name;
 }
 
-void init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id)
+void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
 {
+    sensor->energy_units = read_unit(sensor->fd);
+    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
+    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
+
+    *energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
+    sensor->core_energy = core_energy;
+}
+
+unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
+{
+    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
+        return 0;
+    }
+    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+
     static char filename[BUFFER_SIZE];
     sprintf(filename, base_str, cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, "open(");
         fprintf(stderr, base_str, cpu_id);
-        perror(")");
+        perror(":open()");
         exit(127);
     }
 
-    uint64_t raw_core_energy = read_raw_core_energy(fd);
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(fd);
-
     sensor->cpu_id = cpu_id;
     sensor->name = get_name(cpu_id);
     sensor->fd = fd;
-    sensor->energy_units = read_unit(fd);
-    sensor->core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-    sensor->pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-}
-
-uint64_t get_core_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
-    uint64_t core_energy = raw_to_microjoule(raw_core_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(core_energy, sensor->core_energy);
-    sensor->core_energy = core_energy;
-    return energy_consumed;
-}
-
-uint64_t get_pkg_energy(cpu_sensor_t *sensor)
-{
-    uint64_t raw_pkg_energy = read_raw_pkg_energy(sensor->fd);
-    uint64_t pkg_energy = raw_to_microjoule(raw_pkg_energy, sensor->energy_units);
-
-    uint64_t energy_consumed = modulo_substraction(pkg_energy, sensor->pkg_energy);
-    sensor->pkg_energy = pkg_energy;
-    return energy_consumed;
+    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -258,41 +258,42 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     UNUSED(none);
     _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
-    unsigned int nb_cpu = get_nb_cpu();
-    if (nb_cpu == 0) {
-        fprintf(stderr, "open(");
-        fprintf(stderr, base_str,0);
-        perror(")");
+    unsigned int max_cpus = get_nb_cpu();
+    if (max_cpus == 0) {
+        fprintf(stderr, base_str, 0);
+        perror(":open()");
         exit(127);
     }
 
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(nb_cpu, sizeof(cpu_sensor_t));
-
-    rapl->nb = nb_cpu;
+    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
+    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
     rapl->sensors = cpus;
 
-    for (unsigned int i = 0; i < nb_cpu; i++) {
-        init_cpu_sensor(&rapl->sensors[i], i);
+    unsigned int nb_cpu = 0;
+    for (unsigned int i = 0; i < max_cpus; i++) {
+        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
     }
+    rapl->sensor_count = nb_cpu;
 
     *ptr = (void *) rapl;
-    return rapl->nb;
+    free(cpus_map);
+    return rapl->sensor_count;
 }
 
 
 unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
-        results[i] = get_core_energy(&rapl->sensors[i]);
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
+        update_cpu_sensor(&rapl->sensors[i], &results[i]);
     }
-    return rapl->nb;
+    return rapl->sensor_count;
 }
 
 void label_amd_rapl(char **labels, void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
-    for (unsigned int i = 0; i < rapl->nb; i++) {
+    for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         labels[i] = rapl->sensors[i].name;
     }
 }
@@ -301,9 +302,10 @@ void clean_amd_rapl(void *ptr)
 {
     _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         clean_cpu_sensor(&rapl->sensors[i]);
     }
     free(rapl->sensors);
     free(rapl);
 }
+
-- 
GitLab


From 6e2d8275d7863201bee91ee188adaadb6c2ad276 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:32 +0000
Subject: [PATCH 120/229] format

---
 tests/info_reader.c | 157 ++++++++++++++++++++++++++++++--------------
 1 file changed, 106 insertions(+), 51 deletions(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 9504631..32734c9 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,54 +1,117 @@
 #include "small_test.h"
 
 TFUNCTION(test_replace_first, {
-    char test1[] = "This is my string";
-    replace_first(test1, 'i', 'I');
-    TEST_STR(test1, "ThIs is my string");
+    // useful variables :
+    char result[100];
+    char expected[100];
 
-    char test2[] = "This is my string";
-    replace_first(test2, 'x', 'X');
-    TEST_STR(test2, "This is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "ThIs is my string");
+    // -- Run
+    replace_first(result, 'i', 'I');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'x', 'X');
+    // -- Verification
+    TEST_STR(result, expected);
+
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This_is my string");
+    // -- Run
+    replace_first(result, ' ', '_');
+    // -- Verification
+    TEST_STR(result, expected);
 
-    char test3[] = "This is my string";
-    replace_first(test3, ' ', '_');
-    TEST_STR(test3, "This_is my string");
+    // -- Setup
+    strcpy(result, "This is my string");
+    strcpy(expected, "This is my string");
+    // -- Run
+    replace_first(result, 'T', 'T');
+    // -- Verification
+    TEST_STR(result, expected);
 })
 
 TFUNCTION(test_split_on_delimiter, {
-    char test4[] = "key:value";
-    char *key;
-    char *value;
-
-    split_on_delimiter(test4, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test5[] = "key: value";
-    split_on_delimiter(test5, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value");
-
-    char test6[] = "key:value";
-    replace_first(test6, ':', ' ');
-    split_on_delimiter(test6, " ", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value");
-
-    char test7[] = "";
-    split_on_delimiter(test7, ":", &key, &value);
-    TEST_STR(key, NULL);
-    TEST_STR(value, NULL);
-
-    char test9[] = "key:value:extra";
-    split_on_delimiter(test9, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, "value:extra");
-
-    char test10[] = "key: value :extra";
-    split_on_delimiter(test10, ":", &key, &value);
-    TEST_STR(key, "key");
-    TEST_STR(value, " value :extra");
+    // Useful variables
+    char string[100];
+    char *result_key;
+    char *result_value;
+    char expected_key[100];
+    char expected_value[100];
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key:value");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value");
+    replace_first(string, ':', ' ');
+    // Run
+    split_on_delimiter(string, " ", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, NULL);
+    TEST_STR(result_value, NULL);
+
+    // Setup
+    strcpy(string, "key:value:extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, "value:extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
+
+    // Setup
+    strcpy(string, "key: value :extra");
+    strcpy(expected_key, "key");
+    strcpy(expected_value, " value :extra");
+    // Run
+    split_on_delimiter(string, ":", &result_key, &result_value);
+    // Verification
+    TEST_STR(result_key, expected_key);
+    TEST_STR(result_value, expected_value);
 })
 
 TFUNCTION(test_start_with, {
@@ -110,7 +173,7 @@ TFUNCTION(test_start_with, {
 
 
 TFUNCTION(test_match, {
-    // usefull variable :
+    // useful variables :
     bool _true = true;
     bool _false = false;
     KeyFinder keys[10];
@@ -198,11 +261,3 @@ TFILE_ENTRY_POINT(test_info_reader, {
     CALL_TFUNCTION(test_match);
 })
 
-#ifdef __TESTING_INFO_READER__
-int main()
-{
-    test_info_reader();
-    return 0;
-}
-#endif
-
-- 
GitLab


From be9a5e0585953b8b3ce75adf0a273a9e32babb19 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:28:47 +0000
Subject: [PATCH 121/229] print format

---
 tests/small_test.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 357479a..d1aae8a 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -285,7 +285,7 @@ int test(char *file, int line, unsigned int __indentation_level, void *result, v
     char *fmt_result = format(buffer_result, expected);
     char *fmt_expected = format(buffer_expected, result);
     if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected %s, got %s\n", file, line, fmt_expected, fmt_result);
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
-- 
GitLab


From 221ec2635483b360fdd9d2198eba678609c6993c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:35:26 +0000
Subject: [PATCH 122/229] remove the gcc dependence

---
 tests/small_test.h | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index d1aae8a..9ac572c 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -7,10 +7,9 @@
 #include <stdint.h>
 #include <stdio.h>
 
-// ---------------------------API_INTERFACE
-
-
+#include "../src/util.h"
 
+// ---------------------------API_INTERFACE
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -236,9 +235,10 @@ int string_compare(char *string1, char *string2)
     }
 }
 
-char *string_format(__attribute__((unused)) char *buffer, char *string)
+char *string_format(char *buffer, char *string)
 {
-    return FMT_NULL(string);
+  UNUSED(buffer); 
+  return FMT_NULL(string);
 }
 
 
@@ -247,8 +247,9 @@ int boolean_compare(bool *boolean1, bool *boolean2)
     return *boolean1 == *boolean2;
 }
 
-char *boolean_format(__attribute__((unused)) char *buffer, bool *boolean)
+char *boolean_format(char *buffer, bool *boolean)
 {
+    UNUSED(buffer);
     return *boolean ? "True" : "False";
 }
 
-- 
GitLab


From 26c34e9e53e0c139f7cecf578b9bcf41e16f670b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:10 +0000
Subject: [PATCH 123/229] example of how to use src/nfo_reader.c

---
 .../info_reader_ex.c                          | 43 ++++++-------------
 1 file changed, 12 insertions(+), 31 deletions(-)
 rename tests/example_info_reader.c => doc/info_reader_ex.c (76%)

diff --git a/tests/example_info_reader.c b/doc/info_reader_ex.c
similarity index 76%
rename from tests/example_info_reader.c
rename to doc/info_reader_ex.c
index 1dd6464..38d948a 100644
--- a/tests/example_info_reader.c
+++ b/doc/info_reader_ex.c
@@ -1,23 +1,20 @@
 #include "info_reader.h"
 #include <stdint.h>
 
-#ifdef DEBUG
-#warning "PTR_TO_TPTR hide a cast warning"
-#endif
-
 #define MAX_PROCS 2
+#define NB_KEYS 6
 typedef struct {
-    size_t processor;
+    unsigned int processor;
     char *vendor_id;
-    size_t family;
-    size_t core_id;
-    size_t physical_id;
+    unsigned int family;
+    unsigned int core_id;
+    unsigned int physical_id;
     char *model_name;
 } Cpu;
 
 GenericPointer int_allocator(char *s)
 {
-    size_t value = atoi(s);
+    unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
@@ -59,19 +56,6 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-struct cpu_sensor_t {
-    //TODO: check the reset of the msr registers
-#warning "Check the reset of the msr registers"
-    size_t cpu_id;
-    size_t package_id;
-    char *name;
-
-    int *fd;
-    uint64_t energy_units;
-    uint64_t core_energy;
-    uint64_t pkg_energy;
-};
-
 int main(int argc, char const *argv[])
 {
     Cpu cpus[MAX_PROCS];
@@ -91,7 +75,7 @@ int main(int argc, char const *argv[])
                      .capacity = MAX_PROCS,
                      .storage_struct_size = sizeof(Cpu),
                      .keys = keys,
-                     .nb_keys = 6,
+                     .nb_keys = NB_KEYS,
                      .file = fopen("/proc/cpuinfo", "r")
                     };
 
@@ -99,19 +83,16 @@ int main(int argc, char const *argv[])
 
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
-        printf("Processor: %ld\n", cpus[i].processor);
+        printf("Processor: %u\n", cpus[i].processor);
         printf("Vendor ID: %s\n", cpus[i].vendor_id);
-        printf("Family: %ld\n", cpus[i].family);
-        printf("Core ID: %ld\n", cpus[i].core_id);
-        printf("Physical ID: %ld\n", cpus[i].physical_id);
+        printf("Family: %u\n", cpus[i].family);
+        printf("Core ID: %u\n", cpus[i].core_id);
+        printf("Physical ID: %u\n", cpus[i].physical_id);
         printf("Model Name: %s\n", cpus[i].model_name);
-        printf("==============================\n");
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-
-    printf("size = %ld\n", sizeof (struct cpu_sensor_t));
-
+        printf("==============================\n");
     return 0;
 }
 
-- 
GitLab


From d1d5853bdd89bf2dac4b707d163958542aa5ac76 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 08:39:44 +0000
Subject: [PATCH 124/229] format

---
 doc/info_reader_ex.c | 2 +-
 tests/small_test.h   | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 38d948a..6b284a5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -92,7 +92,7 @@ int main(int argc, char const *argv[])
         free(cpus[i].vendor_id);
         free(cpus[i].model_name);
     }
-        printf("==============================\n");
+    printf("==============================\n");
     return 0;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index 9ac572c..33c34c6 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -237,8 +237,8 @@ int string_compare(char *string1, char *string2)
 
 char *string_format(char *buffer, char *string)
 {
-  UNUSED(buffer); 
-  return FMT_NULL(string);
+    UNUSED(buffer);
+    return FMT_NULL(string);
 }
 
 
-- 
GitLab


From d8d7594057326d29a07d48057cfba3574df122e8 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 09:00:30 +0000
Subject: [PATCH 125/229] cleanup

---
 doc/info_reader_ex.c | 28 +++++++++++++++++++++++++---
 1 file changed, 25 insertions(+), 3 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 6b284a5..23ee7d5 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -1,8 +1,30 @@
-#include "info_reader.h"
-#include <stdint.h>
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+
+// ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
+#include "./../src/info_reader.h"
 
 #define MAX_PROCS 2
 #define NB_KEYS 6
+
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -56,7 +78,7 @@ void set_model_name(GenericPointer storage, GenericPointer data)
     cpu->model_name = (char *) data;
 }
 
-int main(int argc, char const *argv[])
+int main()
 {
     Cpu cpus[MAX_PROCS];
     KeyFinder keys[] = {
-- 
GitLab


From 730f969f8cd60054edf8cc995650fdee0f9d2d44 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:21 +0000
Subject: [PATCH 126/229] add test example

---
 doc/test_file_ex.c | 112 +++++++++++++++++++++++++++++++++++++++++++++
 doc/test_main_ex   | Bin 0 -> 17416 bytes
 doc/test_main_ex.c |  35 ++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 doc/test_file_ex.c
 create mode 100755 doc/test_main_ex
 create mode 100644 doc/test_main_ex.c

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
new file mode 100644
index 0000000..44ebc2c
--- /dev/null
+++ b/doc/test_file_ex.c
@@ -0,0 +1,112 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+// Include of the test library
+#include "./../tests/small_test.h"
+
+// -- A simple function that should pass
+TFUNCTION(test_should_pass, {
+    char *result = "It's going to pass";
+    char *expected = "It's going to pass";
+    TEST_STR(result, expected);
+})
+
+// -- A simple function that should fail
+TFUNCTION(test_should_fail, {
+    char *result = "a fail";
+    char *expected = "a nice fail";
+    TEST_STR(result, expected);
+})
+
+// -- Add a new type in the test framework
+
+typedef struct {
+    int simple_int;
+    char simple_str[20];
+} UserType;
+
+
+// -- Implemet the interface
+int usertype_compare(void *ptr1, void *ptr2)
+{
+    return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
+}
+
+char *usertype_format(char buffer[1000], void *ptr)
+{
+    UserType *x = (UserType *) ptr;
+    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    return buffer;
+}
+
+// Create a variable which contains the functions
+static const TestInterface usertype_interface = {
+    .compare = usertype_compare,
+    .format = usertype_format
+};
+
+// -- Create the test macro to call
+#define TEST_USER_TYPE(__result, __expected) \
+    TEST_INTERFACE(__result, __expected, &usertype_interface);
+
+// -- Create a macro setter
+#define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
+    do {                                                    \
+      __user = (UserType) {                                 \
+          .simple_int = __simple_int,                       \
+          .simple_str = __simple_str                        \
+    };                                                      \
+} while (0);
+
+// -- Compare two usertype
+TFUNCTION(test_user_type, {
+    UserType x1;
+    UserType x2;
+
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    TEST_USER_TYPE(&x1, &x2);
+})
+
+
+// -- Compare an array of usetype
+TFUNCTION(test_array_user_type, {
+    UserType *results[1];
+    UserType *expecteds[1];
+
+    UserType x1;
+    UserType x2;
+    DUMMY_USER_TYPE(x1, 1, "John Doe");
+    DUMMY_USER_TYPE(x2, 1, "John Doe");
+
+    results[0] = &x1;
+    expecteds[0] = &x2;
+
+    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+})
+
+// Define the entry point of a test file
+TFILE_ENTRY_POINT(test_file_ex, {
+    CALL_TFUNCTION(test_should_pass);
+    CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_user_type);
+    CALL_TFUNCTION(test_array_user_type);
+})
diff --git a/doc/test_main_ex b/doc/test_main_ex
new file mode 100755
index 0000000000000000000000000000000000000000..0ab7870283c6ba20a50b3761a1c009eb89f3ac20
GIT binary patch
literal 17416
zcmb<-^>JfjWMqH=W(GS35buEiM8p9?F>u&G84L^z4h$9yybKNu3JmfLYzzzxEMPH+
zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`%Rtq^XpoygLLeGsABc?&8$d09(F{<3fb_9~
zG(h<<aTx8&4U%MFfYC5<kUp?|3J`e)G+G2~C<6nGM%D)k8wXv8J_lP=8WtWexFF&%
zeW2h1>01ERw*aaSMt=Y~h=G9tMnk;|jsuW8Eui6vP8&e2fzjytGNAg<X&0zI7!9%m
zBozF#Bn8Aqw+F_D*#o0t_60!o^(cZ&VPHU~_dtXhU^K`MkWk>$k`z$5fY`)fSTqMg
z?ZXuh2S5SNz`y{bp~1_bpOcwnW}=^yqMMVMS6ZQ4VPU3gW};V|uV)0d9^@`iQUFE2
zyI&{+69dBmkQg)=8JHR%e3*G4IS~d1aJmPnpJ)5Nb?@T%=MPt`vFmpAvMSud+Xhkt
zayLj1NDas$ka<uig18`i7(ht|qy`cmjbL$*7>IE(^;|B9#)U!V3t^EgVPJqKZDeT+
z1_lOf>J4#-YvK@B!XZ8ZhrOV5gU#OgIMjo}17ruX+rjMk_~eSj__WNt#GK5kREGHY
zoXn);_~MepqLTRB#LPT~;*z4|+yaK&)Lal%Tu_vmSCYmM4^onx9iN<$9iNt%nZp3m
z28w<&26rD%C+B!0JtI9+INJoyGB#m|_YCokPf0CGP0uVYNi7QTb<WApOASd($^qG*
zo|~TsGQ6lHJ|3bJt3n0_1||kZ24)5pFl1z4VSr#}22TbCSaHEnDwW9zDuIKcVj`KD
zyr5JT59M!}IE@WtQYJVs7#LvX5G+3)5QIp0K+74Jcmq^C08RWPR6GJr+yoj~325R;
zQ1J{j@mWyu0yOdSQ1J>h@%K>i1~hREVTk)X(8Lp=;uFxsW5poqXP}8shKh4QD=t_#
z!1w}a;{QRJpMinlf<44MP+kP3K?sk5;Rcd8a{hgQB+d>~%)r3#0!f?`N&EwnI4qBY
zq*p-2L1uu;2#^>EZ$J_Ul_wxE5Z-|#4l1)iVjz3~NgU({kQfM`KoW<A1xS1pkA}c#
z2#kinXb6mkz-R~z{Sf%fFZau%`3;9hH|s@x1_qDT10_uVFL*Q`;W!NT+<(&|eFlb4
z|5c0i85sEG89?eYKr)|RKK%dx{{%1})bRQA@*<oMYVdq|c@WMAHBdgi+z97`8YZ7!
zE`;$v{Z~x|o9@B@HviLqRbDhcD;oc=9>_Ha^<UBWZ;|<iZ#_FN#(8u;@@RhYAt1!n
z@POe-k6znoP6memqNnv37`~+G@yoY>e8u3=Ys&}<hhElSdJGI6mOn~FJ-S)ff!M7F
zN;v;N;FoUzDLf3NJ$h{~f+TxQPk|`Se;%D5JPy9I_c-{2*@N+z$HjjoA|BnWwIIpX
z10@{)AEfciyD%`o^n=2$!FH-10|P^;cBn_QZ4`*<(fPE5$D`XeO^<=$#m#^J|G!B2
z|Ns9n)?7UX2FBRK{PHOJUzY#>{~u&fs7L2hkLEWD9-Xx>JUUAscyznI@aS~?;L+{+
zz@yXkhevbm2ZmBUkLKDR45jQlK+*Qv04!L-4if}<?zOZ>cjym~Zr2YUo!2}%kH47q
z@BjbS1N>7C@NYYC@-W;ggf%eZe=wA=d33w}c+Kw7&ALICfgu)~YE(ycyMEx`CIHgK
zzm37-5X2U&`XIJ+yZ+$c#?W%0gwvy!)rXgX;WfKQFRKSHnq@ycI!i%5|KVZn`T@hx
z<~IT!owZOkp%8VwyqvrY3?7~5JUWl>0ENSgb$|c=2RRI@pD}#l(GB*6M>m6qC8jq}
z;|1;&h^7}Fy}bQAsFoW-EPsJydGnh9kIvc~ouyYgLoaxA`kwIVbUonH>AR!Z^#Y?u
zx9bj%ZVr#`&;uUbt|uT-_y1z2>l=tn0Eb7n>j96>V;;S%t~wyQj{m;|O&&Wuy1~*X
zAku0E2<acqwQm?ogO0nt00qfw36EaZm)u}!NEk)^`TxJ!^#x<M>kDhw3q=n+x<SG2
z`=dMbibuEW4bRRG5HoinYf=Sis(r%%i5C<f8g$m)Iqv!dZdnbozPG<YmOWwYc70;)
zdZ*}tM=z@vIM_g*YCu+b`1k++$6eomjPdAY%?3-ke(>mJO@J_ecy#;z@aPWx(CvE1
zr<d17gMq=b^Mps|#m+<fKph^BURF=A%HuC;|NZ~Z==ugZ1fFvtg+K(@QP2>$Q}m$Q
z^$j?Xr6Bqt!DRgV|Nm~+H+a1|5!qBGu&F3stp^(j^6FG%l{bDNdv!Nh3hdSG5GI;e
zBh`_-%Fn>S;L*z(2UdCf#iYL&Uj4&~<kj3?pzz1^sy;+N#H${^FujVD+kC;fZI=Yd
zW^i76q5cbN@q#PI^m?#>G9@^-z3}KYeSqx3-#@`w7B$x-bk?p(@#tnz)c{-S`or+R
zan~)Nv;j`flE?;h{RDY&3uCwI7Hiiv;3Osw_8lnPWsy}T`~-zNc%<^U>j6+{>aoKs
zKO;}UB|mi+$Z(HN*CQUCp=XY}UIB5ByFLIb>U4eL(HZ*Yxa${?s7J5w1CQR&1KqA`
ze0q8Rs3JuUXpF+6m-QeAI0jyP{SAtoJ;z<a!3=hJJVXjC@Z!P`kjr;4cDwEXyS&?V
z4>%o8LRPf;2Pks(fC~5&4{Z@}h?KCtX!-H~KXTeU($HDkgArsiKn@05{EQv!CWyu1
zV2fukcDv57cI^QN84Ea|Ktc8jS*7j|P>{_58ADN!fyy!06&}6ddTqmT*99OGU)y%O
zF7W8~Il2K%ha6qe?b_qh%ez7aDNKDqDWI1%7vicH3x9#abWXGD0><Xr1q>y7kGn1b
zn*}Q87$J%vo-Fzf3f(1)-L6Z(p6qs=0}fpiWJSK;L7_VbJ#^K+qlWGqh0a=7{DXsY
zIvY}Oa)536!r1Nl#oF}^I5^LOEji@T%en=u5)`n)U@>S-b>$l<VE=%e-tGFP`2b_*
z@fXX%e)|LGH-Xa+f`9uD$nOaLKXB&%bKLa@$QZD@{<9*vtKb_b1b#4fyZ!*XtK0Pt
zI0Pnwodk7=_cu@o{6S7jZv>!59(Vl!H+d<t$zouWKQMN?ez11^0rv3=u%RFydxBXY
zA1i`cP>UXYMe^|vh>vH1OX@$+oCWrQEwVl9zJh!J4cQ-{k{aTJ^T>)izoPp9-cWG;
z;i2vNA@(q&oeFL@!&}NApN-<t5Eu=C(GVCqA;1WpQAD^mq^LBN!7VYTIF&)QfI&5<
zl%YmJK|z5*wb)8E#YzD*6_%Q!qmWurkeXbQnxbH%T5PAIke*)xW^pm77Hep7F?g1!
z7b~RaXXd3Vl;kTEBo-Gl=;@cF7MH}QW#**Dr&j1CGt|Vpq^6}76{V&qxE2-V7b#dN
zsHSi+B!cZ=NL0wnOiqQcL9PoePAv+lEJ#(TF3!v?$VrXQ%qszD&{2T$i%W{E6jY0A
z!7eT4!fJde7X#Q4pm{%tBm6>rd_cy-F<8DhBfm5!B_8Z<xD14WEDs6{h$sWZ+|uII
zqWF@^f>f9&R6Mb$D6ujgMHXxhG%y%I?qOhHV3cOI2DLRnQ&Cgi{r?Z@ynK20|Gx+$
z0|U$Z|NnIu85ly||NjqaOxk|<|KEj?fnmjm|Nm1M85pj8`2W9!k%58l<NyCl7#SFx
zKmPxJgpq+E`Q!ipPZ${(=6wABpM{Bm;p)f#|5cb67$iUa|L?-Y!0`Li|NkjW3=Gdc
z|Nq~@#K3Uz%m4pNm>3w?zyAM!go%N{|Lgz%PnZ}On!f%2&%(^W@ZkIZ|0>K34Cj9Q
z|L?-gz%b$G|Nkk>3=E*TZIG`StAZF9D+Cy&dDuB7FhayZYd9+2{r|59QsBZ4nu2Cf
zVPIe|VPIfb@b>@z1duqNfE%BL7e9A7M+1Ysl$DmT3V1pfWNr)t1H+BC|NnzEg48lV
z%mvL^UwHffe*jbrM1kz;VPIhR`0oGzY><E}pFkUvGcOxc5)V5E0|Q8Y4Fdy%&HMlV
zK_e{;F!@xlG+6!&0|SHC`~UwzbKh|Je1tqGUXtGb|8I(HehxyOhmnDy{QZB(6d}y~
zaD+T49zpV!$odNq@;;0V3=`h}|Bp*PhmnC{<@^8t!D}*L=2s*1_b@UroPGcQ|087c
znQnp=fc?+Nz|jBU|Nqx0@{i#1XBZh6qCVo5f5XVYp!(_me=}tLxnS+!@Z(`(V6gu5
z|Gx*ad_6*5hlzn9`P2XZ#-QF1%>B$-j35;t_xUg}FqD1%|33~zJ`^sW!^FU_<;(y7
z?~u)BdJ57Gw!a6IUcdhTe+Wf>CtQ9F69a?FxBvg8kmUox(jbvhJQ@O{Aut*OqaiRF
z0;3@?8UlDj0JeS(wq6dlJ`T1X4z~Ucw%!f4z74jX4Yqy_wq6akJ`J`W4b%hzIRLcg
z4@C2T2oQ!ghIv731_lNTX$V6SLc!PhL4_GWQyL&CaGM7-1PU5kW`MMZLE<p^umAq%
zgZLXjbG8f&46wCg4?uIa3=9mgHDWiQ@~|~&J3*Ql7#N_-s2M<``ye4v5P^iD+88E4
z*O!5&ib2v9AOhO12QfkG+Ca28h+tq~*Z~!QQVbuU4uiS-1T>&vYv*A0%R%+S)cyVs
z@gE}tBuM^2`5U0-{fF|Q#xZ<=@@GNie?s|uP;;qG!Pa@Bn`;1#ZwDwH0HqV4bODq`
z*GDWLw$2gKX<=Y+cXqZ?&<IT`%_}KYFf`ON)-%vGECq87>x_)_3`{hk!uV|fg(C~Y
z$N%W6K=A}x&)Ne`5YXk644`G3*wlmKk%>WoK>)h`6lNYsA4uE*P289PwCYuW0hTXe
z>OuL4kwKb40lJ<O<UWvGD5(F<AjSY&2MZDd;TotpuzU^@1K|#^dQo^j1Brp~a`3(e
zO#f~JtCwOxUq^ZnEH2IfTW1T4#`92d*m_!+_&umNY~3tO9MmUeWDsY7t&fF?{{pL*
zW^jP|_XRY(L48zEI5>bikqitlaT!Ji21W)U1_9{$d|0rmL&Xiy#Ern>;ta5LwlI5L
z!Qw&;9#Hk5c}7t91VF_TpyIIdAsQ-P0TqXpYiUsNR;V~M8!{Av#ze5BD_rTP0&I>5
zgMcc?6{r|ndTRr#mta88kNw~TBMjfS05fS3SiK~?T!V>&7Fh@}2r$6PdvKqgfq~&L
zBWPW{00XStheiX#Ij}fPH-di6h<$y29ur7h3bZK)p_qYzft?9rKCHe0<r9zsVJ6Vp
zaVZ7~XnFvNfv^-vJ(D239s!AgumVUN#6ZJg%pmj81Q{3@tikF97;>N$5x9>Is&Am;
zMbHQbk3BFjFhqjIG0g$>@dX$#{Z)xWJ*dwQ^CPlpvzZte1ev55VC5T3ZUsmjw6g)K
z30l1|YzLb!zyPbi!DB=W3=D^$;;{N1JhsHZz;F&6p3)2&;K2@<=?n~)q3Umg2J;vg
z7{Fs43=9lKP;uD)D)5*X0|Ub&s5q?NhZ*+?Dh_KWz|zk@sJ-a%$OVoU0fs1OMGqbW
zVPIh3hl<16A>gqq1_lOcs5q?M0Upy~U|`UJit|A$Qt(&|0|SF2R9ptyuz*^_5DFGY
z_#ei~WQK%4x;sn3>IE2J?IZA58v_GF6Ei41!*nC)IZ*ZOpaDS!1_oIAS<B4803Ikr
zC<U`lfYdYbfD${H4<pWj#2Ew_mVycjP`JY+f|H9%4E6FE;^PyOGUH1U(;1SBN{UNL
z)6(>k84#N};!ASllR?`#iW%bLQ}W}}bMliCbK+A<@{5Y&6H6-?lJh~s(<P}XdIs24
zfcBzf#zTgLQ}arSDjCv>5_41IQ%ZAlD;eVBk$CZ$d6^|BO2Na%py6W3@O5!XQG8x$
zPL7@hXd4S?OgyzHEipNjAt^sU2Z>uyQiQ}SH8VltC6%V7r544*M)dW}8K5FXsl}x^
zC3<EcH<jik$H(iLBA6x&py6!LST~YU@$qR8g~kYlMhK=Mf@#1|T9TQgm&_0!?-u0f
z>l*Ls=Mo>!5bqM{=jiL{%n%>%?iU*G>H(GYa0z0FclYska`cJ!cXJDN4T%qNbn<bH
zX8`#uEx#x?v4jESEhrOXmyZK%(++{{IUwUeF_>7C$`GHLl30?+0FEz={XlR7O&~-6
zu%Uc#1VQHy!1Du;eMNBPpiM*Z@gRdCdw@XkmYiFFCXc#DC_be)KRzQdF9o!J$kRW*
zxFjVr4>X;S0@581^)o0fAe^3;0&y28mLO9SAQm{jpz1-v1y>)RR9p;o5GZv)(hp2w
zacU7*BTO~ekB|fmG8AHbZhlH>PJVoGX;N`XQDSmQW_}(6bTbv2=R$m)q0tRar7%;$
zyQZ*ig#z0L4O8%(4C<aPRO3Ne2JCeP2EF3S+>*p32EF2vA_$!UV`b)*q!tx0=;h^?
zr0S*TmFg7~<rjdwi6oR%nwgWLo0$R?a&+?41r-Zm<r#^^84P+Um3hULxe&Ufhyg59
zmReK{@;fpozKB7uC^aV$qyfq*$SGma1G`nPAg4qxJ->tj%qUJxX3#51ttes8OUum5
zWY8<h2PGB;z0?e7$&is!gy2EUhzCaoL<fuw(gm_quP7hvz{K3lWClHuD1%-SXg)4E
zKQ}iu4>X4YD*`E@LDd1MX$0%f;o8p&vje0S#s<;Kpf(G*tqtNaFu?Ya!e|4CFr0+-
z=U@V$dJEJygxQb2j}<iE1XBy5Vf8(T4Z@&)0kVErzXV1@n+YJLV2rLmoPmMi+yDRh
zF#BQsXBZ8$AJ%_HcYh+Z?+nuq>tDlY4rqXZ+z4XA^h2v>2GIUKP}3f!AJ$)o(XjqG
z*zw>#0gMHq3mF&~Kz(1Bepr7OMnju1@cutc9gMDHU|<0CrD1$ne;P)^nw#kEhuF@*
z&<pN2f%<F^5m^5oM#K8|=-~(R|8%H+Cx~|VcmZtOpaLom(hq8yqKDr?XqbTH!AfBr
z87K`(-(Yblfgb;$C2gR1f$3L(>VwhXIZmiv5CxTn@8bmZ8<F)lKo!7fC>Nv^jA48j
zy#dYr6QB|>8hMTsWB^neZa*k}AlnaXpTg)c*gy|RGjwk$lnJKxquCD|kAl&#{v22_
zG_GK55PcM?AC`XLn~|XzuM6ZjkU}VixgW}9IE$tq*S>O?di40aji%oN+NgxlXW$Nl
zm;g&Z5FP`=Qw9bG(3lV?4}!#C`)pzR&e7Gw_%Qk-sErQY9}dzF8;9_Ko&x|=2a*F}
z7#~Leg}NVRKWsc90IDBX{DaH_VJ=3<*d9zjtltYehX8io04V>0)WhtB#lvbe`(fjI
z6ZAo<85qEOMj%Wu3DXawg~9!2(9UJBG@?HXE%;&i94ZSLyn}HV7#Jj>19~v`!^U?c
zp!zvr7D4qulNFT5z#s>;AF3QK4%4p<7lANf$q|`GOCn%}9#8`hKnn)YI2LFq1Lho<
zzc`WN9;^{caF|0Fmth`*aKUGEK$&0)G){x21T22r3QRG8#%~}j2nlmHgvY=D0FOXj
A`~Uy|

literal 0
HcmV?d00001

diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
new file mode 100644
index 0000000..0aa86b9
--- /dev/null
+++ b/doc/test_main_ex.c
@@ -0,0 +1,35 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+// ~/mojitos/doc$ gcc -Wall -Wextra -Wpedantic -o test_main_ex test_main_ex.c ./../src/util.c
+// Include of the test library
+#include "./../tests/small_test.h"
+
+// Include the *.c files that contain the tests
+#include "./test_file_ex.c"
+// #include "./test_another_test_file.c"
+
+// Define the entry point of the programme
+TMAIN({
+    // Must contain the call to the entry point functions of each file
+    // USE CALL_TFUNCTION(my_function) instead of my_function()
+    CALL_TFUNCTION(test_file_ex);
+    // CALL_TFUNCTION(another_file_entry_point_function);
+})
-- 
GitLab


From e16dc9f4d47bc55b5875136ff06629459839ffca Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:14:43 +0000
Subject: [PATCH 127/229] add licence

---
 src/amd_rapl.c      |   2 +-
 src/amd_rapl.h      |   2 +-
 tests/amd_rapl.c    |  20 ++++
 tests/info_reader.c |  40 ++++++--
 tests/main.c        |  20 ++++
 tests/small_test.h  | 216 +++++++++++++++++++++++++-------------------
 tests/util.c        |  20 ++++
 7 files changed, 215 insertions(+), 105 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 2f20ea2..51df298 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 4f375b9..f16ed4f 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 262c1f8..39214fc 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "small_test.h"
 #include "../src/amd_rapl.c"
 
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 32734c9..b2a8c6f 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "small_test.h"
 
 TFUNCTION(test_replace_first, {
@@ -124,27 +144,27 @@ TFUNCTION(test_start_with, {
     prefix = "Hello";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = "Goodbye";
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello World";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 
     prefix = "Hello";
     string = "Hello";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
 
     prefix = NULL;
     string = "Hello World";
     result = start_with(prefix, string);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
 })
 
 #define NONE 0
@@ -193,7 +213,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[0]);
     TEST_STR(raw_value, "value");
 
@@ -207,7 +227,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -221,7 +241,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 
@@ -236,7 +256,7 @@ TFUNCTION(test_match, {
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
     // -- Verification
-    TEST_BOOLEAN(&result, &_true);
+    TEST_BOOL(&result, &_true);
     TEST_PTR(found_key_finder, &keys[1]);
     TEST_STR(raw_value, "value");
 
@@ -249,7 +269,7 @@ TFUNCTION(test_match, {
     raw_value = NULL;
     // -- Run
     result = match(&parser, line, &found_key_finder, &raw_value);
-    TEST_BOOLEAN(&result, &_false);
+    TEST_BOOL(&result, &_false);
     TEST_PTR(found_key_finder, NULL);
     TEST_STR(raw_value, NULL);
 })
diff --git a/tests/main.c b/tests/main.c
index e48b56a..3246f04 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "util.c"
 #include "amd_rapl.c"
 #include "info_reader.c"
diff --git a/tests/small_test.h b/tests/small_test.h
index 33c34c6..9f6a6d9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #ifndef __SMALL_TEST_H
 #define __SMALL_TEST_H
 
@@ -77,49 +97,48 @@
  * @param function_name The name of the test function to be called.
  */
 #define CALL_TFUNCTION(function_name) \
-  __error_counter__ += function_name(__indentation_level + 1)
-
+  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
 
 /**
  * @def TEST_STR(result, expected)
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `result`, which is the string to be tested, and `expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
  * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the string to be tested
- * @param expected the expected value of the string
+ * @param __result the string to be tested
+ * @param __expected the expected value of the string
  *
  * @code
  * TEST_STR("Hello", "Hello");
  * @endcode
  */
-#define TEST_STR(result, expected) \
-    __error_counter__ += test_str(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_STR(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &str_interface);} while(0)
 
 /**
- * @def TEST_BOOLEAN(result, expected)
- * @brief Test booleans
- * This macro is used to test booleans. It takes two arguments: `result`, which is the boolean to be tested, and `expected`, which is the expected value of the boolean.
- * The macro uses the `test_boolean()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
+ * @def TEST_BOOL(__result, __expected)
+ * @brief Test bools
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the boolean to be tested
- * @param expected the expected value of the boolean
+ * @param __result the bool to be tested
+ * @param __expected the expected value of the bool
  *
  * @code
- * TEST_BOOLEAN(1 == 1, true);
+ * TEST_BOOL(1 == 1, true);
  * @endcode
  */
-#define TEST_BOOLEAN(result, expected) \
-	__error_counter__ += test_boolean(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_BOOL(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
 /**
- * @def TEST_PTR(result, expected)
+ * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `result`, which is the pointer to be tested, and `expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
  * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the pointer to be tested
- * @param expected the expected value of the pointer
+ * @param __result the pointer to be tested
+ * @param __expected the expected value of the pointer
  *
  * @code
  * int x = 5;
@@ -127,47 +146,48 @@
  * TEST_PTR(ptr, &x);
  * @endcode
  */
-#define TEST_PTR(result, expected) \
-	__error_counter__ += test_ptr(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_PTR(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &ptr_interface);} while(0)
 
 
 /**
- * @def TEST_UINT64_T(result, expected)
+ * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `result`, which is the integer to be tested, and `expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
  * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param result the integer to be tested
- * @param expected the expected value of the integer
+ * @param __result the integer to be tested
+ * @param __expected the expected value of the integer
  *
  * @code
  * TEST_UINT64_T(5, 5);
  * @endcode
  */
-#define TEST_UINT64_T(result, expected) \
-	__error_counter__ += test_uint64_t(__FILE__, __LINE__, __indentation_level, result, expected)
+#define TEST_UINT64_T(__result, __expected) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+
+#define TEST_INTERFACE(__result, __expected, __interface) \
+	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element,
- * adding any errors to the nb_error variable.
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
- * @param function the test function to be used on each element of the array
- * @param nb_error the number of errors encountered during the test
- * @param size the number of elements in the array
- * @param results the array of elements to be tested
- * @param expecteds the array of expected values
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, errors, 3, results, expecteds);
+ * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(function, size, results, expecteds)	\
-	for (unsigned int i = 0; i < size; i++) {						\
-		function(results[i], expecteds[i]);				\
+#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+	for (unsigned int i = 0; i < __array_size; i++) {                       \
+      __test_macro(__results[i], __expecteds[i]);                         \
 	}
 
 
@@ -213,46 +233,71 @@
 
 #define DEFERRED_FILE_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-//INDENTED_PRINT("Deferred Error in %s: %d\n",__FILE__, nb_error);
 
 #define DEFERRED_FUNCTION_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
-#define FMT_NULL(string) \
-	string = string ? string : "NULL"
-
 typedef int (Comparator) (void *, void *);
 typedef char *(Formatter) (char *, void *);
 
-int string_compare(char *string1, char *string2)
+typedef struct {
+    Comparator *compare;
+    Formatter *format;
+} TestInterface;
+
+//  ---------------------------str_interface
+
+int str_compare(void *ptr1, void *ptr2)
 {
-    if (string1 == NULL && string2 == NULL) {
+    char *str1 = (char *) ptr1;
+    char *str2 = (char *) ptr2;
+
+    if (str1 == NULL && str2 == NULL) {
         return 1;
-    } else if (string1 == NULL || string2 == NULL) {
+    } else if (str1 == NULL || str2 == NULL) {
         return 0;
     } else {
-        return (strcmp(string1, string2) == 0);
+        return (strcmp(str1, str2) == 0);
     }
 }
 
-char *string_format(char *buffer, char *string)
+char *str_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return FMT_NULL(string);
+    static char *str_null = "NULL";
+    char *str = (char *) ptr;
+    return str ? str : str_null;
 }
 
+static const TestInterface str_interface = {
+    .compare = str_compare,
+    .format = str_format
+};
+
+//  --------------------------bool_interface
 
-int boolean_compare(bool *boolean1, bool *boolean2)
+
+int bool_compare(void *ptr1, void *ptr2)
 {
-    return *boolean1 == *boolean2;
+    bool *bool1 = (bool *) ptr1;
+    bool *bool2 = (bool *) ptr2;
+    return *bool1 == *bool2;
 }
 
-char *boolean_format(char *buffer, bool *boolean)
+char *bool_format(char *buffer, void *ptr)
 {
     UNUSED(buffer);
-    return *boolean ? "True" : "False";
+    bool *_bool = (bool *) ptr;
+    return *_bool ? "True" : "False";
 }
 
+static const TestInterface bool_interface = {
+    .compare = bool_compare,
+    .format = bool_format
+};
+
+// ---------------------------ptr_interface
+
 int ptr_compare(void *ptr1, void *ptr2)
 {
     return ptr1 == ptr2;
@@ -264,63 +309,48 @@ char *ptr_format(char *buffer, void *ptr)
     return buffer;
 }
 
+static const TestInterface ptr_interface = {
+    .compare = ptr_compare,
+    .format = ptr_format
+};
+
+// ---------------------------u64_interface
 
-int uint64_t_compare(uint64_t *value1, uint64_t *value2)
+int u64_compare(void *ptr1, void *ptr2)
 {
-    return *value1 == *value2;
+    uint64_t *v1 = (uint64_t *) ptr1;
+    uint64_t *v2 = (uint64_t *) ptr2;
+    return *v1 == *v2;
 }
 
-char *uint64_t_format(char *buffer, uint64_t *value)
+char *u64_format(char *buffer, void *ptr)
 {
-    sprintf(buffer, "%"PRIu64"", *value);
+    uint64_t *v = (uint64_t *) ptr;
+    sprintf(buffer, "%"PRIu64"", *v);
     return buffer;
 }
 
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, Comparator *compare, Formatter *format)
+static const TestInterface u64_interface = {
+    .compare = u64_compare,
+    .format = u64_format
+};
+
+// ---------------------------test_function
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
-    __indentation_level++;
+    __indentation_level += 1;
     static char buffer_result[1000];
     static char buffer_expected[1000];
-    int is_equal = compare(result, expected);
+    int is_equal = interface->compare(result, expected);
 
-    char *fmt_result = format(buffer_result, expected);
-    char *fmt_expected = format(buffer_expected, result);
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
     if  (!is_equal) {
         INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
     return !is_equal;
 }
 
-int test_str(char *file, int line,unsigned int __indentation_level, char *result, char *expected)
-{
-    Comparator *compare = (Comparator *) string_compare;
-    Formatter *format = (Formatter *) string_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_boolean(char *file, int line, unsigned int __indentation_level, bool *result, bool *expected)
-{
-    Comparator *compare = (Comparator *) boolean_compare;
-    Formatter *format = (Formatter *) boolean_format;
-
-    return test(file, line, __indentation_level, (int *) result, (void *) expected, compare, format);
-}
-
-int test_ptr(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) ptr_compare;
-    Formatter *format = (Formatter *) ptr_format;
-
-    return test(file, line, __indentation_level, result, expected, compare, format);
-}
-
-int test_uint64_t(char *file, int line, unsigned int __indentation_level, void *result, void *expected)
-{
-    Comparator *compare = (Comparator *) uint64_t_compare;
-    Formatter *format = (Formatter *) uint64_t_format;
-
-    return test(file, line, __indentation_level, (uint64_t *)result, (uint64_t *)expected, compare, format);
-}
 #endif
 
diff --git a/tests/util.c b/tests/util.c
index a91c58f..69941bf 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
 #include "../src/util.h"
 #include "small_test.h"
 
-- 
GitLab


From 22cbdb2ae7804be8f3a03610175c3b4e56c93dc0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:26:23 +0000
Subject: [PATCH 128/229] add informations

---
 tests/small_test.h | 31 ++++++++-----------------------
 1 file changed, 8 insertions(+), 23 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 9f6a6d9..aedc685 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -30,6 +30,11 @@
 #include "../src/util.h"
 
 // ---------------------------API_INTERFACE
+/**
+ * @brief Define the entry point of the tests
+ * It initializes each useful variables.
+ */
+
 #define TMAIN(code)                                              \
   int main()                                                     \
 {                                                                \
@@ -169,6 +174,7 @@
 #define TEST_INTERFACE(__result, __expected, __interface) \
 	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
+
 /**
  * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
  * @brief Test arrays of data
@@ -192,6 +198,7 @@
 
 
 // --------------------------------API_CODE
+// These functions should not be used, only use the previous macros.
 
 
 #define INDENTED_PRINT(__fmt, ...)                          \
@@ -202,32 +209,10 @@
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
-/**
- * @def INIT_TEST_FILE()
- * @brief Initialize the test file
- * This macro is used to initialize the test file. It takes the `__FILE__` and `__func__` preprocessor macros as arguments, which provide the name of the current file and the current function, respectively.
- *
- * @param __FILE__ preprocessor macro that provides the name of the current file
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FILE();
- * @endcode
- */
+
 #define INIT_TEST_FILE()     \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
-/**
- * @def INIT_TEST_FUNCTION()
- * @brief Initialize the test function
- * This macro is used to initialize the test function. It takes the `__func__` preprocessor macro as an argument, which provides the name of the current function.
- *
- * @param __func__ preprocessor macro that provides the name of the current function
- *
- * @code
- * INIT_TEST_FUNCTION();
- * @endcode
- */
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-- 
GitLab


From 95956fd34bad0e160dd15e96f25d006eef8df7a1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:27:51 +0000
Subject: [PATCH 129/229] remove bin

---
 doc/test_main_ex | Bin 17416 -> 0 bytes
 1 file changed, 0 insertions(+), 0 deletions(-)
 delete mode 100755 doc/test_main_ex

diff --git a/doc/test_main_ex b/doc/test_main_ex
deleted file mode 100755
index 0ab7870283c6ba20a50b3761a1c009eb89f3ac20..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 17416
zcmb<-^>JfjWMqH=W(GS35buEiM8p9?F>u&G84L^z4h$9yybKNu3JmfLYzzzxEMPH+
zJWM@|zQF_$htV7mE(0@Ep9F}(z`%e`%Rtq^XpoygLLeGsABc?&8$d09(F{<3fb_9~
zG(h<<aTx8&4U%MFfYC5<kUp?|3J`e)G+G2~C<6nGM%D)k8wXv8J_lP=8WtWexFF&%
zeW2h1>01ERw*aaSMt=Y~h=G9tMnk;|jsuW8Eui6vP8&e2fzjytGNAg<X&0zI7!9%m
zBozF#Bn8Aqw+F_D*#o0t_60!o^(cZ&VPHU~_dtXhU^K`MkWk>$k`z$5fY`)fSTqMg
z?ZXuh2S5SNz`y{bp~1_bpOcwnW}=^yqMMVMS6ZQ4VPU3gW};V|uV)0d9^@`iQUFE2
zyI&{+69dBmkQg)=8JHR%e3*G4IS~d1aJmPnpJ)5Nb?@T%=MPt`vFmpAvMSud+Xhkt
zayLj1NDas$ka<uig18`i7(ht|qy`cmjbL$*7>IE(^;|B9#)U!V3t^EgVPJqKZDeT+
z1_lOf>J4#-YvK@B!XZ8ZhrOV5gU#OgIMjo}17ruX+rjMk_~eSj__WNt#GK5kREGHY
zoXn);_~MepqLTRB#LPT~;*z4|+yaK&)Lal%Tu_vmSCYmM4^onx9iN<$9iNt%nZp3m
z28w<&26rD%C+B!0JtI9+INJoyGB#m|_YCokPf0CGP0uVYNi7QTb<WApOASd($^qG*
zo|~TsGQ6lHJ|3bJt3n0_1||kZ24)5pFl1z4VSr#}22TbCSaHEnDwW9zDuIKcVj`KD
zyr5JT59M!}IE@WtQYJVs7#LvX5G+3)5QIp0K+74Jcmq^C08RWPR6GJr+yoj~325R;
zQ1J{j@mWyu0yOdSQ1J>h@%K>i1~hREVTk)X(8Lp=;uFxsW5poqXP}8shKh4QD=t_#
z!1w}a;{QRJpMinlf<44MP+kP3K?sk5;Rcd8a{hgQB+d>~%)r3#0!f?`N&EwnI4qBY
zq*p-2L1uu;2#^>EZ$J_Ul_wxE5Z-|#4l1)iVjz3~NgU({kQfM`KoW<A1xS1pkA}c#
z2#kinXb6mkz-R~z{Sf%fFZau%`3;9hH|s@x1_qDT10_uVFL*Q`;W!NT+<(&|eFlb4
z|5c0i85sEG89?eYKr)|RKK%dx{{%1})bRQA@*<oMYVdq|c@WMAHBdgi+z97`8YZ7!
zE`;$v{Z~x|o9@B@HviLqRbDhcD;oc=9>_Ha^<UBWZ;|<iZ#_FN#(8u;@@RhYAt1!n
z@POe-k6znoP6memqNnv37`~+G@yoY>e8u3=Ys&}<hhElSdJGI6mOn~FJ-S)ff!M7F
zN;v;N;FoUzDLf3NJ$h{~f+TxQPk|`Se;%D5JPy9I_c-{2*@N+z$HjjoA|BnWwIIpX
z10@{)AEfciyD%`o^n=2$!FH-10|P^;cBn_QZ4`*<(fPE5$D`XeO^<=$#m#^J|G!B2
z|Ns9n)?7UX2FBRK{PHOJUzY#>{~u&fs7L2hkLEWD9-Xx>JUUAscyznI@aS~?;L+{+
zz@yXkhevbm2ZmBUkLKDR45jQlK+*Qv04!L-4if}<?zOZ>cjym~Zr2YUo!2}%kH47q
z@BjbS1N>7C@NYYC@-W;ggf%eZe=wA=d33w}c+Kw7&ALICfgu)~YE(ycyMEx`CIHgK
zzm37-5X2U&`XIJ+yZ+$c#?W%0gwvy!)rXgX;WfKQFRKSHnq@ycI!i%5|KVZn`T@hx
z<~IT!owZOkp%8VwyqvrY3?7~5JUWl>0ENSgb$|c=2RRI@pD}#l(GB*6M>m6qC8jq}
z;|1;&h^7}Fy}bQAsFoW-EPsJydGnh9kIvc~ouyYgLoaxA`kwIVbUonH>AR!Z^#Y?u
zx9bj%ZVr#`&;uUbt|uT-_y1z2>l=tn0Eb7n>j96>V;;S%t~wyQj{m;|O&&Wuy1~*X
zAku0E2<acqwQm?ogO0nt00qfw36EaZm)u}!NEk)^`TxJ!^#x<M>kDhw3q=n+x<SG2
z`=dMbibuEW4bRRG5HoinYf=Sis(r%%i5C<f8g$m)Iqv!dZdnbozPG<YmOWwYc70;)
zdZ*}tM=z@vIM_g*YCu+b`1k++$6eomjPdAY%?3-ke(>mJO@J_ecy#;z@aPWx(CvE1
zr<d17gMq=b^Mps|#m+<fKph^BURF=A%HuC;|NZ~Z==ugZ1fFvtg+K(@QP2>$Q}m$Q
z^$j?Xr6Bqt!DRgV|Nm~+H+a1|5!qBGu&F3stp^(j^6FG%l{bDNdv!Nh3hdSG5GI;e
zBh`_-%Fn>S;L*z(2UdCf#iYL&Uj4&~<kj3?pzz1^sy;+N#H${^FujVD+kC;fZI=Yd
zW^i76q5cbN@q#PI^m?#>G9@^-z3}KYeSqx3-#@`w7B$x-bk?p(@#tnz)c{-S`or+R
zan~)Nv;j`flE?;h{RDY&3uCwI7Hiiv;3Osw_8lnPWsy}T`~-zNc%<^U>j6+{>aoKs
zKO;}UB|mi+$Z(HN*CQUCp=XY}UIB5ByFLIb>U4eL(HZ*Yxa${?s7J5w1CQR&1KqA`
ze0q8Rs3JuUXpF+6m-QeAI0jyP{SAtoJ;z<a!3=hJJVXjC@Z!P`kjr;4cDwEXyS&?V
z4>%o8LRPf;2Pks(fC~5&4{Z@}h?KCtX!-H~KXTeU($HDkgArsiKn@05{EQv!CWyu1
zV2fukcDv57cI^QN84Ea|Ktc8jS*7j|P>{_58ADN!fyy!06&}6ddTqmT*99OGU)y%O
zF7W8~Il2K%ha6qe?b_qh%ez7aDNKDqDWI1%7vicH3x9#abWXGD0><Xr1q>y7kGn1b
zn*}Q87$J%vo-Fzf3f(1)-L6Z(p6qs=0}fpiWJSK;L7_VbJ#^K+qlWGqh0a=7{DXsY
zIvY}Oa)536!r1Nl#oF}^I5^LOEji@T%en=u5)`n)U@>S-b>$l<VE=%e-tGFP`2b_*
z@fXX%e)|LGH-Xa+f`9uD$nOaLKXB&%bKLa@$QZD@{<9*vtKb_b1b#4fyZ!*XtK0Pt
zI0Pnwodk7=_cu@o{6S7jZv>!59(Vl!H+d<t$zouWKQMN?ez11^0rv3=u%RFydxBXY
zA1i`cP>UXYMe^|vh>vH1OX@$+oCWrQEwVl9zJh!J4cQ-{k{aTJ^T>)izoPp9-cWG;
z;i2vNA@(q&oeFL@!&}NApN-<t5Eu=C(GVCqA;1WpQAD^mq^LBN!7VYTIF&)QfI&5<
zl%YmJK|z5*wb)8E#YzD*6_%Q!qmWurkeXbQnxbH%T5PAIke*)xW^pm77Hep7F?g1!
z7b~RaXXd3Vl;kTEBo-Gl=;@cF7MH}QW#**Dr&j1CGt|Vpq^6}76{V&qxE2-V7b#dN
zsHSi+B!cZ=NL0wnOiqQcL9PoePAv+lEJ#(TF3!v?$VrXQ%qszD&{2T$i%W{E6jY0A
z!7eT4!fJde7X#Q4pm{%tBm6>rd_cy-F<8DhBfm5!B_8Z<xD14WEDs6{h$sWZ+|uII
zqWF@^f>f9&R6Mb$D6ujgMHXxhG%y%I?qOhHV3cOI2DLRnQ&Cgi{r?Z@ynK20|Gx+$
z0|U$Z|NnIu85ly||NjqaOxk|<|KEj?fnmjm|Nm1M85pj8`2W9!k%58l<NyCl7#SFx
zKmPxJgpq+E`Q!ipPZ${(=6wABpM{Bm;p)f#|5cb67$iUa|L?-Y!0`Li|NkjW3=Gdc
z|Nq~@#K3Uz%m4pNm>3w?zyAM!go%N{|Lgz%PnZ}On!f%2&%(^W@ZkIZ|0>K34Cj9Q
z|L?-gz%b$G|Nkk>3=E*TZIG`StAZF9D+Cy&dDuB7FhayZYd9+2{r|59QsBZ4nu2Cf
zVPIe|VPIfb@b>@z1duqNfE%BL7e9A7M+1Ysl$DmT3V1pfWNr)t1H+BC|NnzEg48lV
z%mvL^UwHffe*jbrM1kz;VPIhR`0oGzY><E}pFkUvGcOxc5)V5E0|Q8Y4Fdy%&HMlV
zK_e{;F!@xlG+6!&0|SHC`~UwzbKh|Je1tqGUXtGb|8I(HehxyOhmnDy{QZB(6d}y~
zaD+T49zpV!$odNq@;;0V3=`h}|Bp*PhmnC{<@^8t!D}*L=2s*1_b@UroPGcQ|087c
znQnp=fc?+Nz|jBU|Nqx0@{i#1XBZh6qCVo5f5XVYp!(_me=}tLxnS+!@Z(`(V6gu5
z|Gx*ad_6*5hlzn9`P2XZ#-QF1%>B$-j35;t_xUg}FqD1%|33~zJ`^sW!^FU_<;(y7
z?~u)BdJ57Gw!a6IUcdhTe+Wf>CtQ9F69a?FxBvg8kmUox(jbvhJQ@O{Aut*OqaiRF
z0;3@?8UlDj0JeS(wq6dlJ`T1X4z~Ucw%!f4z74jX4Yqy_wq6akJ`J`W4b%hzIRLcg
z4@C2T2oQ!ghIv731_lNTX$V6SLc!PhL4_GWQyL&CaGM7-1PU5kW`MMZLE<p^umAq%
zgZLXjbG8f&46wCg4?uIa3=9mgHDWiQ@~|~&J3*Ql7#N_-s2M<``ye4v5P^iD+88E4
z*O!5&ib2v9AOhO12QfkG+Ca28h+tq~*Z~!QQVbuU4uiS-1T>&vYv*A0%R%+S)cyVs
z@gE}tBuM^2`5U0-{fF|Q#xZ<=@@GNie?s|uP;;qG!Pa@Bn`;1#ZwDwH0HqV4bODq`
z*GDWLw$2gKX<=Y+cXqZ?&<IT`%_}KYFf`ON)-%vGECq87>x_)_3`{hk!uV|fg(C~Y
z$N%W6K=A}x&)Ne`5YXk644`G3*wlmKk%>WoK>)h`6lNYsA4uE*P289PwCYuW0hTXe
z>OuL4kwKb40lJ<O<UWvGD5(F<AjSY&2MZDd;TotpuzU^@1K|#^dQo^j1Brp~a`3(e
zO#f~JtCwOxUq^ZnEH2IfTW1T4#`92d*m_!+_&umNY~3tO9MmUeWDsY7t&fF?{{pL*
zW^jP|_XRY(L48zEI5>bikqitlaT!Ji21W)U1_9{$d|0rmL&Xiy#Ern>;ta5LwlI5L
z!Qw&;9#Hk5c}7t91VF_TpyIIdAsQ-P0TqXpYiUsNR;V~M8!{Av#ze5BD_rTP0&I>5
zgMcc?6{r|ndTRr#mta88kNw~TBMjfS05fS3SiK~?T!V>&7Fh@}2r$6PdvKqgfq~&L
zBWPW{00XStheiX#Ij}fPH-di6h<$y29ur7h3bZK)p_qYzft?9rKCHe0<r9zsVJ6Vp
zaVZ7~XnFvNfv^-vJ(D239s!AgumVUN#6ZJg%pmj81Q{3@tikF97;>N$5x9>Is&Am;
zMbHQbk3BFjFhqjIG0g$>@dX$#{Z)xWJ*dwQ^CPlpvzZte1ev55VC5T3ZUsmjw6g)K
z30l1|YzLb!zyPbi!DB=W3=D^$;;{N1JhsHZz;F&6p3)2&;K2@<=?n~)q3Umg2J;vg
z7{Fs43=9lKP;uD)D)5*X0|Ub&s5q?NhZ*+?Dh_KWz|zk@sJ-a%$OVoU0fs1OMGqbW
zVPIh3hl<16A>gqq1_lOcs5q?M0Upy~U|`UJit|A$Qt(&|0|SF2R9ptyuz*^_5DFGY
z_#ei~WQK%4x;sn3>IE2J?IZA58v_GF6Ei41!*nC)IZ*ZOpaDS!1_oIAS<B4803Ikr
zC<U`lfYdYbfD${H4<pWj#2Ew_mVycjP`JY+f|H9%4E6FE;^PyOGUH1U(;1SBN{UNL
z)6(>k84#N};!ASllR?`#iW%bLQ}W}}bMliCbK+A<@{5Y&6H6-?lJh~s(<P}XdIs24
zfcBzf#zTgLQ}arSDjCv>5_41IQ%ZAlD;eVBk$CZ$d6^|BO2Na%py6W3@O5!XQG8x$
zPL7@hXd4S?OgyzHEipNjAt^sU2Z>uyQiQ}SH8VltC6%V7r544*M)dW}8K5FXsl}x^
zC3<EcH<jik$H(iLBA6x&py6!LST~YU@$qR8g~kYlMhK=Mf@#1|T9TQgm&_0!?-u0f
z>l*Ls=Mo>!5bqM{=jiL{%n%>%?iU*G>H(GYa0z0FclYska`cJ!cXJDN4T%qNbn<bH
zX8`#uEx#x?v4jESEhrOXmyZK%(++{{IUwUeF_>7C$`GHLl30?+0FEz={XlR7O&~-6
zu%Uc#1VQHy!1Du;eMNBPpiM*Z@gRdCdw@XkmYiFFCXc#DC_be)KRzQdF9o!J$kRW*
zxFjVr4>X;S0@581^)o0fAe^3;0&y28mLO9SAQm{jpz1-v1y>)RR9p;o5GZv)(hp2w
zacU7*BTO~ekB|fmG8AHbZhlH>PJVoGX;N`XQDSmQW_}(6bTbv2=R$m)q0tRar7%;$
zyQZ*ig#z0L4O8%(4C<aPRO3Ne2JCeP2EF3S+>*p32EF2vA_$!UV`b)*q!tx0=;h^?
zr0S*TmFg7~<rjdwi6oR%nwgWLo0$R?a&+?41r-Zm<r#^^84P+Um3hULxe&Ufhyg59
zmReK{@;fpozKB7uC^aV$qyfq*$SGma1G`nPAg4qxJ->tj%qUJxX3#51ttes8OUum5
zWY8<h2PGB;z0?e7$&is!gy2EUhzCaoL<fuw(gm_quP7hvz{K3lWClHuD1%-SXg)4E
zKQ}iu4>X4YD*`E@LDd1MX$0%f;o8p&vje0S#s<;Kpf(G*tqtNaFu?Ya!e|4CFr0+-
z=U@V$dJEJygxQb2j}<iE1XBy5Vf8(T4Z@&)0kVErzXV1@n+YJLV2rLmoPmMi+yDRh
zF#BQsXBZ8$AJ%_HcYh+Z?+nuq>tDlY4rqXZ+z4XA^h2v>2GIUKP}3f!AJ$)o(XjqG
z*zw>#0gMHq3mF&~Kz(1Bepr7OMnju1@cutc9gMDHU|<0CrD1$ne;P)^nw#kEhuF@*
z&<pN2f%<F^5m^5oM#K8|=-~(R|8%H+Cx~|VcmZtOpaLom(hq8yqKDr?XqbTH!AfBr
z87K`(-(Yblfgb;$C2gR1f$3L(>VwhXIZmiv5CxTn@8bmZ8<F)lKo!7fC>Nv^jA48j
zy#dYr6QB|>8hMTsWB^neZa*k}AlnaXpTg)c*gy|RGjwk$lnJKxquCD|kAl&#{v22_
zG_GK55PcM?AC`XLn~|XzuM6ZjkU}VixgW}9IE$tq*S>O?di40aji%oN+NgxlXW$Nl
zm;g&Z5FP`=Qw9bG(3lV?4}!#C`)pzR&e7Gw_%Qk-sErQY9}dzF8;9_Ko&x|=2a*F}
z7#~Leg}NVRKWsc90IDBX{DaH_VJ=3<*d9zjtltYehX8io04V>0)WhtB#lvbe`(fjI
z6ZAo<85qEOMj%Wu3DXawg~9!2(9UJBG@?HXE%;&i94ZSLyn}HV7#Jj>19~v`!^U?c
zp!zvr7D4qulNFT5z#s>;AF3QK4%4p<7lANf$q|`GOCn%}9#8`hKnn)YI2LFq1Lho<
zzc`WN9;^{caF|0Fmth`*aKUGEK$&0)G){x21T22r3QRG8#%~}j2nlmHgvY=D0FOXj
A`~Uy|

-- 
GitLab


From 427ee8f328e16521aa18d3778f9b769c417a5fba Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Sun, 5 Feb 2023 12:29:11 +0000
Subject: [PATCH 130/229] ignore new bin

---
 .gitignore | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.gitignore b/.gitignore
index 8110229..dd136f4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,3 +6,5 @@ obj
 *.swp
 *.swo
 .vscode
+doc/test_main_ex
+doc/info_reader_ex
-- 
GitLab


From fb5106fc764e64a741fe9a5e97e67e4184fb1f09 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:04:56 +0000
Subject: [PATCH 131/229] fix: NB_MAX cpu

---
 doc/info_reader_ex.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 23ee7d5..5cfa5f4 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 2
+#define MAX_PROCS 64 
 #define NB_KEYS 6
 
 typedef struct {
-- 
GitLab


From 844433049c8f02aab7238679b6d052d2f84aa0ff Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 10:05:38 +0000
Subject: [PATCH 132/229] core: amd_rapl.c

---
 src/amd_rapl.c   | 92 ++++++++++++++++++++++++++++++++++++------------
 tests/amd_rapl.c | 34 +++---------------
 2 files changed, 74 insertions(+), 52 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 51df298..f6eff43 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -30,6 +30,7 @@
 #include "util.h"
 
 #define BUFFER_SIZE 64
+#define __READ_CPUINFO__
 
 // ---------------------------MSR_REGISTERS
 static const uint64_t amd_energy_mask = 0xFFFFFFFF;
@@ -62,11 +63,9 @@ typedef struct _amd_rapl_t _amd_rapl_t;
 // -----------------------------INFO_READER
 
 #ifdef __READ_CPUINFO__
-#warning "Must be modified before release"
-#define MAX_CPUS 64
 #define NB_KEYS 3
 
-static const char *cpuinfo = "/proc/cpuinfo";
+static char *cpuinfo = "/proc/cpuinfo";
 
 static GenericPointer uint_allocator(char *s)
 {
@@ -97,6 +96,21 @@ static KeyFinder keys[NB_KEYS] = {
     {"physical id", ": ", uint_allocator, _set_package_id},
     {"core id", ": ", uint_allocator, _set_core_id}
 };
+
+
+static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+    Parser parser = {
+        .storage = (GenericPointer) storage,
+        .nb_stored = 0,
+        .capacity = capacity,
+        .storage_struct_size = sizeof(cpu_sensor_t),
+        .keys = keys,
+        .nb_keys = NB_KEYS,
+        .file = fopen(cpuinfo, "r")
+    };
+    return parse(&parser);
+}
+
 #endif
 
 // --------------------------------READ_MSR
@@ -159,13 +173,14 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(cpu_sensor_t *sensor)
 {
     //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
-    printf("cpu_id : %d, package_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
+           sensor->core_id,
            sensor->name,
            sensor->fd,
            sensor->energy_units,
-           sensor->core_energy,
+           sensor->core_energy
           );
 }
 
@@ -197,6 +212,22 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
+void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, cpu_sensor_t *sensors, unsigned int nb_sensor)
+{
+    unsigned int nb_package = 0;
+    unsigned int nb_core = 0;
+    for (unsigned int i = 0; i < nb_sensor; i++) {
+        if (sensors[i].package_id > nb_package) {
+            nb_package = sensors[i].package_id;
+        }
+        if (sensors[i].core_id > nb_core) {
+            nb_core = sensors[i].core_id;
+        }
+    }
+    *ret_nb_package = nb_package + 1;
+    *ret_nb_core = nb_core + 1;
+}
+
 char *get_name(unsigned int cpu_id)
 {
     static const char *base_name = "core%d";
@@ -216,27 +247,29 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int init_cpu_sensor(cpu_sensor_t *sensor, unsigned int cpu_id, unsigned char *cpus_map, unsigned int max_cpus)
-{
-    if (cpus_map[sensor->core_id * max_cpus + sensor->package_id] > 0) {
-        return 0;
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+        return 1;
     }
-    cpus_map[sensor->core_id * max_cpus + sensor->package_id] += 1;
+    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    return 0;
+}
 
+void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
+{
     static char filename[BUFFER_SIZE];
-    sprintf(filename, base_str, cpu_id);
+    snprintf(filename,BUFFER_SIZE, base_str, cpu_info->cpu_id);
 
     int fd = open(filename, O_RDONLY);
     if (fd < 0) {
-        fprintf(stderr, base_str, cpu_id);
+        fprintf(stderr, base_str, cpu_info->cpu_id);
         perror(":open()");
         exit(127);
     }
 
-    sensor->cpu_id = cpu_id;
-    sensor->name = get_name(cpu_id);
+    memcpy(sensor, cpu_info, sizeof(cpu_sensor_t));
+    sensor->name = get_name(sensor->cpu_id);
     sensor->fd = fd;
-    return 1;
 }
 
 void clean_cpu_sensor(cpu_sensor_t *sensor)
@@ -256,7 +289,6 @@ void free_amd_rapl(_amd_rapl_t *rapl)
 unsigned int init_amd_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
 
     unsigned int max_cpus = get_nb_cpu();
     if (max_cpus == 0) {
@@ -265,18 +297,32 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    unsigned char *cpus_map = calloc(max_cpus * max_cpus, sizeof(unsigned char));
-    cpu_sensor_t *cpus = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
-    rapl->sensors = cpus;
+    cpu_sensor_t *cpu_information = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    if (parse_cpuinfo(cpu_information, max_cpus)) {
+        free(cpu_information);
+        PANIC(1, "cpuinfo");
+    }
 
-    unsigned int nb_cpu = 0;
+    unsigned int nb_package;
+    unsigned int nb_core;
+    get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
+
+    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+
+    unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        nb_cpu += init_cpu_sensor(&rapl->sensors[nb_cpu], i, cpus_map, max_cpus);
+        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+            init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
+            sensor_count += 1;
+        }
     }
-    rapl->sensor_count = nb_cpu;
+    free(cpu_information);
 
+    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+    rapl->sensors = sensors;
+    rapl->sensor_count = sensor_count;
     *ptr = (void *) rapl;
-    free(cpus_map);
     return rapl->sensor_count;
 }
 
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 39214fc..2425287 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -179,48 +179,24 @@ TFUNCTION(test_label_amd_rapl, {
     TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
-TFUNCTION(test_init_cpu_sensor, {
-    static const unsigned int max_cpus = 10;
-    unsigned char cpus_map[max_cpus * max_cpus];
-    cpu_sensor_t sensor_t1;
-    unsigned int result;
-    unsigned int expected;
-
-    // Test 1:
-    // -- Setup
-    memset(cpus_map, 0, max_cpus *max_cpus * sizeof(unsigned char));
-    result = 0;
-    expected = 1;
-    memset(&sensor_t1, 0, sizeof(cpu_sensor_t));
-    sensor_t1.cpu_id = 1;
-    sensor_t1.core_id = 0;
-    sensor_t1.package_id = 0;
-    // -- Run
-    result = init_cpu_sensor(&sensor_t1, 0, cpus_map, max_cpus);
-    // -- Verification
-    TEST_UINT64_T(&result, &expected);
-})
-
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
-    // CALL_TFUNCTION(test_init_cpu_sensor);
 })
 
 #ifdef __TESTING__AMD__
 int main()
 {
-    test_amd_rapl();
     static const unsigned int time = 10;
     _amd_rapl_t *rapl = NULL;
-    unsigned int nb_cpu = init_amd_rapl(NULL, (void **) &rapl);
-    uint64_t results[nb_cpu];
-    char *labels[nb_cpu];
+    unsigned int count_cpu = init_amd_rapl(NULL, (void **) &rapl);
+    uint64_t results[count_cpu];
+    char *labels[count_cpu];
 
     label_amd_rapl(labels, (void *) rapl);
 
-    for (unsigned int i = 0; i < rapl->nb; ++i) {
+    for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         printf("%s ", labels[i]);
     }
     printf("\n");
@@ -231,7 +207,7 @@ int main()
         sleep(1);
         get_amd_rapl(results, (void *)rapl);
 
-        for (unsigned int j = 0; j < rapl->nb; ++j) {
+        for (unsigned int j = 0; j < rapl->sensor_count; ++j) {
             printf("%ld ", results[j]);
         }
         printf("\n");
-- 
GitLab


From 76653cfafb1f60a31791a761fcd41d5c54b6b9c4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 11:47:35 +0000
Subject: [PATCH 133/229] core: small_test modification of the api

---
 doc/info_reader_ex.c |   2 +-
 doc/test_file_ex.c   |  31 ++++++++----
 src/amd_rapl.c       |  14 +++---
 tests/amd_rapl.c     | 116 ++++++++++++++++++++++++++++++++++++++----
 tests/small_test.h   | 117 +++++++++++++++++++++++++++++++++++--------
 5 files changed, 231 insertions(+), 49 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 5cfa5f4..f672d98 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -22,7 +22,7 @@
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
 #include "./../src/info_reader.h"
 
-#define MAX_PROCS 64 
+#define MAX_PROCS 64
 #define NB_KEYS 6
 
 typedef struct {
diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 44ebc2c..4e3a093 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -35,6 +35,20 @@ TFUNCTION(test_should_fail, {
     TEST_STR(result, expected);
 })
 
+// -- A simple test of array
+TFUNCTION(test_array, {
+    static unsigned int size = 10;
+    int array[10];
+    TEST_ARRAY(TEST_INT, size, array, array);
+})
+
+// -- A simple test of array of pointer
+TFUNCTION(test_ptr_array, {
+    static unsigned int size = 10;
+    void *array[10];
+    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
+})
+
 // -- Add a new type in the test framework
 
 typedef struct {
@@ -89,24 +103,21 @@ TFUNCTION(test_user_type, {
 
 // -- Compare an array of usetype
 TFUNCTION(test_array_user_type, {
-    UserType *results[1];
-    UserType *expecteds[1];
-
-    UserType x1;
-    UserType x2;
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    UserType results[1];
+    UserType expecteds[1];
 
-    results[0] = &x1;
-    expecteds[0] = &x2;
+    DUMMY_USER_TYPE(results[0], 1, "John Doe");
+    DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_T_ARRAY(TEST_USER_TYPE, 1, (void **)results, (void **)expecteds);
+    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
 })
 
 // Define the entry point of a test file
 TFILE_ENTRY_POINT(test_file_ex, {
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
+    CALL_TFUNCTION(test_array);
+    CALL_TFUNCTION(test_ptr_array);
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index f6eff43..1d9bc37 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -98,7 +98,8 @@ static KeyFinder keys[NB_KEYS] = {
 };
 
 
-static unsigned int parse_cpuinfo(cpu_sensor_t* storage, unsigned int capacity) {
+static unsigned int parse_cpuinfo(cpu_sensor_t *storage, unsigned int capacity)
+{
     Parser parser = {
         .storage = (GenericPointer) storage,
         .nb_stored = 0,
@@ -247,12 +248,13 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core) {
+unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+{
     if (map[sensor->core_id * nb_core + sensor->package_id]) {
-        return 1;
+        return 0;
     }
     map[sensor->core_id * nb_core + sensor->package_id] += 1;
-    return 0;
+    return 1;
 }
 
 void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
@@ -307,8 +309,8 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char*) calloc(nb_core * nb_package, sizeof(unsigned char));
-    cpu_sensor_t *sensors = (cpu_sensor_t*) calloc(max_cpus, sizeof(cpu_sensor_t));
+    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 2425287..1857a6a 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -116,15 +116,15 @@ do {                                             \
     .energy_units = NONE,                        \
     .core_energy = NONE,                         \
   };                                             \
-	} while(0);
+} while(0);
 
 #define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
-	do {                                                 \
-		__rapl = (_amd_rapl_t) {                           \
-			.sensors = __sensors,                            \
-			.sensor_count = __sensors_count                 \
-		};                                                 \
-	} while(0);
+do {                                                   \
+    __rapl = (_amd_rapl_t) {                           \
+        .sensors = __sensors,                          \
+        .sensor_count = __sensors_count                \
+    };                                                 \
+} while(0);
 
 TFUNCTION(test_label_amd_rapl, {
     cpu_sensor_t sensors[100];
@@ -142,7 +142,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 2:
     // -- Setup
@@ -159,7 +159,7 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 
     // Test 3:
     // -- Setup
@@ -176,13 +176,109 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_T_ARRAY(TEST_STR, nb, results, expecteds);
+    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
 })
 
+
+#define DUMMY_CPUINFO(__sensor, __cpu_id, __package_id, __core_id) \
+do {                                                               \
+    __sensor = (cpu_sensor_t) {                                    \
+        .cpu_id = __cpu_id,                                        \
+        .package_id = __package_id,                                \
+        .core_id = __core_id,                                      \
+        .name = NULL,                                              \
+        .fd = NONE,                                                \
+        .energy_units = NONE,                                      \
+        .core_energy = NONE                                        \
+    };                                                             \
+} while (0);
+
+TFUNCTION(test_is_duplicate, {
+    static const unsigned int nb_core = 4;
+    static const unsigned int nb_package = 2;
+    static const unsigned int max_cpu = 10;
+
+    unsigned char map[nb_core * nb_package];
+    cpu_sensor_t cpu_information[max_cpu];
+    unsigned int results[2];
+    unsigned int expecteds[2];
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 0;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    expecteds[0] = 1;
+    expecteds[1] = 1;
+    // -- Run
+    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    // -- Verification
+    TEST_BOOL(&results[0], &expecteds[0]);
+    TEST_BOOL(&results[1], &expecteds[1]);
+})
+
+
 TFILE_ENTRY_POINT(test_amd_rapl, {
     CALL_TFUNCTION(test_raw_to_microjoule);
     CALL_TFUNCTION(test_get_name);
     CALL_TFUNCTION(test_label_amd_rapl);
+    CALL_TFUNCTION(test_is_duplicate);
 })
 
 #ifdef __TESTING__AMD__
diff --git a/tests/small_test.h b/tests/small_test.h
index aedc685..ef9d90b 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,15 +33,17 @@
 /**
  * @brief Define the entry point of the tests
  * It initializes each useful variables.
+ *
+ * @param __code The code that contains the calls to the test functions
  */
 
-#define TMAIN(code)                                              \
+#define TMAIN(__code)                                              \
   int main()                                                     \
 {                                                                \
   unsigned int __indentation_level = 0;                          \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
-  do code while (0);                                             \
+  do __code while (0);                                             \
   DEFERRED_FILE_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
@@ -108,7 +110,6 @@
  * @def TEST_STR(result, expected)
  * @brief Test strings
  * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
- * The macro uses the `test_str()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the string to be tested
  * @param __expected the expected value of the string
@@ -124,23 +125,43 @@
  * @def TEST_BOOL(__result, __expected)
  * @brief Test bools
  * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
- * The macro uses the `test_bool()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the bool to be tested
- * @param __expected the expected value of the bool
+ * @param __result the pointer to bool to be tested
+ * @param __expected the pointer to the expected value of the bool
  *
  * @code
- * TEST_BOOL(1 == 1, true);
+ * bool x = true;
+ * bool y = false;
+ * TEST_BOOL(&x, &y);
  * @endcode
  */
 #define TEST_BOOL(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &bool_interface);} while (0)
 
+/**
+ * @def TEST_INT(__result, __expected)
+ * @brief Test ints
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ *
+ * @param __result the pointer to int to be tested
+ * @param __expected the pointer to expected value of the int
+ *
+ * @code
+ * int x = 1;
+ * int y = 1;
+ * TEST_INT(&x, &y)
+ * @endcode
+ */
+#define TEST_INT(__result, __expected) \
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
+
+
+
+
 /**
  * @def TEST_PTR(__result, __expected)
  * @brief Test pointers
  * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
- * The macro uses the `test_ptr()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
  * @param __result the pointer to be tested
  * @param __expected the expected value of the pointer
@@ -159,24 +180,38 @@
  * @def TEST_UINT64_T(__result, __expected)
  * @brief Test 64-bit unsigned integers
  * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
- * The macro uses the `test_uint64_t()` function to perform the test, and provides the `__FILE__`, `__LINE__` preprocessor macros to indicate the location of the test in the source code.
  *
- * @param __result the integer to be tested
- * @param __expected the expected value of the integer
+ * @param __result the pointer to integer to be tested
+ * @param __expected the pointer to expected value of the integer
  *
  * @code
- * TEST_UINT64_T(5, 5);
+ * uint64_t x = 5;
+ * uint64_t y = 5;
+ * TEST_UINT64_T(&x, &y);
  * @endcode
  */
 #define TEST_UINT64_T(__result, __expected) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &u64_interface);} while(0)
 
+/**
+ * @def TEST_INTERFACE(__result, __expected, __interface)
+ * @brief Define a macro on a usertype with the given __interface
+ * This macro is used by the user to define a new test macro on a usertype.
+ *
+ * @param __result
+ * @param __expected
+ * @param __interface the usertype interface
+ *
+ * @code
+ * #define TEST_USERTYPE(__result, __expected)
+ * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * @endcode
+ */
 #define TEST_INTERFACE(__result, __expected, __interface) \
-	do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
-
+    do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
 /**
- * @def TEST_T_ARRAY(function, nb_error, size, results, expecteds)
+ * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
  * @brief Test arrays of data
  * The macro uses a for loop to iterate through the array and apply the test function to each element.
  *
@@ -188,15 +223,33 @@
  * @code
  * int results[3] = {1, 2, 3};
  * int expecteds[3] = {1, 2, 3};
- * TEST_T_ARRAY(TEST_INT, 3, results, expecteds);
+ * TEST_ARRAY(TEST_INT, 3, results, expecteds);
  * @endcode
 */
-#define TEST_T_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-	for (unsigned int i = 0; i < __array_size; i++) {                       \
-      __test_macro(__results[i], __expecteds[i]);                         \
-	}
+#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
+    for (unsigned i = 0; i < __array_size; i++) {                      \
+        __test_macro(&__results[i], &__expecteds[i]);                   \
+    }
 
+/**
+ * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
+ * @brief Test arrays of pointer
+ * The macro uses a for loop to iterate through the array and apply the test function to each element.
+ *
+ * @param __test_macro the test function to be used on each element of the array
+ * @param __array_size the number of elements in the array
+ * @param __results the array of elements to be tested
+ * @param __expecteds the array of expected values
 
+ * @code
+ * void* array[3];
+ * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
+ * @endcode
+*/
+#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
+    for (unsigned int i = 0; i < __array_size; i++) {                     \
+      __test_macro(__results[i], __expecteds[i]);                         \
+    }
 // --------------------------------API_CODE
 // These functions should not be used, only use the previous macros.
 
@@ -261,7 +314,6 @@ static const TestInterface str_interface = {
 
 //  --------------------------bool_interface
 
-
 int bool_compare(void *ptr1, void *ptr2)
 {
     bool *bool1 = (bool *) ptr1;
@@ -281,6 +333,27 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
+// ---------------------------int_interface
+
+int int_compare(void *ptr1, void *ptr2)
+{
+    int *int1 = (int *) ptr1;
+    int *int2 = (int *) ptr2;
+    return *int1 == *int2;
+}
+
+char *int_format(char buffer[1000], void *ptr)
+{
+    int *_int = (int *) ptr;
+    snprintf(buffer, 1000, "%d", *_int);
+    return buffer;
+}
+
+static const TestInterface int_interface = {
+    .compare = int_compare,
+    .format = int_format
+};
+
 // ---------------------------ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
-- 
GitLab


From bab4a95c8dccf445cb0bb359fc8dfe9b8eee0d59 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:09:00 +0000
Subject: [PATCH 134/229] fix: is_duplicate

---
 src/amd_rapl.c   |  2 +-
 tests/amd_rapl.c | 24 ++++++++++++++++++++++--
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 1d9bc37..0c363af 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (!is_duplicate(cpu_information, cpu_map, nb_core)) {
+        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 1857a6a..f2d13ef 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -200,8 +200,8 @@ TFUNCTION(test_is_duplicate, {
 
     unsigned char map[nb_core * nb_package];
     cpu_sensor_t cpu_information[max_cpu];
-    unsigned int results[2];
-    unsigned int expecteds[2];
+    unsigned int results[max_cpu];
+    unsigned int expecteds[max_cpu];
 
     // -- Setup
     memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
@@ -271,6 +271,26 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
+    
+    // -- Setup
+    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[2], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[3], 0, 1, 1);
+    DUMMY_CPUINFO(cpu_information[4], 0, 0, 0);
+    DUMMY_CPUINFO(cpu_information[5], 0, 0, 1);
+    DUMMY_CPUINFO(cpu_information[6], 0, 1, 0);
+    DUMMY_CPUINFO(cpu_information[7], 0, 1, 1);
+    memset(expecteds, 1, sizeof(unsigned int) * 4);
+    memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
+    // -- Run
+    for (unsigned int i = 0; i < 8; i++) {
+        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+    }
+    // -- Verification
+    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
 })
 
 
-- 
GitLab


From a1cded04769e4d1c90e9b370419026e8c296b8e3 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 12:15:20 +0000
Subject: [PATCH 135/229] fix: init_amd_rapl

---
 src/amd_rapl.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 0c363af..888df5a 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -314,7 +314,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(cpu_information, cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
-- 
GitLab


From 00600d4ad379584817de4a5cdabaeb78a8206a1c Mon Sep 17 00:00:00 2001
From: Floreal Risso <frisso@grue-2.nancy.grid5000.fr>
Date: Mon, 6 Feb 2023 13:54:44 +0100
Subject: [PATCH 136/229] fix is_duplicate

---
 src/amd_rapl.c   | 11 ++++++-----
 tests/amd_rapl.c | 36 ++++++++++++++++++------------------
 2 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 888df5a..805e698 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -248,12 +248,12 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor, unsigned char map[], unsigned int nb_core)
+unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
 {
-    if (map[sensor->core_id * nb_core + sensor->package_id]) {
+    if (map[sensor->core_id][sensor->package_id] == 1) {
         return 0;
     }
-    map[sensor->core_id * nb_core + sensor->package_id] += 1;
+    map[sensor->core_id][sensor->package_id] += 1;
     return 1;
 }
 
@@ -309,12 +309,13 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     unsigned int nb_core;
     get_arch(&nb_package, &nb_core, cpu_information, max_cpus);
 
-    unsigned char *cpu_map = (unsigned char *) calloc(nb_core * nb_package, sizeof(unsigned char));
+    unsigned char cpu_map[nb_core][nb_package];
+    memset(cpu_map, 0, sizeof(cpu_map));
     cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
-        if (is_duplicate(&cpu_information[i], cpu_map, nb_core) == 1) {
+        if (is_duplicate(&cpu_information[i], nb_core, nb_package, cpu_map) == 1) {
             init_cpu_sensor(&sensors[sensor_count],&cpu_information[i]);
             sensor_count += 1;
         }
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index f2d13ef..09ac0d9 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -198,82 +198,82 @@ TFUNCTION(test_is_duplicate, {
     static const unsigned int nb_package = 2;
     static const unsigned int max_cpu = 10;
 
-    unsigned char map[nb_core * nb_package];
+    unsigned char map[nb_core][nb_package];
     cpu_sensor_t cpu_information[max_cpu];
     unsigned int results[max_cpu];
     unsigned int expecteds[max_cpu];
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[0], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
+    results[1] = is_duplicate(&cpu_information[0], nb_core, nb_package,map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
 
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     expecteds[0] = 1;
     expecteds[1] = 1;
     // -- Run
-    results[0] = is_duplicate(&cpu_information[0], map, nb_core);
-    results[1] = is_duplicate(&cpu_information[1], map, nb_core);
+    results[0] = is_duplicate(&cpu_information[0], nb_core, nb_package, map);
+    results[1] = is_duplicate(&cpu_information[1], nb_core, nb_package, map);
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
     
     // -- Setup
-    memset(map, NONE, sizeof(unsigned char) * nb_package * nb_core);
+    memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
@@ -287,7 +287,7 @@ TFUNCTION(test_is_duplicate, {
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
     for (unsigned int i = 0; i < 8; i++) {
-        results[i] = is_duplicate(&cpu_information[i], map, nb_core);
+        results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
     TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
-- 
GitLab


From 851cef1b09b4bf468aed0e11ca8c6cba31826067 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:39:07 +0000
Subject: [PATCH 137/229] fix: add ifndef

---
 src/info_reader.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

diff --git a/src/info_reader.h b/src/info_reader.h
index 1696ede..e83b2c3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -1,3 +1,26 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+#ifndef _INFO_READER_H
+#define _INFO_READER_
+
 #include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
@@ -216,3 +239,5 @@ static bool start_with(const char *prefix, const char *string)
     }
 }
 
+#endif
+
-- 
GitLab


From 5e505cc72bb11a4a119527a21c80b6d208fffdbb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 6 Feb 2023 16:49:39 +0000
Subject: [PATCH 138/229] fix: add safety

---
 doc/test_file_ex.c |  4 ++--
 tests/small_test.h | 24 +++++++++++++-----------
 2 files changed, 15 insertions(+), 13 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 4e3a093..13e1f48 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -63,10 +63,10 @@ int usertype_compare(void *ptr1, void *ptr2)
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
-char *usertype_format(char buffer[1000], void *ptr)
+char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
-    sprintf(buffer, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
+    snprintf(buffer, FMT_BUFFER_SIZE, "UserType {simple_int: %d, simple_str: %s}", x->simple_int, x->simple_str);
     return buffer;
 }
 
diff --git a/tests/small_test.h b/tests/small_test.h
index ef9d90b..eddbdb0 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -29,6 +29,8 @@
 
 #include "../src/util.h"
 
+#define FMT_BUFFER_SIZE 1000
+
 // ---------------------------API_INTERFACE
 /**
  * @brief Define the entry point of the tests
@@ -276,7 +278,7 @@
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
-typedef char *(Formatter) (char *, void *);
+typedef char *(Formatter) (char[FMT_BUFFER_SIZE], void *);
 
 typedef struct {
     Comparator *compare;
@@ -299,7 +301,7 @@ int str_compare(void *ptr1, void *ptr2)
     }
 }
 
-char *str_format(char *buffer, void *ptr)
+char *str_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     static char *str_null = "NULL";
@@ -321,7 +323,7 @@ int bool_compare(void *ptr1, void *ptr2)
     return *bool1 == *bool2;
 }
 
-char *bool_format(char *buffer, void *ptr)
+char *bool_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UNUSED(buffer);
     bool *_bool = (bool *) ptr;
@@ -342,10 +344,10 @@ int int_compare(void *ptr1, void *ptr2)
     return *int1 == *int2;
 }
 
-char *int_format(char buffer[1000], void *ptr)
+char *int_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     int *_int = (int *) ptr;
-    snprintf(buffer, 1000, "%d", *_int);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%d", *_int);
     return buffer;
 }
 
@@ -361,9 +363,9 @@ int ptr_compare(void *ptr1, void *ptr2)
     return ptr1 == ptr2;
 }
 
-char *ptr_format(char *buffer, void *ptr)
+char *ptr_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
-    sprintf(buffer, "%p", ptr);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%p", ptr);
     return buffer;
 }
 
@@ -381,10 +383,10 @@ int u64_compare(void *ptr1, void *ptr2)
     return *v1 == *v2;
 }
 
-char *u64_format(char *buffer, void *ptr)
+char *u64_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     uint64_t *v = (uint64_t *) ptr;
-    sprintf(buffer, "%"PRIu64"", *v);
+    snprintf(buffer, FMT_BUFFER_SIZE, "%"PRIu64"", *v);
     return buffer;
 }
 
@@ -398,8 +400,8 @@ static const TestInterface u64_interface = {
 int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
 {
     __indentation_level += 1;
-    static char buffer_result[1000];
-    static char buffer_expected[1000];
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
     int is_equal = interface->compare(result, expected);
 
     char *fmt_result = interface->format(buffer_expected, expected);
-- 
GitLab


From 9b9a4c4206947e9cd6180cd1071441911a3783ba Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:55:33 +0000
Subject: [PATCH 139/229] fix: documentation

---
 doc/test_file_ex.c |  93 +++++++++++++++--------
 doc/test_main_ex.c |   3 +-
 tests/amd_rapl.c   |  26 +++++--
 tests/small_test.h | 183 +++++++++++++++++++--------------------------
 4 files changed, 163 insertions(+), 142 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 13e1f48..95baaa7 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,49 +20,70 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
+// Include the file that contains the function you want to test 
+// #include "a_file.c"
 
-// -- A simple function that should pass
+// This example is divided into three parts:
+// 1. SOME SIMPLE EXAMPLES
+// 2. A MORE COMPLEX EXAMPLE
+// 3. FILE ENTRY POINT
+
+//  -----------------1. SOME SIMPLE EXAMPLES
+
+// A simple function that should pass
+// test_should_pass is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_pass, {
-    char *result = "It's going to pass";
-    char *expected = "It's going to pass";
-    TEST_STR(result, expected);
+    int result = 42;
+    int expected = 42;
+    TEST_INT(&result, &expected);
 })
 
-// -- A simple function that should fail
+// A simple function that should pass
+// test_should_fail is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_should_fail, {
     char *result = "a fail";
     char *expected = "a nice fail";
     TEST_STR(result, expected);
 })
 
-// -- A simple test of array
+// A simple test on an array
+// test_array is the name of the function
+// {} is the function code
+// Use one of the define TEST_XXX defined in small_test.h
 TFUNCTION(test_array, {
     static unsigned int size = 10;
-    int array[10];
-    TEST_ARRAY(TEST_INT, size, array, array);
+    int results[10] = {0};
+    int expecteds[10] = {0};
+    for (unsigned int i = 0; i < size; i++) {
+        TEST_INT(&results[i], &expecteds[i]);
+    }
 })
 
-// -- A simple test of array of pointer
-TFUNCTION(test_ptr_array, {
-    static unsigned int size = 10;
-    void *array[10];
-    TEST_PTR_ARRAY(TEST_PTR, size, array, array);
-})
+// See "TFILE_ENTRY_POINT" for how to call these functions.
 
-// -- Add a new type in the test framework
+// ------------2. THE MORE COMPLEX EXAMPLE
+// This example shows how to add a new type to the framework
 
+// The type that you want to add :
 typedef struct {
     int simple_int;
     char simple_str[20];
 } UserType;
 
 
-// -- Implemet the interface
+// The test framework needs two functions :
+
+// A function that compares two values.
 int usertype_compare(void *ptr1, void *ptr2)
 {
     return memcmp(ptr1, ptr2, sizeof(UserType)) == 0;
 }
 
+// A function to format a value.
 char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
 {
     UserType *x = (UserType *) ptr;
@@ -70,17 +91,18 @@ char *usertype_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
     return buffer;
 }
 
-// Create a variable which contains the functions
+// Store the functions in the interface type.
 static const TestInterface usertype_interface = {
     .compare = usertype_compare,
     .format = usertype_format
 };
 
-// -- Create the test macro to call
+// Create a macro that implements the interface by passing the interface created to the TEST_INTERFACE macro.
 #define TEST_USER_TYPE(__result, __expected) \
-    TEST_INTERFACE(__result, __expected, &usertype_interface);
+    TEST_INTERFACE(__result, __expected, &usertype_interface)
 
-// -- Create a macro setter
+
+// Creating a constructor is recommended (C can have problems parsing macros where "," is used).
 #define DUMMY_USER_TYPE(__user, __simple_int, __simple_str) \
     do {                                                    \
       __user = (UserType) {                                 \
@@ -89,19 +111,22 @@ static const TestInterface usertype_interface = {
     };                                                      \
 } while (0);
 
-// -- Compare two usertype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_user_type, {
-    UserType x1;
-    UserType x2;
+    UserType result;
+    UserType expected;
 
-    DUMMY_USER_TYPE(x1, 1, "John Doe");
-    DUMMY_USER_TYPE(x2, 1, "John Doe");
+    DUMMY_USER_TYPE(result, 1, "John Doe");
+    DUMMY_USER_TYPE(expected, 1, "John Doe");
 
-    TEST_USER_TYPE(&x1, &x2);
+    TEST_USER_TYPE(&result, &expected);
 })
 
-
-// -- Compare an array of usetype
+// Now you can write test for your new type
+// all you have to do is call the macro that implements "TEST_INTERFACE".
+// here it's "TEST_USERTYPE"
 TFUNCTION(test_array_user_type, {
     UserType results[1];
     UserType expecteds[1];
@@ -109,15 +134,23 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    TEST_ARRAY(TEST_USER_TYPE, 1, results, expecteds);
+    for (unsigned int i = 0; i < 1; i++) {
+        TEST_USER_TYPE(&results[i], &expecteds[i]);
+    }
 })
 
+// ---------------------3. FILE ENTRY POINT
+
 // Define the entry point of a test file
+// Use the macro "CALL_TFUNCTION" where the name of a function is defined with the macro "TFUNCTION".
 TFILE_ENTRY_POINT(test_file_ex, {
+    // Call the simple examples
     CALL_TFUNCTION(test_should_pass);
     CALL_TFUNCTION(test_should_fail);
     CALL_TFUNCTION(test_array);
-    CALL_TFUNCTION(test_ptr_array);
+
+    // Call the more complex example
     CALL_TFUNCTION(test_user_type);
     CALL_TFUNCTION(test_array_user_type);
 })
+
diff --git a/doc/test_main_ex.c b/doc/test_main_ex.c
index 0aa86b9..a5e7841 100644
--- a/doc/test_main_ex.c
+++ b/doc/test_main_ex.c
@@ -22,7 +22,7 @@
 // Include of the test library
 #include "./../tests/small_test.h"
 
-// Include the *.c files that contain the tests
+// Include the *.c files containing the tests
 #include "./test_file_ex.c"
 // #include "./test_another_test_file.c"
 
@@ -33,3 +33,4 @@ TMAIN({
     CALL_TFUNCTION(test_file_ex);
     // CALL_TFUNCTION(another_file_entry_point_function);
 })
+
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 09ac0d9..0485099 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -142,7 +142,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 
     // Test 2:
     // -- Setup
@@ -159,8 +162,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
-
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
     // Test 3:
     // -- Setup
     nb = 4;
@@ -176,7 +181,10 @@ TFUNCTION(test_label_amd_rapl, {
     // -- Run
     label_amd_rapl(results, (void *) &rapl);
     // -- Verification
-    TEST_PTR_ARRAY(TEST_STR, nb, results, expecteds);
+    for(unsigned int i = 0; i < nb; i++)
+    {
+        TEST_STR(results[i], expecteds[i]);
+    }
 })
 
 
@@ -271,7 +279,7 @@ TFUNCTION(test_is_duplicate, {
     // -- Verification
     TEST_BOOL(&results[0], &expecteds[0]);
     TEST_BOOL(&results[1], &expecteds[1]);
-    
+
     // -- Setup
     memset(map, NONE, sizeof(map));
     memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
@@ -286,11 +294,15 @@ TFUNCTION(test_is_duplicate, {
     memset(expecteds, 1, sizeof(unsigned int) * 4);
     memset(&expecteds[4], 0, sizeof(unsigned int) * 4);
     // -- Run
-    for (unsigned int i = 0; i < 8; i++) {
+    for (unsigned int i = 0; i < 8; i++)
+    {
         results[i] = is_duplicate(&cpu_information[i], nb_core, nb_package, map );
     }
     // -- Verification
-    TEST_ARRAY(TEST_BOOL, 8, results, expecteds);
+    for(unsigned int i = 0; i < 8; i++)
+    {
+        TEST_BOOL(&results[i], &expecteds[i]);
+    }
 })
 
 
diff --git a/tests/small_test.h b/tests/small_test.h
index eddbdb0..abae768 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,10 +33,10 @@
 
 // ---------------------------API_INTERFACE
 /**
- * @brief Define the entry point of the tests
- * It initializes each useful variables.
+ * @brief Define the entry point for the tests.
+ * It initialises any useful variables and acts as the main one.
  *
- * @param __code The code that contains the calls to the test functions
+ * @param __code The code that contains the calls to the test functions.
  */
 
 #define TMAIN(__code)                                              \
@@ -46,22 +46,24 @@
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
   unsigned int __error_counter__ = 0;                            \
   do __code while (0);                                             \
-  DEFERRED_FILE_ERROR(__error_counter__);                        \
+  DEFERRED_ERROR(__error_counter__);                        \
   return __error_counter__;                                      \
 }
 
 /**
+ * @def TFILE_ENTRY_POINT(__filename, __code)
+ *
  * @brief Define the entry point of a test file.
  * This macro is used to define the entry point of a test file.
  * It defines a function with the specified __filename that contains the test code specified in code.
  *
- * When the function is called, it initializes the test file using the INIT_TEST_FILE macro,
+ * When the function is called, it initialises the test file using the INIT_TEST_FILE macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__,
  * which indicates the number of errors encountered during the tests.
  *
- * @param __filename The name of the function that serves as the entry point for the test file.
+ * @param __filename The name of the function to be used as an entry point for the test file.
  * @param __code The test code to be executed in the function.
  */
 #define TFILE_ENTRY_POINT(__filename, __code)       \
@@ -70,16 +72,18 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_FILE_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);           \
   return __error_counter__;                         \
 }
 
 /**
+ * @def TFUNCTION(__function_name, __code)
+ *
  * @brief Define a test function within a test file.
  * This macro is used to define a test function within a test file.
- * It defines a function with the specified function_name that contains the test code specified in code.
+ * It defines a function with the given __function_name containing the test code specified in __code.
  *
- * When the function is called, it initializes the test function using the INIT_TEST_FUNCTION macro,
+ * When the function is called, it initialises the test function using the INIT_TEST_FUNCTION macro,
  * declares an integer variable __error_counter__ to keep track of any errors encountered during the tests,
  * executes the test code in a do-while loop, and then checks for any deferred errors using the DEFERRED_ERROR macro.
  * The function returns the value of __error_counter__, which indicates the number of errors encountered during the tests.
@@ -93,28 +97,32 @@
   INIT_TEST_FUNCTION(); \
   int __error_counter__ = 0; \
   do __code while(0); \
-  DEFERRED_FUNCTION_ERROR(__error_counter__); \
+  DEFERRED_ERROR(__error_counter__); \
   return __error_counter__; \
 }
 
 /**
+ * @def CALL_TFUNCTION(__function_name)
+ *
  * @brief Call a test function within a test file.
  * This macro is used to call a test function within a test file.
- * It calls the function specified by function_name and adds the return value to the __error_counter__ variable.
+ * It calls the function specified by __function_name and adds the return value to the __error_counter__ variable.
  * This allows multiple test functions to be executed and their error count to be accumulated.
  *
- * @param function_name The name of the test function to be called.
+ * @param __function_name The name of the test function to be called.
  */
-#define CALL_TFUNCTION(function_name) \
-  do {__error_counter__ += function_name(__indentation_level + 1);} while(0)
+#define CALL_TFUNCTION(__function_name) \
+  do {__error_counter__ += __function_name(__indentation_level + 1);} while(0)
 
 /**
- * @def TEST_STR(result, expected)
+ * @def TEST_STR(__result, __expected)
+ *
  * @brief Test strings
- * This macro is used to test strings. It takes two arguments: `__result`, which is the string to be tested, and `__expected`, which is the expected value of the string.
+ * This macro is used to test strings. It takes two arguments: `__result`, which is the string to test, and `__expected`,
+ * which is the expected value of the string.
  *
- * @param __result the string to be tested
- * @param __expected the expected value of the string
+ * @param __result the string to test.
+ * @param __expected the expected value of the string.
  *
  * @code
  * TEST_STR("Hello", "Hello");
@@ -125,15 +133,17 @@
 
 /**
  * @def TEST_BOOL(__result, __expected)
+ *
  * @brief Test bools
- * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to be tested, and `__expected`, which is the expected value of the bool.
+ * This macro is used to test bools. It takes two arguments: `__result`, which is the bool to test, and `__expected`,
+ * which is the expected value of the bool.
  *
- * @param __result the pointer to bool to be tested
- * @param __expected the pointer to the expected value of the bool
+ * @param __result the pointer to bool to test.
+ * @param __expected the pointer to the expected value of the bool.
  *
  * @code
  * bool x = true;
- * bool y = false;
+ * bool y = true;
  * TEST_BOOL(&x, &y);
  * @endcode
  */
@@ -142,11 +152,13 @@
 
 /**
  * @def TEST_INT(__result, __expected)
+ *
  * @brief Test ints
- * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be tested, and `__expected`, which is the expected value of the int.
+ * This macro is used to test ints. It takes two arguments: `__result`, which is the int to be test, and `__expected`,
+ * which is the expected value of the int.
  *
- * @param __result the pointer to int to be tested
- * @param __expected the pointer to expected value of the int
+ * @param __result the pointer to int to test.
+ * @param __expected the pointer to expected value of the int.
  *
  * @code
  * int x = 1;
@@ -157,16 +169,15 @@
 #define TEST_INT(__result, __expected) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, &int_interface);} while (0)
 
-
-
-
 /**
  * @def TEST_PTR(__result, __expected)
+ *
  * @brief Test pointers
- * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to be tested, and `__expected`, which is the expected value of the pointer.
+ * This macro is used to test pointers. It takes two arguments: `__result`, which is the pointer to test, and `__expected`,
+ * which is the expected value of the pointer.
  *
- * @param __result the pointer to be tested
- * @param __expected the expected value of the pointer
+ * @param __result the pointer to test.
+ * @param __expected the expected value of the pointer.
  *
  * @code
  * int x = 5;
@@ -180,11 +191,13 @@
 
 /**
  * @def TEST_UINT64_T(__result, __expected)
+ *
  * @brief Test 64-bit unsigned integers
- * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`, which is the integer to be tested, and `__expected`, which is the expected value of the integer.
+ * This macro is used to test 64-bit unsigned integers. It takes two arguments: `__result`,
+ * which is the integer to test, and `__expected`, which is the expected value of the integer.
  *
- * @param __result the pointer to integer to be tested
- * @param __expected the pointer to expected value of the integer
+ * @param __result the pointer to integer to test.
+ * @param __expected the pointer to expected value of the integer.
  *
  * @code
  * uint64_t x = 5;
@@ -197,64 +210,28 @@
 
 /**
  * @def TEST_INTERFACE(__result, __expected, __interface)
- * @brief Define a macro on a usertype with the given __interface
+ *
+ * @brief Define a macro on a usertype with the given __interface.
  * This macro is used by the user to define a new test macro on a usertype.
  *
  * @param __result
  * @param __expected
- * @param __interface the usertype interface
+ * @param __interface the interface of the usertype.
  *
  * @code
- * #define TEST_USERTYPE(__result, __expected)
- * TEST_INTERFACE(__result, __expected, usertype_interface)
+ * TestInterface usertype_interface = {.compare = ..., .format = ...};
+ * #define TEST_USERTYPE(__result, __expected) \
+ * TEST_INTERFACE(__result, __expected, &usertype_interface)
  * @endcode
  */
 #define TEST_INTERFACE(__result, __expected, __interface) \
     do {__error_counter__ += test(__FILE__, __LINE__, __indentation_level, __result, __expected, __interface);} while(0)
 
-/**
- * @def TEST_T_ARRAY(__test_macro, __size, __results, __expecteds)
- * @brief Test arrays of data
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
-
- * @code
- * int results[3] = {1, 2, 3};
- * int expecteds[3] = {1, 2, 3};
- * TEST_ARRAY(TEST_INT, 3, results, expecteds);
- * @endcode
-*/
-#define TEST_ARRAY(__test_macro, __array_size, __results, __expecteds) \
-    for (unsigned i = 0; i < __array_size; i++) {                      \
-        __test_macro(&__results[i], &__expecteds[i]);                   \
-    }
 
-/**
- * @def TEST_T_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)
- * @brief Test arrays of pointer
- * The macro uses a for loop to iterate through the array and apply the test function to each element.
- *
- * @param __test_macro the test function to be used on each element of the array
- * @param __array_size the number of elements in the array
- * @param __results the array of elements to be tested
- * @param __expecteds the array of expected values
 
- * @code
- * void* array[3];
- * TEST_PTR_ARRAY(TEST_PTR, 3, array, array);
- * @endcode
-*/
-#define TEST_PTR_ARRAY(__test_macro, __array_size, __results, __expecteds)  \
-    for (unsigned int i = 0; i < __array_size; i++) {                     \
-      __test_macro(__results[i], __expecteds[i]);                         \
-    }
-// --------------------------------API_CODE
-// These functions should not be used, only use the previous macros.
 
+// ------------------------------------CODE
+// These functions should not be in use, only the previous macros should be in use.
 
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
@@ -271,10 +248,7 @@
 #define INIT_TEST_FUNCTION() \
   INDENTED_PRINT("%s()\n", __func__);
 
-#define DEFERRED_FILE_ERROR(nb_error) \
-    INDENTED_PRINT("|_Deferred Error : %u\n",nb_error);
-
-#define DEFERRED_FUNCTION_ERROR(nb_error) \
+#define DEFERRED_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
 typedef int (Comparator) (void *, void *);
@@ -285,8 +259,26 @@ typedef struct {
     Formatter *format;
 } TestInterface;
 
-//  ---------------------------str_interface
+// ---------------------------TEST FUNCTION
+
+int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
+{
+    __indentation_level += 1;
+    static char buffer_result[FMT_BUFFER_SIZE];
+    static char buffer_expected[FMT_BUFFER_SIZE];
+    int is_equal = interface->compare(result, expected);
+
+    char *fmt_result = interface->format(buffer_expected, expected);
+    char *fmt_expected = interface->format(buffer_result, result);
+    if  (!is_equal) {
+        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
+    }
+    return !is_equal;
+}
+
+// ------------------------------INTERFACES
 
+// -- str_interface
 int str_compare(void *ptr1, void *ptr2)
 {
     char *str1 = (char *) ptr1;
@@ -314,7 +306,7 @@ static const TestInterface str_interface = {
     .format = str_format
 };
 
-//  --------------------------bool_interface
+// -- bool_interface
 
 int bool_compare(void *ptr1, void *ptr2)
 {
@@ -335,7 +327,7 @@ static const TestInterface bool_interface = {
     .format = bool_format
 };
 
-// ---------------------------int_interface
+// -- int_interface
 
 int int_compare(void *ptr1, void *ptr2)
 {
@@ -356,7 +348,7 @@ static const TestInterface int_interface = {
     .format = int_format
 };
 
-// ---------------------------ptr_interface
+// -- ptr_interface
 
 int ptr_compare(void *ptr1, void *ptr2)
 {
@@ -374,7 +366,7 @@ static const TestInterface ptr_interface = {
     .format = ptr_format
 };
 
-// ---------------------------u64_interface
+// -- u64_interface
 
 int u64_compare(void *ptr1, void *ptr2)
 {
@@ -395,22 +387,5 @@ static const TestInterface u64_interface = {
     .format = u64_format
 };
 
-// ---------------------------test_function
-
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
-{
-    __indentation_level += 1;
-    static char buffer_result[FMT_BUFFER_SIZE];
-    static char buffer_expected[FMT_BUFFER_SIZE];
-    int is_equal = interface->compare(result, expected);
-
-    char *fmt_result = interface->format(buffer_expected, expected);
-    char *fmt_expected = interface->format(buffer_result, result);
-    if  (!is_equal) {
-        INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
-    }
-    return !is_equal;
-}
-
 #endif
 
-- 
GitLab


From 585fa51e2a9f1d181ccd1bc10f2ac3deba544a3b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:58:49 +0000
Subject: [PATCH 140/229] format

---
 doc/test_file_ex.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/doc/test_file_ex.c b/doc/test_file_ex.c
index 95baaa7..0595e9a 100644
--- a/doc/test_file_ex.c
+++ b/doc/test_file_ex.c
@@ -20,7 +20,7 @@
 
 // Include of the test library
 #include "./../tests/small_test.h"
-// Include the file that contains the function you want to test 
+// Include the file that contains the function you want to test
 // #include "a_file.c"
 
 // This example is divided into three parts:
@@ -58,7 +58,8 @@ TFUNCTION(test_array, {
     static unsigned int size = 10;
     int results[10] = {0};
     int expecteds[10] = {0};
-    for (unsigned int i = 0; i < size; i++) {
+    for (unsigned int i = 0; i < size; i++)
+    {
         TEST_INT(&results[i], &expecteds[i]);
     }
 })
@@ -134,7 +135,8 @@ TFUNCTION(test_array_user_type, {
     DUMMY_USER_TYPE(results[0], 1, "John Doe");
     DUMMY_USER_TYPE(expecteds[0], 1, "John Doe");
 
-    for (unsigned int i = 0; i < 1; i++) {
+    for (unsigned int i = 0; i < 1; i++)
+    {
         TEST_USER_TYPE(&results[i], &expecteds[i]);
     }
 })
-- 
GitLab


From bea62d235a126b799dd3e05692903e27cc7129ed Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 07:59:19 +0000
Subject: [PATCH 141/229] fix: use a const

---
 src/load.c | 24 +++++++++++++-----------
 1 file changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/load.c b/src/load.c
index 6dcf2b0..1c049ce 100644
--- a/src/load.c
+++ b/src/load.c
@@ -26,11 +26,12 @@
 #include "util.h"
 
 #define LOAD_BUFFER_SIZE 1024
+#define LOAD_VALUES_SIZE 10
 char buffer[LOAD_BUFFER_SIZE];
 
 static int load_fid = -1;
-static uint64_t load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-static uint64_t tmp_load_values[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint64_t tmp_load_values[LOAD_VALUES_SIZE] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
 static char *stat = "/proc/stat";
 
 void _get_load(uint64_t *results)
@@ -46,8 +47,8 @@ void _get_load(uint64_t *results)
         pos++;
     }
 
-    for (int i = 0; i < 10; i++) {
-        results[i] = strtoull(buffer + pos, NULL, 10);
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
+        results[i] = strtoull(buffer + pos, NULL, LOAD_VALUES_SIZE);
 
         while (buffer[pos] <= '9' && buffer[pos] >= '0') {
             pos++;
@@ -71,7 +72,7 @@ unsigned int init_load(char *argument, void **state)
     }
 
     _get_load(load_values);
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 unsigned int get_load(uint64_t *results, void *state)
@@ -79,12 +80,12 @@ unsigned int get_load(uint64_t *results, void *state)
     UNUSED(state);
     _get_load(tmp_load_values);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         results[i] = tmp_load_values[i] - load_values[i];
     }
 
     memcpy(load_values, tmp_load_values, sizeof(load_values));
-    return 10;
+    return LOAD_VALUES_SIZE;
 }
 
 void clean_load(void *state)
@@ -93,14 +94,15 @@ void clean_load(void *state)
     close(load_fid);
 }
 
-char *_labels[10] = {"user", "nice", "system", "idle", "iowait", "irq",
-                     "softirq", "steal", "guest", "guest_nice"
-                    };
+char *_labels[LOAD_VALUES_SIZE] = {
+    "user", "nice", "system", "idle", "iowait", "irq",
+    "softirq", "steal", "guest", "guest_nice"
+};
 void label_load(char **labels, void *none)
 {
     UNUSED(none);
 
-    for (int i = 0; i < 10; i++) {
+    for (int i = 0; i < LOAD_VALUES_SIZE; i++) {
         labels[i] = _labels[i];
     }
 }
-- 
GitLab


From fa47271704f8d2fe67a86d94b8746c8d39eb527d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:17:33 +0000
Subject: [PATCH 142/229] cleanup

---
 doc/info_reader_ex.c | 54 ++++++++++++++++++++++++++++++--------------
 src/info_reader.h    |  8 +++----
 2 files changed, 41 insertions(+), 21 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index f672d98..2e76251 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -23,8 +23,8 @@
 #include "./../src/info_reader.h"
 
 #define MAX_PROCS 64
-#define NB_KEYS 6
 
+// -----------------------------The storage
 typedef struct {
     unsigned int processor;
     char *vendor_id;
@@ -34,12 +34,16 @@ typedef struct {
     char *model_name;
 } Cpu;
 
+// --------------IMPLEMENTING THE INTERFACE
+
+// -- Define the behaviour if the attempted value is an int
 GenericPointer int_allocator(char *s)
 {
     unsigned int value = atoi(s);
     return (GenericPointer) value;
 }
 
+// -- Define the behaviour if the attempted value is a string
 GenericPointer string_allocator(char *s)
 {
     char *value = malloc(strlen(s) + 1);
@@ -47,31 +51,42 @@ GenericPointer string_allocator(char *s)
     return (GenericPointer) value;
 }
 
+// -- Define the processor setter
 void set_processor(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->processor = data;
 }
+
+// -- Define the vendor_id setter
 void set_vendor_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->vendor_id = (char *) data;
 }
+
+// -- Define the family setter
 void set_family(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->family = data;
 }
+
+// -- Define the core_id setter
 void set_core_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->core_id = data;
 }
+
+// -- Define the physical_id setter
 void set_physical_id(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
     cpu->physical_id = data;
 }
+
+// -- Define the model_name setter
 void set_model_name(GenericPointer storage, GenericPointer data)
 {
     Cpu *cpu = (Cpu *) storage;
@@ -81,28 +96,33 @@ void set_model_name(GenericPointer storage, GenericPointer data)
 int main()
 {
     Cpu cpus[MAX_PROCS];
+
+    // -- Define the setter, the allocator for each key / separator.
     KeyFinder keys[] = {
-        {"processor", ": ", (CopyAllocator *) int_allocator, (Setter *)set_processor},
-        {"vendor_id", ": ", (CopyAllocator *) string_allocator, (Setter *)set_vendor_id},
-        {"cpu family", ": ", (CopyAllocator *) int_allocator, (Setter *)set_family},
-        {"core id", ": ", (CopyAllocator *) int_allocator, (Setter *)set_core_id},
-        {"physical id", ": ", (CopyAllocator *) int_allocator,(Setter *)set_physical_id},
-        {
-            "model name", ": ", (CopyAllocator *) string_allocator,
-            (Setter *)set_model_name
-        }
+        {.key = "processor", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_processor},
+        {.key = "vendor_id", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_vendor_id},
+        {.key = "cpu family", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_family},
+        {.key = "core id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_core_id},
+        {.key = "physical id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_physical_id},
+        {.key = "model name", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_model_name}
     };
 
-    Parser parser = {.storage = (GenericPointer) cpus,
-                     .capacity = MAX_PROCS,
-                     .storage_struct_size = sizeof(Cpu),
-                     .keys = keys,
-                     .nb_keys = NB_KEYS,
-                     .file = fopen("/proc/cpuinfo", "r")
-                    };
+    size_t nb_keys = sizeof(keys)/sizeof(KeyFinder);
+
+    // -- Init the parser
+    Parser parser = {
+        .storage = (GenericPointer) cpus,
+        .capacity = MAX_PROCS,
+        .storage_struct_size = sizeof(Cpu),
+        .keys = keys,
+        .nb_keys = nb_keys,
+        .file = fopen("/proc/cpuinfo", "r")
+    };
 
+    // -- Parse the file
     parse(&parser);
 
+    // Print and free the results
     for (unsigned int i = 0; i < parser.nb_stored; ++i) {
         printf("========== PROC[%d] ==========\n", i);
         printf("Processor: %u\n", cpus[i].processor);
diff --git a/src/info_reader.h b/src/info_reader.h
index e83b2c3..0d694d3 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -96,10 +96,10 @@ static bool start_with(const char *prefix, const char *string);
 /**
  * @brief Matches a line of text to a key in the parser's list of keys.
  *
- * @param parser Pointer to the Parser struct.
- * @param line Line of text to match.
- * @param key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
- * @param raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
+ * @param[in] parser Pointer to the Parser struct.
+ * @param[in] line Line of text to match.
+ * @param[out] key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
+ * @param[out] raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
  *
  * @return Returns 1 if a key is matched, 0 otherwise.
  */
-- 
GitLab


From 402140300f756114e7ed4f18fd4692b9b5e6aae4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:25:30 +0000
Subject: [PATCH 143/229] format

---
 tests/small_test.h | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index abae768..bf0ca10 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -39,15 +39,15 @@
  * @param __code The code that contains the calls to the test functions.
  */
 
-#define TMAIN(__code)                                              \
-  int main()                                                     \
-{                                                                \
-  unsigned int __indentation_level = 0;                          \
-  INDENTED_PRINT("%s:%s\n", __FILE__, __func__);                 \
-  unsigned int __error_counter__ = 0;                            \
-  do __code while (0);                                             \
-  DEFERRED_ERROR(__error_counter__);                        \
-  return __error_counter__;                                      \
+#define TMAIN(__code)                            \
+  int main()                                     \
+{                                                \
+  unsigned int __indentation_level = 0;          \
+  INDENTED_PRINT("%s:%s\n", __FILE__, __func__); \
+  unsigned int __error_counter__ = 0;            \
+  do __code while (0);                           \
+  DEFERRED_ERROR(__error_counter__);             \
+  return __error_counter__;                      \
 }
 
 /**
@@ -72,7 +72,7 @@
   INIT_TEST_FILE();                                 \
   int __error_counter__ = 0;                        \
   do __code while(0);                               \
-  DEFERRED_ERROR(__error_counter__);           \
+  DEFERRED_ERROR(__error_counter__);                \
   return __error_counter__;                         \
 }
 
@@ -91,14 +91,14 @@
  * @param __function_name The name of the test function.
  * @param __code The test code to be executed in the function.
  */
-#define TFUNCTION(__function_name, __code) \
+#define TFUNCTION(__function_name, __code)              \
   int __function_name(unsigned int __indentation_level) \
-{ \
-  INIT_TEST_FUNCTION(); \
-  int __error_counter__ = 0; \
-  do __code while(0); \
-  DEFERRED_ERROR(__error_counter__); \
-  return __error_counter__; \
+{                                                       \
+  INIT_TEST_FUNCTION();                                 \
+  int __error_counter__ = 0;                            \
+  do __code while(0);                                   \
+  DEFERRED_ERROR(__error_counter__);                    \
+  return __error_counter__;                             \
 }
 
 /**
@@ -236,13 +236,13 @@
 #define INDENTED_PRINT(__fmt, ...)                          \
   do {                                                      \
     for(unsigned int i = 0; i < __indentation_level; i++) { \
-      printf("|    ");                                       \
+      printf("|    ");                                      \
     }                                                       \
     printf(__fmt, ##__VA_ARGS__);                           \
   } while(0)
 
 
-#define INIT_TEST_FILE()     \
+#define INIT_TEST_FILE() \
   INDENTED_PRINT("%s:%s\n", __FILE__, __func__)
 
 #define INIT_TEST_FUNCTION() \
-- 
GitLab


From 4b22f61991d079ebfce3c387d4ceae227a57ed47 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:26:24 +0000
Subject: [PATCH 144/229] doc

---
 tests/small_test.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/tests/small_test.h b/tests/small_test.h
index bf0ca10..66c4de9 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -33,6 +33,8 @@
 
 // ---------------------------API_INTERFACE
 /**
+ * @def TMAIN(__code)
+ *
  * @brief Define the entry point for the tests.
  * It initialises any useful variables and acts as the main one.
  *
-- 
GitLab


From f29c9ade9da41bc824c40c59b4ce0e48e79c13fb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 08:35:54 +0000
Subject: [PATCH 145/229] fix: header

---
 src/info_reader.h   | 2 +-
 tests/info_reader.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/info_reader.h b/src/info_reader.h
index 0d694d3..ec28db6 100644
--- a/src/info_reader.h
+++ b/src/info_reader.h
@@ -19,7 +19,7 @@
 *******************************************************/
 
 #ifndef _INFO_READER_H
-#define _INFO_READER_
+#define _INFO_READER_H
 
 #include <string.h>
 #include <stdbool.h>
diff --git a/tests/info_reader.c b/tests/info_reader.c
index b2a8c6f..19d9c0a 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -19,6 +19,7 @@
 *******************************************************/
 
 #include "small_test.h"
+#include "./../src/info_reader.h"
 
 TFUNCTION(test_replace_first, {
     // useful variables :
-- 
GitLab


From 8aeab626fdda56b5090c4b88ae6ca46631509491 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 12:39:47 +0100
Subject: [PATCH 146/229] build: support for multiple options per captor

- Makefile now includes captors.mk which defines captor object files to
  build (the previous behaviour was to build all captors regardless of
  the captor selection during configuration)
- correct a bug in configure.sh : now properly detect amd cpu family
- configure.sh now print an error when 0 captors are selected
- configure.sh now do a `make clean` on successful configuration
---
 .gitignore        |  21 +++++-----
 configure.sh      |  71 ++++++++++++++++++++++++--------
 makefile          |  14 +++----
 src/amd_rapl.h    |  16 ++++++--
 src/counters.h    |  29 +++++++++----
 src/infiniband.h  |  17 ++++++--
 src/load.h        |  16 ++++++--
 src/mojitos.c     | 101 ++++++++++++++++++++++++++++++----------------
 src/network.h     |  15 +++++--
 src/optparse.h    |   2 +
 src/rapl.h        |  16 ++++++--
 src/temperature.h |  16 ++++++--
 12 files changed, 234 insertions(+), 100 deletions(-)

diff --git a/.gitignore b/.gitignore
index dd136f4..6643912 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,11 @@
-src/counters_option.h
-src/captors.h
-tests/run
-bin
-obj
-*.swp
-*.swo
-.vscode
-doc/test_main_ex
-doc/info_reader_ex
+doc/test_main_ex
+doc/info_reader_ex
+tests/run
+src/counters_option.h
+src/sensors.h
+captors.mk
+bin
+obj
+*.swp
+*.swo
+.vscode
diff --git a/configure.sh b/configure.sh
index 2d21bf5..49e1789 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,7 +20,8 @@ decho() {
 }
 
 debug=0
-target=src/captors.h
+target_hdr=src/captors.h
+target_mk=captors.mk
 
 noncaptor='counters_option|optparse|captors|util|info_reader'
 
@@ -41,8 +42,8 @@ ls_captors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
-	dprint hdr_blacklist
-	dprint hdr_whitelist
+	dprint hdr_blacklist >&2
+	dprint hdr_whitelist >&2
 
 	ls -1 *.h |
 		grep -xEv "($hdr_blacklist)\.h" |
@@ -50,31 +51,53 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
+# gen_captors_h(captors, nb_captors)
 gen_captors_h() {
-	captors=$(ls_captors)
-	nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
-	printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-	printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-	echo "$captors" >&2
-
-	[ -n "$captors" ] || return
+	captors=$1
+	nb_captors=$2
+	nb_captor_opts=$(
+		for captor in $captors; do
+			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+		done |
+			paste -s -d '+' |
+			bc
+	)
+
+	dprint captors >&2
+	dprint nb_captor_opts >&2
+	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
 
 	# gen includes
 	for captor in $captors; do
 		printf '#include "%s.h"\n' "$captor"
 	done
-	printf '\n#define NB_CAPTORS %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
+	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
 
 	# gen `init_captors()`
-	printf 'void init_captors(struct optparse_long *longopts, struct captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	printf '    int opt_idx = offset;\n'
 	for captor in $captors; do
-		printf '    longopts[offset + *nb_defined] = %s_opt;\n' "$captor"
-		printf '    captors[(*nb_defined)++] = %s;\n' "$captor"
+		cat <<-!
+		    for (int i = 0; i < ${captor}.nb_opt; i++) {
+		        longopts[opt_idx++] = ${captor}_opt[i];
+		    }
+		    captors[(*nb_defined)++] = ${captor};
+		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
+gen_captors_mk() {
+	captors=$1
+	printf 'CAPTOR_OBJ = '
+	for captor in $captors; do
+		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	done
+	printf '\n'
+}
+
 detect_caps() {
 	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
 	[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
@@ -92,7 +115,7 @@ detect_caps() {
 		hdr_whitelist="${hdr_whitelist}|rapl"
 		;;
 	*amd*)
-		family=$(awk '/cpu[ \t]*family/ {print $3; exit}' /proc/cpuinfo)
+		family=$(awk '/cpu[ \t]*family/ {print $4; exit}' /proc/cpuinfo)
 		if isnum "$family"; then
 			[ $family -ge 17 ] && hdr_whitelist="${hdr_whitelist}|amd_rapl"
 		fi
@@ -132,4 +155,20 @@ while [ "$1" ]; do
 	shift
 done
 
-gen_captors_h > "$target"
+captors=$(ls_captors)
+nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+
+if [ "$nb_captors" -eq 0 ]; then
+	printf -- '0 captors are selected. cannot build.\n' >&2
+	exit 1
+fi
+
+try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
+try gen_captors_mk "$captors" > "$target_mk"
+
+printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
+printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
+echo "$captors" >&2
+
+make clean >/dev/null
+
diff --git a/makefile b/makefile
index eabffaf..3f8a70b 100644
--- a/makefile
+++ b/makefile
@@ -8,15 +8,13 @@ TESTS_DIR = tests
 
 BIN = mojitos
 
+CAPTOR_OBJ =
+
+include ./captors.mk
+
 OBJ =  \
-	$(OBJ_DIR)/counters.o \
-	$(OBJ_DIR)/rapl.o \
-	$(OBJ_DIR)/network.o \
-	$(OBJ_DIR)/load.o \
-	$(OBJ_DIR)/infiniband.o \
-	$(OBJ_DIR)/temperature.o \
-	$(OBJ_DIR)/util.o \
-	$(OBJ_DIR)/amd_rapl.o 
+	$(CAPTOR_OBJ) \
+	$(OBJ_DIR)/util.o
 
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index f16ed4f..52a7c6c 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,12 +23,20 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-struct optparse_long amd_rapl_opt = {"amd_rapl", 'a', OPTPARSE_NONE};
-struct captor amd_rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "AMD_RAPL",
+Captor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
     .label = label_amd_rapl,
+    .nb_opt = 1,
+};
+
+Optparse amd_rapl_opt[1] = {
+    {
+        .longname = "amd-rapl",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "AMD RAPL",
+    },
 };
diff --git a/src/counters.h b/src/counters.h
index 313feeb..a191e5a 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,17 +22,32 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
+void show_all_counters();
 
-struct optparse_long counters_opt = {"perf-list", 'p', OPTPARSE_REQUIRED};
-struct captor counters = {
-    .usage_arg = "<perf_list>",
-    .usage_msg = "performance counters\n"
-    "\tperf_list is a coma separated list of performance counters.\n"
-    "\tEx: instructions,cache_misses",
+Captor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
     .label = label_counters,
+    .nb_opt = 2,
+};
+
+Optparse counters_opt[2] = {
+    {
+        .longname = "perf-list",
+        .shortname = 'p',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<perf_list>",
+        .usage_msg = "performance counters\n"
+        "\tperf_list is a coma separated list of performance counters.\n"
+        "\tEx: instructions,cache_misses",
+    },
+    {
+        .longname = "list",
+        .shortname = 'l',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "list the possible performance counters and quit"
+    },
 };
 
-void show_all_counters();
diff --git a/src/infiniband.h b/src/infiniband.h
index 0f1ad11..285b2ba 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,12 +21,21 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-struct optparse_long infiniband_opt = {"monitor-infiniband", 'i', OPTPARSE_REQUIRED};
-struct captor infiniband = {
-    .usage_arg = "<infiniband_path>",
-    .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+Captor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
     .label = label_infiniband,
+    .nb_opt = 1,
 };
+
+Optparse infiniband_opt[1] = {
+    {
+        .longname = "monitor-infiniband",
+        .shortname = 'i',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<infiniband_path>",
+        .usage_msg = "infiniband monitoring (if infiniband_path is X, tries to detect it automatically)",
+    },
+};
+
diff --git a/src/load.h b/src/load.h
index 366e448..c7c5575 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,12 +23,20 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-struct optparse_long load_opt = {"sysload", 'u', OPTPARSE_NONE};
-struct captor load = {
-    .usage_arg = NULL,
-    .usage_msg = "system load",
+Captor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
     .label = label_load,
+    .nb_opt = 1,
+};
+
+Optparse load_opt[1] = {
+    {
+        .longname = "sysload",
+        .shortname = 'u',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "system load",
+    },
 };
diff --git a/src/mojitos.c b/src/mojitos.c
index dc113fc..683bdfa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -37,44 +37,75 @@ typedef void (*labeler_t)(char **, void *);
 typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
-struct captor {
-    char *usage_arg;
-    char *usage_msg;
+typedef struct Opt Opt;
+typedef struct Captor Captor;
+/* optparse typedef */
+typedef struct optparse_long Optparse;
+
+struct Captor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
     labeler_t label;
+    int nb_opt;
 };
 
 int nb_defined_captors = 0;
 
 #include "captors.h"
 
-struct captor captors[NB_CAPTORS];
-
-#define NB_OPTS 6
-struct optparse_long longopts[NB_OPTS + NB_CAPTORS + 1] = {
-    {"overhead-stats", 's', OPTPARSE_NONE},
-    {"list", 'l', OPTPARSE_NONE},
-    {"freq", 'f', OPTPARSE_REQUIRED},
-    {"time", 't', OPTPARSE_REQUIRED},
-    {"exec", 'e', OPTPARSE_REQUIRED},
-    {"logfile", 'o', OPTPARSE_REQUIRED},
+Captor captors[NB_CAPTOR];
+
+#define NB_OPT 5
+Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+    {
+        .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<freq>",
+        .usage_msg = "specify frequency",
+    },
+    {
+        .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<time>",
+        .usage_msg = "specify time",
+    },
+    {
+        .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<cmd>",
+        .usage_msg = "specify a command",
+    },
+    {
+        .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<file>",
+        .usage_msg = "specify a log file",
+    },
+    {
+        .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "enable overhead statistics in nanoseconds",
+    },
 };
 
 
+void printopt(Optparse *opt)
+{
+    printf("-%c", opt->shortname);
+    printf("|--%s", opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" %s", opt->usage_arg);
+    }
+    printf("\n\t%s\n", opt->usage_msg);
+}
+
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...] [-o logfile] [-e cmd ...]\n"
-           "\nOPTIONS:\n"
-           "-t <time>\t\tspecify time\n"
-           "-f <freq>\t\tspecify frequency\n"
-           "-e <cmd>\t\tspecify a command\n"
-           "-l\t\tlist the possible performance counters and quit\n"
-           "-s\t\tenable overhead statistics in nanoseconds\n"
-           "if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n"
-           , argv[0]);
+    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+
+    printf("\nOPTIONS:\n");
+    for (int i = 0; i < NB_OPT; i++) {
+        printopt(&longopts[i]);
+    }
+    printf("if time==0 then loops infinitively\n"
+           "if -e is present, time and freq are not used\n");
 
     if (nb_defined_captors == 0) {
         // no captor to show
@@ -82,13 +113,8 @@ void usage(char **argv)
     }
 
     printf("\nCAPTORS:\n");
-
-    for (int i = 0; i < nb_defined_captors; i++) {
-        printf("-%c", longopts[NB_OPTS + i].shortname);
-        if (captors[i].usage_arg != NULL) {
-            printf(" %s", captors[i].usage_arg);
-        }
-        printf("\n\t%s\n", captors[i].usage_msg);
+    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
+        printopt(&longopts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -123,7 +149,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(struct captor *cpt, char *arg)
+void add_source(Captor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -160,7 +186,7 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPTS + NB_CAPTORS, NB_OPTS, &nb_defined_captors);
+    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
 
     if (argc == 1) {
         usage(argv);
@@ -207,10 +233,15 @@ int main(int argc, char **argv)
             break;
         default: {
             int ismatch = 0;
+            int opt_idx = NB_OPT;
             for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                if (opt == longopts[NB_OPTS + i].shortname) {
-                    ismatch = 1;
-                    add_source(&captors[i], options.optarg);
+                for (int j = 0; j < captors[i].nb_opt; j++) {
+                    if (opt == longopts[opt_idx].shortname) {
+                        ismatch = 1;
+                        add_source(&captors[i], options.optarg);
+                        break;
+                    }
+                    opt_idx++;
                 }
             }
             if (!ismatch) {
diff --git a/src/network.h b/src/network.h
index 3182587..82fcfc3 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,13 +23,20 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-struct optparse_long network_opt = {"net-dev", 'd', OPTPARSE_REQUIRED};
-struct captor network = {
-    .usage_arg = "<net_dev>",
-    .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+Captor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
     .label = label_network,
+    .nb_opt = 1,
 };
 
+Optparse network_opt[1] = {
+    {
+        .longname = "net-dev",
+        .shortname = 'd',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<net_dev>",
+        .usage_msg = "network monitoring (if network_device is X, tries to detect it automatically)",
+    },
+};
diff --git a/src/optparse.h b/src/optparse.h
index 04e60f6..b1908d4 100644
--- a/src/optparse.h
+++ b/src/optparse.h
@@ -71,6 +71,8 @@ struct optparse_long {
     const char *longname;
     int shortname;
     enum optparse_argtype argtype;
+    char *usage_arg;
+    char *usage_msg;
 };
 
 /**
diff --git a/src/rapl.h b/src/rapl.h
index b8dc9a2..95f9fd4 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,13 +23,21 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-struct optparse_long rapl_opt = {"rapl", 'r', OPTPARSE_NONE};
-struct captor rapl = {
-    .usage_arg = NULL,
-    .usage_msg = "RAPL",
+Captor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
     .label = label_rapl,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "rapl",
+        .shortname = 'r',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "RAPL",
+    },
 };
 
diff --git a/src/temperature.h b/src/temperature.h
index 5e8046e..ec2faef 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,12 +23,20 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-struct optparse_long temperature_opt = {"cpu-temp", 'c', OPTPARSE_NONE};
-struct captor temperature = {
-    .usage_arg = NULL,
-    .usage_msg = "processor temperature",
+Captor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
     .label = label_temperature,
+    .nb_opt = 1,
+};
+
+Optparse temperature_opt[1] = {
+    {
+        .longname = "cpu-temp",
+        .shortname = 'c',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "processor temperature"
+    },
 };
-- 
GitLab


From ea44320719bf3b4c74772dc732535ae1e45e214b Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 13:05:29 +0100
Subject: [PATCH 147/229] update documentation (doc/counter_ex.h)

---
 doc/counter_ex.h | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 4ab7915..5702adc 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,12 +7,20 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-struct optparse_long counters_opt = {"accumulator", 'a', OPTPARSE_NONE};
-struct captor counters = {
-    .usage_arg = NULL,
-    .usage_msg = "dumb accumulator\n"
+Captor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
     .label = label_acc,
+    .nb_opt = 1,
+};
+
+Optparse rapl_opt[1] = {
+    {
+        .longname = "accumulator",
+        .shortname = 'a',
+        .argtype = OPTPARSE_NONE,		/* OPTPARSE_NONE / OPTPARSE_OPTIONAL / OPTPARSE_REQUIRED */
+        .usage_arg = NULL,
+        .usage_msg = "dumb accumulator",
+    },
 };
-- 
GitLab


From 569f527a427531691dee1b9e305cab5d4b6d00f8 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 31 Jan 2023 17:32:40 +0100
Subject: [PATCH 148/229] Add a generation system for README.md and
 doc/mojitos.1

- README.md can be updated via `make readme`
- doc/mojitos.1 can be generated via `make man`
- README.md is updated and doc/mojitos.1 generated on `make all`
- correct wrong translation "captor", to "sensor"
- update README.md build instructions
- mv src/optparse.h and src/info_reader.h to ./lib/
- add the possibility to execute an alternative function when parsing
  sensor options (other than `add_source()`)
---
 .gitignore                       |  3 +-
 README.md                        | 75 +++++++++++++-------------
 configure.sh                     | 91 ++++++++++++++++---------------
 doc/counter_ex.h                 |  2 +-
 doc/{mojitos.1 => mojitos.pre.1} | 41 +++-----------
 {src => lib}/info_reader.h       |  0
 {src => lib}/optparse.h          |  1 +
 makefile                         | 18 +++++--
 src/amd_rapl.h                   |  2 +-
 src/counters.c                   |  6 ++-
 src/counters.h                   |  7 +--
 src/infiniband.h                 |  2 +-
 src/load.h                       |  2 +-
 src/mojitos.c                    | 93 +++++++++++++++++++++-----------
 src/network.h                    |  2 +-
 src/rapl.h                       |  2 +-
 src/temperature.h                |  2 +-
 tools/update-readme-usage.sh     | 27 ++++++++++
 18 files changed, 213 insertions(+), 163 deletions(-)
 rename doc/{mojitos.1 => mojitos.pre.1} (69%)
 rename {src => lib}/info_reader.h (100%)
 rename {src => lib}/optparse.h (99%)
 create mode 100755 tools/update-readme-usage.sh

diff --git a/.gitignore b/.gitignore
index 6643912..31260f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,9 +1,10 @@
 doc/test_main_ex
 doc/info_reader_ex
+doc/mojitos.1
 tests/run
 src/counters_option.h
 src/sensors.h
-captors.mk
+sensors.mk
 bin
 obj
 *.swp
diff --git a/README.md b/README.md
index 6422ce0..10f5aaf 100644
--- a/README.md
+++ b/README.md
@@ -6,51 +6,52 @@ MojitO/S runs on GNU/Linux
 ## Usage
 
 ```bash
-Usage : mojitos [-rsu] [-t time] [-f freq] [-p perf_list]  \
-                [-d network_device] [-o logfile] [-e command arguments...]
-        mojitos [-l]
-
-     -s      Enable overhead statistics (in nanoseconds).
-
-     -u      Enable system-level load monitoring.
-
-     -r      Enable RAPL.
-
-     -p perf_list
-             Enable performance counters.  The argument is a coma separated
-             list of performance counters.
-
-     -d net_device
-             Enable network monitoring.
-
-     -l      List the available performance counters and quit.
-
-     -t time
-             Set duration value (in seconds). If 0, then loops indefinitely.
-
-     -f freq
-             Set amount of measurements per second.
-
-     -e cmd ...
-             Execute a command with optional arguments.  If this option is
-             used, any usage of -t or -f is ignored.
+Usage : ./bin/mojitos [OPTIONS] [SENSOR ...] [-e <cmd> ...]
+
+OPTIONS:
+-f|--freq <freq>
+	set amount of measurements per second.
+-t|--time <time>
+	set duration value (seconds). If 0, then loops infinitely.
+-e|--exec <cmd> ...
+	Execute a command with optional arguments.
+	If this option is used, any usage of -t or -f is ignored.
+-o|--logfile <file>
+	specify a log file.
+-s|--overhead-stats
+	enable overhead statistics (nanoseconds).
+
+SENSORS:
+-p|--perf-list <perf_list>
+	performance counters
+	perf_list is a coma separated list of performance counters.
+	Ex: instructions,cache_misses
+-l|--list
+	list the available performance counters and quit
+-u|--sysload
+	system load
+-d|--net-dev <net_dev>
+	network monitoring (if network_device is X, tries to detect it automatically)
+-r|--rapl
+	RAPL
+-c|--cpu-temp
+	processor temperature
 ```
 
 ## Installation Instructions
 
-Dependencies
-```bash
-sudo apt install libpowercap0 libpowercap-dev powercap-utils python3
-```
 Download the source code
 ```bash
 git clone https://gitlab.irit.fr/sepia-pub/mojitos.git
 ```
-Compile the code
+The quickest way to compile the code is:
 ```bash
 cd mojitos
+./configure.sh
 make
 ```
+You may want to run `./configure.sh --help` to see configuration options.
+
 To execute mojitos without being root to monitor performance counters
 ```bash
 sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
@@ -65,7 +66,7 @@ sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
 
 RAPL values during 2 seconds with a frequency of 2 Hz
 ```bash
-$ ./mojitos -t 2 -f 2 -r
+$ ./bin/mojitos -t 2 -f 2 -r
 #timestamp package-00 core0 dram0
 1036389.135659868 10986 2869 1526
 1036389.500183551 1291440 255736 515562
@@ -75,7 +76,7 @@ $ ./mojitos -t 2 -f 2 -r
 Performance counters (cpu_cycle, cache_ll_r_a and page_faults) during 4 seconds with a frequency of 1Hz. For cache performance counters, _r and _w are respectively read and write, and _a, _m and _p are respectively access, miss, pending.
 
 ```bash
-$ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
+$ ./bin/mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 #timestamp cpu_cycles cache_ll page_faults
 1036846.351749455 571199 1232 0
 1036847.001098880 348173344 2451387 872
@@ -85,7 +86,7 @@ $ ./mojitos -t 4 -f 1 -p cpu_cycles,cache_ll_r_a,page_faults
 
 Network values with no time limit with a frequency of 1Hz. rxp and txp are the number of received and sent packets, while rxb and txp are the number of received and sent bytes.
 ```bash
-$ ./mojitos -t 0 -f 1 -d enp0s25
+$ ./bin/mojitos -t 0 -f 1 -d enp0s25
 #timestamp rxp rxb txp txb
 1036559.277376027 0 0 0 0
 1036560.000161101 4 581 2 179
@@ -97,7 +98,7 @@ $ ./mojitos -t 0 -f 1 -d enp0s25
 
 Overhead of the monitoring for RAPL and cpu_cycle
 ```bash
-$ ./mojitos -t 5 -f 1 -p cpu_cycles -r -s
+$ ./bin/mojitos -t 5 -f 1 -p cpu_cycles -r -s
 #timestamp cpu_cycles package-00 core0 dram0 overhead
 1036988.197227391 162214 19898 4944 1586 149612
 1036989.000151326 332613664 2513116 379577 1115171 739573
diff --git a/configure.sh b/configure.sh
index 49e1789..62f297a 100755
--- a/configure.sh
+++ b/configure.sh
@@ -20,25 +20,25 @@ decho() {
 }
 
 debug=0
-target_hdr=src/captors.h
-target_mk=captors.mk
+target_hdr=src/sensors.h
+target_mk=sensors.mk
 
-noncaptor='counters_option|optparse|captors|util|info_reader'
+nonsensor='counters_option|optparse|sensors|util|info_reader'
 
-hdr_blacklist=$noncaptor
+hdr_blacklist=$nonsensor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <captor>] [-i <captor>] [-u <captor>]\n' "$(basename "$0")" >&2
-	printf -- '-e | --exclude      :   exclude captor, can be called multiple times\n' >&2
-	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
-	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
-	printf -- '-u | --unique       :   only include the specified captor\n' >&2
+	printf -- 'Usage: %s [-l] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
+	printf -- '-e | --exclude      :   exclude sensor, can be called multiple times\n' >&2
+	printf -- '-i | --include      :   include sensor, can be called multiple times\n' >&2
+	printf -- '-l | --list-sensors :   list all sensors and exit\n' >&2
+	printf -- '-u | --unique       :   only include the specified sensor\n' >&2
 	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
 	exit 1
 }
 
-ls_captors() {
+ls_sensors() {
 	try cd src
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
@@ -51,49 +51,52 @@ ls_captors() {
 		sed 's/\.h$//'
 }
 
-# gen_captors_h(captors, nb_captors)
-gen_captors_h() {
-	captors=$1
-	nb_captors=$2
-	nb_captor_opts=$(
-		for captor in $captors; do
-			sed -n 's/.*'"${captor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${captor}.h"
+# gen_sensors_h(sensor, nb_sensors)
+gen_sensors_h() {
+	sensors=$1
+	nb_sensors=$2
+	nb_sensor_opts=$(
+		for sensor in $sensors; do
+			sed -n 's/.*'"${sensor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${sensor}.h"
 		done |
 			paste -s -d '+' |
 			bc
 	)
 
-	dprint captors >&2
-	dprint nb_captor_opts >&2
-	isnum "$nb_captor_opts" || die "could not get total number of captors's command-line options"
+	dprint sensors >&2
+	dprint nb_sensor_opts >&2
+	isnum "$nb_sensor_opts" || die "could not get total number of sensors's command-line options"
 
 	# gen includes
-	for captor in $captors; do
-		printf '#include "%s.h"\n' "$captor"
+	for sensor in $sensors; do
+		printf '#include "%s.h"\n' "$sensor"
 	done
-	printf '\n#define NB_CAPTOR %d\n\n' "$nb_captors"
-	printf '\n#define NB_CAPTOR_OPT %d\n\n' "$nb_captor_opts"
+	printf '\n'
+
+	printf '#define NB_SENSOR %d\n' "$nb_sensors"
+	printf '#define NB_SENSOR_OPT %d\n' "$nb_sensor_opts"
+	printf '\n'
 
-	# gen `init_captors()`
-	printf 'void init_captors(Optparse *longopts, Captor *captors, size_t len, size_t offset, int *nb_defined)\n{\n'
+	# gen `init_sensors()`
+	printf 'void init_sensors(Optparse *opts, Sensor *sensors, size_t len, size_t offset, int *nb_defined)\n{\n'
 	printf '    int opt_idx = offset;\n'
-	for captor in $captors; do
+	for sensor in $sensors; do
 		cat <<-!
-		    for (int i = 0; i < ${captor}.nb_opt; i++) {
-		        longopts[opt_idx++] = ${captor}_opt[i];
+		    for (int i = 0; i < ${sensor}.nb_opt; i++) {
+		        opts[opt_idx++] = ${sensor}_opt[i];
 		    }
-		    captors[(*nb_defined)++] = ${captor};
+		    sensors[(*nb_defined)++] = ${sensor};
 		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
 	printf '}\n'
 }
 
-gen_captors_mk() {
-	captors=$1
+gen_sensors_mk() {
+	sensors=$1
 	printf 'CAPTOR_OBJ = '
-	for captor in $captors; do
-		printf '$(OBJ_DIR)/%s.o ' "$captor"
+	for sensor in $sensors; do
+		printf '$(OBJ_DIR)/%s.o ' "$sensor"
 	done
 	printf '\n'
 }
@@ -140,8 +143,8 @@ while [ "$1" ]; do
 		shift; [ "$1" ] || usage
 		hdr_blacklist="${hdr_blacklist}|${1}"
 		;;
-	--list-captors|-l)
-		ls_captors
+	--list-sensors|-l)
+		ls_sensors
 		exit 0
 		;;
 	--unique|-u)
@@ -155,20 +158,20 @@ while [ "$1" ]; do
 	shift
 done
 
-captors=$(ls_captors)
-nb_captors=$(echo "$captors" | sed '/^$/d' | wc -l)
+sensors=$(ls_sensors)
+nb_sensors=$(echo "$sensors" | sed '/^$/d' | wc -l)
 
-if [ "$nb_captors" -eq 0 ]; then
-	printf -- '0 captors are selected. cannot build.\n' >&2
+if [ "$nb_sensors" -eq 0 ]; then
+	printf -- '0 sensors are selected. cannot build.\n' >&2
 	exit 1
 fi
 
-try gen_captors_h "$captors" "$nb_captors" > "$target_hdr"
-try gen_captors_mk "$captors" > "$target_mk"
+try gen_sensors_h "$sensors" "$nb_sensors" > "$target_hdr"
+try gen_sensors_mk "$sensors" > "$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
-printf -- 'The resulting binary will have the %d following captors:\n' "$nb_captors" >&2
-echo "$captors" >&2
+printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
+echo "$sensors" >&2
 
 make clean >/dev/null
 
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 5702adc..65fabf3 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,7 +7,7 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
diff --git a/doc/mojitos.1 b/doc/mojitos.pre.1
similarity index 69%
rename from doc/mojitos.1
rename to doc/mojitos.pre.1
index a7927e8..af9cb9b 100644
--- a/doc/mojitos.1
+++ b/doc/mojitos.pre.1
@@ -3,47 +3,18 @@
 .Os
 .Sh NAME
 .Nm mojitos
-.Nd An open source system, energy and network monitoring tool.
+.Nd An open source system monitoring tool.
 .Sh SYNOPSIS
 .Nm mojitos
-.Op Fl rsu
-.Op Fl t Ar time
-.Op Fl f Ar freq
-.Op Fl p Ar perf_list
-.Op Fl d Ar net_device
-.Op Fl o Ar logfile
+.Op Ar OPTIONS
+.Op Ar SENSOR ...
 .Op Fl e Ar cmd ...
-.Nm mojitos
-.Op Fl l
 .Sh DESCRIPTION
 .Nm
-enables monitoring the system, its energy comsumption and the network activity, at the OS level.
-It runs on GNU/Linux.
-.Pp
+is a monitoring tool with a multitude of sensors that does measurements at the OS level.
 .Nm
-supports the following options:
-.Bl -tag -width Ds
-.It Fl s
-Enable overhead statistics (in nanoseconds).
-.It Fl u
-Enable system-level load monitoring.
-.It Fl r
-Enable RAPL.
-.It Fl p Ar perf_list
-Enable performance counters.
-The argument is a coma separated list of performance counters.
-.It Fl d Ar net_device
-Enable network monitoring.
-.It Fl l
-List the available performance counters and quit.
-.It Fl t Ar time
-Set duration value (in seconds). If 0, then loops indefinitely.
-.It Fl f Ar freq
-Set amount of measurements per second.
-.It Fl e Ar cmd ...
-Execute a command with optional arguments.
-If this option is used, any usage of -t or -f is ignored.
-.El
+runs on GNU/Linux.
+USAGE
 .Sh EXIT STATUS
 .Ex
 .Sh EXAMPLES
diff --git a/src/info_reader.h b/lib/info_reader.h
similarity index 100%
rename from src/info_reader.h
rename to lib/info_reader.h
diff --git a/src/optparse.h b/lib/optparse.h
similarity index 99%
rename from src/optparse.h
rename to lib/optparse.h
index b1908d4..1925d73 100644
--- a/src/optparse.h
+++ b/lib/optparse.h
@@ -73,6 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
+    void *(*fn)(void *, size_t);
 };
 
 /**
diff --git a/makefile b/makefile
index 3f8a70b..d5d2d23 100644
--- a/makefile
+++ b/makefile
@@ -10,21 +10,21 @@ BIN = mojitos
 
 CAPTOR_OBJ =
 
-include ./captors.mk
+include ./sensors.mk
 
 OBJ =  \
 	$(CAPTOR_OBJ) \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
 CFLAGS = $(CPPFLAGS) -O3 -Werror
 LDFLAGS =
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-all: $(BIN)
+all: $(BIN) readme man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
@@ -48,7 +48,7 @@ $(BIN_DIR):
 	mkdir -p $(BIN_DIR)
 
 debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
-debug: all
+debug: $(BIN)
 
 tests:
 	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
@@ -64,4 +64,12 @@ clean:
 	\rm -f $(SRC_DIR)/counters_option.h
 	\rm -f $(TESTS_DIR)/run
 
-.PHONY: all clean mojitos debug format tests
+readme: $(BIN)
+	sh ./tools/update-readme-usage.sh
+
+man: $(BIN)
+	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
+		'/^USAGE/ { $$0=usage } 1' \
+		doc/mojitos.pre.1 > doc/mojitos.1 2>/dev/null
+
+.PHONY: all clean mojitos debug format tests readme man
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 52a7c6c..1a16db8 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -23,7 +23,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *);
 void clean_amd_rapl(void *);
 void label_amd_rapl(char **labels, void *);
 
-Captor amd_rapl = {
+Sensor amd_rapl = {
     .init = init_amd_rapl,
     .get = get_amd_rapl,
     .clean = clean_amd_rapl,
diff --git a/src/counters.c b/src/counters.c
index 874e6fc..d42ceae 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -44,11 +44,15 @@ typedef struct _counter_t *counter_t;
 
 #include "counters_option.h"
 
-void show_all_counters()
+void *show_all_counters(void *none1, size_t none2)
 {
     for (unsigned int i = 0; i < nb_counter_option; i++) {
         printf("%s\n", perf_static_info[i].name);
     }
+    UNUSED(none1);
+    UNUSED(none2);
+    exit(EXIT_SUCCESS);
+    return NULL;	/* not reached */
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
diff --git a/src/counters.h b/src/counters.h
index a191e5a..0304a07 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -22,9 +22,9 @@ unsigned int init_counters(char *, void **);
 unsigned int get_counters(uint64_t *results, void *);
 void clean_counters(void *);
 void label_counters(char **labels, void *);
-void show_all_counters();
+void *show_all_counters(void *, size_t);
 
-Captor counters = {
+Sensor counters = {
     .init = init_counters,
     .get = get_counters,
     .clean = clean_counters,
@@ -47,7 +47,8 @@ Optparse counters_opt[2] = {
         .shortname = 'l',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "list the possible performance counters and quit"
+        .usage_msg = "list the available performance counters and quit",
+        .fn = show_all_counters,
     },
 };
 
diff --git a/src/infiniband.h b/src/infiniband.h
index 285b2ba..fac05f8 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -21,7 +21,7 @@
 unsigned int init_infiniband(char *infi_path, void **ptr);
 void label_infiniband(char **labels, void *);
 
-Captor infiniband = {
+Sensor infiniband = {
     .init = init_infiniband,
     .get = NULL,
     .clean = NULL,
diff --git a/src/load.h b/src/load.h
index c7c5575..038b263 100644
--- a/src/load.h
+++ b/src/load.h
@@ -23,7 +23,7 @@ unsigned int get_load(uint64_t *results, void *);
 void clean_load(void *);
 void label_load(char **labels, void *);
 
-Captor load = {
+Sensor load = {
     .init = init_load,
     .get = get_load,
     .clean = clean_load,
diff --git a/src/mojitos.c b/src/mojitos.c
index 683bdfa..3ecf111 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -38,11 +38,11 @@ typedef unsigned int (*getter_t)(uint64_t *, void *);
 typedef void (*cleaner_t)(void *);
 
 typedef struct Opt Opt;
-typedef struct Captor Captor;
+typedef struct Sensor Sensor;
 /* optparse typedef */
 typedef struct optparse_long Optparse;
 
-struct Captor {
+struct Sensor {
     initializer_t init;
     getter_t get;
     cleaner_t clean;
@@ -50,41 +50,70 @@ struct Captor {
     int nb_opt;
 };
 
-int nb_defined_captors = 0;
+int nb_defined_sensors = 0;
 
-#include "captors.h"
+#include "sensors.h"
 
-Captor captors[NB_CAPTOR];
+Sensor sensors[NB_SENSOR];
 
 #define NB_OPT 5
-Optparse longopts[NB_OPT + NB_CAPTOR_OPT + 1] = {
+Optparse opts[NB_OPT + NB_SENSOR_OPT + 1] = {
     {
         .longname = "freq", .shortname = 'f', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<freq>",
-        .usage_msg = "specify frequency",
+        .usage_msg = "set amount of measurements per second.",
     },
     {
         .longname = "time", .shortname = 't', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<time>",
-        .usage_msg = "specify time",
+        .usage_msg = "set duration value (seconds). If 0, then loops infinitely.",
     },
     {
         .longname = "exec", .shortname = 'e', .argtype = OPTPARSE_REQUIRED,
-        .usage_arg = "<cmd>",
-        .usage_msg = "specify a command",
+        .usage_arg = "<cmd> ...",
+        .usage_msg = "Execute a command with optional arguments.\n"
+        "\tIf this option is used, any usage of -t or -f is ignored.",
     },
     {
         .longname = "logfile", .shortname = 'o', .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<file>",
-        .usage_msg = "specify a log file",
+        .usage_msg = "specify a log file.",
     },
     {
         .longname = "overhead-stats", .shortname = 's', .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "enable overhead statistics in nanoseconds",
+        .usage_msg = "enable overhead statistics (nanoseconds).",
     },
 };
 
+void dumpopt(Optparse *opt)
+{
+    printf(".It Fl %c | Fl \\-%s", opt->shortname, opt->longname);
+    if (opt->usage_arg != NULL) {
+        printf(" Ar %s", opt->usage_arg);
+    }
+    printf("\n");
+    printf("%s\n", opt->usage_msg);
+}
+
+void dumpopts(Optparse *opts, size_t nb_opt, size_t nb_sensor_opt)
+{
+    size_t i;
+
+    /* options */
+    printf(".Pp\nOPTIONS:\n.Bl -tag -width Ds\n");
+    for (i = 0; i < nb_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+
+    /* sensors */
+    printf(".Pp\nSENSORS:\n.Bl -tag -width Ds\n");
+    for (i++; i < nb_opt + nb_sensor_opt; i++) {
+        dumpopt(&opts[i]);
+    }
+    printf(".El\n");
+}
 
 void printopt(Optparse *opt)
 {
@@ -98,23 +127,21 @@ void printopt(Optparse *opt)
 
 void usage(char **argv)
 {
-    printf("Usage : %s [OPTIONS] [CAPTOR ...]\n", argv[0]);
+    printf("Usage : %s [OPTIONS] [SENSOR ...] [-e <cmd> ...]\n", argv[0]);
 
     printf("\nOPTIONS:\n");
     for (int i = 0; i < NB_OPT; i++) {
-        printopt(&longopts[i]);
+        printopt(&opts[i]);
     }
-    printf("if time==0 then loops infinitively\n"
-           "if -e is present, time and freq are not used\n");
 
-    if (nb_defined_captors == 0) {
+    if (nb_defined_sensors == 0) {
         // no captor to show
         exit(EXIT_FAILURE);
     }
 
-    printf("\nCAPTORS:\n");
-    for (int i = 0; i < NB_CAPTOR_OPT; i++) {
-        printopt(&longopts[NB_OPT + i]);
+    printf("\nSENSORS:\n");
+    for (int i = 0; i < NB_SENSOR_OPT; i++) {
+        printopt(&opts[NB_OPT + i]);
     }
 
     exit(EXIT_FAILURE);
@@ -149,7 +176,7 @@ unsigned int nb_sensors = 0;
 char **labels = NULL;
 uint64_t *values = NULL;
 
-void add_source(Captor *cpt, char *arg)
+void add_source(Sensor *cpt, char *arg)
 {
     nb_sources++;
     initializer_t init = cpt->init;
@@ -186,12 +213,17 @@ int main(int argc, char **argv)
     char **application = NULL;
     int stat_mode = -1;
 
-    init_captors(longopts, captors, NB_OPT + NB_CAPTOR_OPT, NB_OPT, &nb_defined_captors);
+    init_sensors(opts, sensors, NB_OPT + NB_SENSOR_OPT, NB_OPT, &nb_defined_sensors);
 
     if (argc == 1) {
         usage(argv);
     }
 
+    if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '1' && argv[1][2] == '\0') {
+        dumpopts(opts, NB_OPT, NB_SENSOR_OPT);
+        exit(EXIT_SUCCESS);
+    }
+
     output = stdout;
 
     atexit(flushexit);
@@ -202,7 +234,7 @@ int main(int argc, char **argv)
     options.permute = 0;
 
     optparse_init(&options, argv);
-    while ((opt = optparse_long(&options, longopts, NULL)) != -1 && application == NULL) {
+    while ((opt = optparse_long(&options, opts, NULL)) != -1 && application == NULL) {
         switch (opt) {
         case 'f':
             frequency = atoi(options.optarg);
@@ -218,9 +250,6 @@ int main(int argc, char **argv)
         case 's':
             stat_mode = 0;
             break;
-        case 'l':
-            show_all_counters();
-            exit(EXIT_SUCCESS);
         case 'o':
             if ((output = fopen(options.optarg, "wb")) == NULL) {
                 perror("fopen");
@@ -234,11 +263,15 @@ int main(int argc, char **argv)
         default: {
             int ismatch = 0;
             int opt_idx = NB_OPT;
-            for (int i = 0; i < nb_defined_captors && !ismatch; i++) {
-                for (int j = 0; j < captors[i].nb_opt; j++) {
-                    if (opt == longopts[opt_idx].shortname) {
+            for (int i = 0; i < nb_defined_sensors && !ismatch; i++) {
+                for (int j = 0; j < sensors[i].nb_opt; j++) {
+                    if (opt == opts[opt_idx].shortname) {
                         ismatch = 1;
-                        add_source(&captors[i], options.optarg);
+                        if (opts[opt_idx].fn != NULL) {
+                            (void) opts[opt_idx].fn(NULL, 0);
+                        } else {
+                            add_source(&sensors[i], options.optarg);
+                        }
                         break;
                     }
                     opt_idx++;
diff --git a/src/network.h b/src/network.h
index 82fcfc3..994651a 100644
--- a/src/network.h
+++ b/src/network.h
@@ -23,7 +23,7 @@ unsigned int get_network(uint64_t *results, void *);
 void clean_network(void *);
 void label_network(char **labels, void *);
 
-Captor network = {
+Sensor network = {
     .init = init_network,
     .get = get_network,
     .clean = clean_network,
diff --git a/src/rapl.h b/src/rapl.h
index 95f9fd4..a02624d 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -23,7 +23,7 @@ unsigned int get_rapl(uint64_t *results, void *);
 void clean_rapl(void *);
 void label_rapl(char **labels, void *);
 
-Captor rapl = {
+Sensor rapl = {
     .init = init_rapl,
     .get = get_rapl,
     .clean = clean_rapl,
diff --git a/src/temperature.h b/src/temperature.h
index ec2faef..8609dba 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -23,7 +23,7 @@ unsigned int get_temperature(uint64_t *results, void *);
 void clean_temperature(void *);
 void label_temperature(char **labels, void *);
 
-Captor temperature = {
+Sensor temperature = {
     .init = init_temperature,
     .get = get_temperature,
     .clean = clean_temperature,
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
new file mode 100755
index 0000000..b9f16de
--- /dev/null
+++ b/tools/update-readme-usage.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+die() { yell "$*"; exit 111; }
+try() { "$@" || die "cannot $*"; }
+yell() { echo "$0: $*" >&2; }
+echo() { printf '%s\n' "$*"; }
+
+usage=$(./bin/mojitos)
+[ -n "$usage" ] || die 'empty usage. try to recompile mojitos.'
+
+try awk -v "usage=$usage" '
+	/^Usage/ {
+		print usage
+		del = 1
+	}
+	{
+		if (del == 1) {
+			if (match($0, "^```")) {
+				del = 0
+				print $0
+			}
+		} else {
+			print $0
+		}
+	}
+' README.md > README.tmp
+try mv README.tmp README.md
-- 
GitLab


From 24f03a059ada281567c9b7a600cd461619865640 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 6 Feb 2023 10:43:08 +0100
Subject: [PATCH 149/229] small changes

---
 lib/optparse.h |  2 +-
 makefile       | 12 ++++++------
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/lib/optparse.h b/lib/optparse.h
index 1925d73..ee7dcb6 100644
--- a/lib/optparse.h
+++ b/lib/optparse.h
@@ -73,7 +73,7 @@ struct optparse_long {
     enum optparse_argtype argtype;
     char *usage_arg;
     char *usage_msg;
-    void *(*fn)(void *, size_t);
+    void *(*fn)(void *, size_t);	/* SUBJECT TO CHANGE */
 };
 
 /**
diff --git a/makefile b/makefile
index d5d2d23..950028c 100644
--- a/makefile
+++ b/makefile
@@ -55,14 +55,14 @@ tests:
 	$(TESTS_DIR)/run
 
 format:
-	$(ASTYLE) $(SRC_DIR)/*.[ch]
-	$(ASTYLE) $(DOC_DIR)/*.[ch]
-	$(ASTYLE) $(TESTS_DIR)/*.[ch]
+	$(ASTYLE) $(SRC_DIR)/*.[ch] \
+		$(DOC_DIR)/*.[ch] \
+		$(TESTS_DIR)/*.[ch]
 
 clean:
-	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/*
-	\rm -f $(SRC_DIR)/counters_option.h
-	\rm -f $(TESTS_DIR)/run
+	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
+		$(SRC_DIR)/counters_option.h \
+		$(TESTS_DIR)/run
 
 readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
-- 
GitLab


From 10d6b8c4c1cffff4f52dca798cd6d7cba8eee1ee Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 7 Feb 2023 14:11:24 +0100
Subject: [PATCH 150/229] fix sensor example (doc)

plus add build instructions (in doc/counter_ex.c)
---
 doc/counter_ex.c | 95 +++++++++++++++++++++++++++++++++++++++++++-----
 doc/counter_ex.h |  4 +-
 2 files changed, 88 insertions(+), 11 deletions(-)

diff --git a/doc/counter_ex.c b/doc/counter_ex.c
index 0dc6f29..e0d7023 100644
--- a/doc/counter_ex.c
+++ b/doc/counter_ex.c
@@ -1,26 +1,103 @@
+/*
+ * compilation:
+ *
+
+# normally, this part is done with `configure.sh`, but here we need to
+# do this manually
+cat <<EOF > src/sensors.h
 #include "counter_ex.h"
 
-static int acc;
+#define NB_SENSOR 1
+#define NB_SENSOR_OPT 1
+
+void init_sensors(Optparse *opts, Sensor *sensors, size_t len, size_t offset, int *nb_defined)
+{
+    int opt_idx = offset;
+    for (int i = 0; i < counter_ex.nb_opt; i++) {
+        opts[opt_idx++] = counter_ex_opt[i];
+    }
+    sensors[(*nb_defined)++] = counter_ex;
+    assert((offset + *nb_defined) <= len);
+}
+EOF
+
+# idem
+echo 'CAPTOR_OBJ = doc/counters_ex.o' > sensors.mk
+
+# actual compilation here
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/counter_ex.c -o obj/counter_ex.o
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/util.c -o obj/util.o
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/mojitos.c -o obj/mojitos.o
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og obj/util.o obj/mojitos.o obj/counter_ex.o -o bin/mojitos
 
-unsigned int init_acc(char *a, void **b)
+ *
+**/
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "util.h"
+
+#define NB_SENSOR 3
+
+struct accumulator_t {
+    int v[NB_SENSOR];
+};
+
+void _get_acc(int v[NB_SENSOR])
 {
-    acc = 0;
+    for (int i = 0; i < NB_SENSOR; i++) {
+        v[i]++;
+    }
 }
 
-unsigned int get_acc(uint64_t *results, void *none)
+unsigned int init_acc(char *none, void **ptr)
 {
+    /* "none" refers to an optionnal command-line argument */
+    /* there is none in this case, so this parameter is not used */
     UNUSED(none);
-    return a++;
+
+    struct accumulator_t *state = malloc(sizeof(struct accumulator_t));
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        state->v[i] = -1;
+    }
+
+    *ptr = (void *)state;
+    _get_acc(state->v);
+
+    return NB_SENSOR;
+}
+
+unsigned int get_acc(uint64_t *results, void *ptr)
+{
+    struct accumulator_t *state = (struct accumulator_t *)ptr;
+
+    _get_acc(state->v);
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        results[i] = state->v[i];
+    }
+
+    return NB_SENSOR;
 }
 
+char *_labels_accumulator[NB_SENSOR] = {"acc1", "acc2", "acc3"};
 void label_acc(char **labels, void *none)
 {
     UNUSED(none);
-    labels[0] = "acc";
+    for (int i = 0; i < NB_SENSOR; i++) {
+        labels[i] = _labels_accumulator[i];
+    }
 }
 
-void clean_acc(void *none)
+void clean_acc(void *ptr)
 {
-    /* That's a no-op for this example */
-    UNUSED(none);
+    struct accumulator_t *state = (struct accumulator_t *)ptr;
+
+    if (state == NULL) {
+        return;
+    }
+
+    free(state);
 }
diff --git a/doc/counter_ex.h b/doc/counter_ex.h
index 65fabf3..8d798fc 100644
--- a/doc/counter_ex.h
+++ b/doc/counter_ex.h
@@ -7,7 +7,7 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-Sensor rapl = {
+Sensor counter_ex = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
@@ -15,7 +15,7 @@ Sensor rapl = {
     .nb_opt = 1,
 };
 
-Optparse rapl_opt[1] = {
+Optparse counter_ex_opt[1] = {
     {
         .longname = "accumulator",
         .shortname = 'a',
-- 
GitLab


From 1aa72c5c628ab3b24718596e27792b1d6fddacc1 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 7 Feb 2023 14:15:49 +0100
Subject: [PATCH 151/229] rename counter_ex to sensor_ex

---
 doc/{counter_ex.c => sensor_ex.c} | 14 +++++++-------
 doc/{counter_ex.h => sensor_ex.h} |  6 +++---
 2 files changed, 10 insertions(+), 10 deletions(-)
 rename doc/{counter_ex.c => sensor_ex.c} (86%)
 rename doc/{counter_ex.h => sensor_ex.h} (83%)

diff --git a/doc/counter_ex.c b/doc/sensor_ex.c
similarity index 86%
rename from doc/counter_ex.c
rename to doc/sensor_ex.c
index e0d7023..6b10076 100644
--- a/doc/counter_ex.c
+++ b/doc/sensor_ex.c
@@ -5,7 +5,7 @@
 # normally, this part is done with `configure.sh`, but here we need to
 # do this manually
 cat <<EOF > src/sensors.h
-#include "counter_ex.h"
+#include "sensor_ex.h"
 
 #define NB_SENSOR 1
 #define NB_SENSOR_OPT 1
@@ -13,22 +13,22 @@ cat <<EOF > src/sensors.h
 void init_sensors(Optparse *opts, Sensor *sensors, size_t len, size_t offset, int *nb_defined)
 {
     int opt_idx = offset;
-    for (int i = 0; i < counter_ex.nb_opt; i++) {
-        opts[opt_idx++] = counter_ex_opt[i];
+    for (int i = 0; i < sensor_ex.nb_opt; i++) {
+        opts[opt_idx++] = sensor_ex_opt[i];
     }
-    sensors[(*nb_defined)++] = counter_ex;
+    sensors[(*nb_defined)++] = sensor_ex;
     assert((offset + *nb_defined) <= len);
 }
 EOF
 
 # idem
-echo 'CAPTOR_OBJ = doc/counters_ex.o' > sensors.mk
+echo 'CAPTOR_OBJ = doc/sensor_ex.o' > sensors.mk
 
 # actual compilation here
-gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/counter_ex.c -o obj/counter_ex.o
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/sensor_ex.c -o obj/sensor_ex.o
 gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/util.c -o obj/util.o
 gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og -c doc/mojitos.c -o obj/mojitos.o
-gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og obj/util.o obj/mojitos.o obj/counter_ex.o -o bin/mojitos
+gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og obj/util.o obj/mojitos.o obj/sensor_ex.o -o bin/mojitos
 
  *
 **/
diff --git a/doc/counter_ex.h b/doc/sensor_ex.h
similarity index 83%
rename from doc/counter_ex.h
rename to doc/sensor_ex.h
index 8d798fc..a040558 100644
--- a/doc/counter_ex.h
+++ b/doc/sensor_ex.h
@@ -1,5 +1,5 @@
 /*
- * Example of a basic counter: an accumulator
+ * Example of a basic sensor: an accumulator
 **/
 
 unsigned int init_acc(char *, void **);
@@ -7,7 +7,7 @@ unsigned int get_acc(uint64_t *results, void *);
 void clean_acc(void *);
 void label_acc(char **labels, void *);
 
-Sensor counter_ex = {
+Sensor sensor_ex = {
     .init = init_acc,
     .get = get_acc,
     .clean = clean_acc,
@@ -15,7 +15,7 @@ Sensor counter_ex = {
     .nb_opt = 1,
 };
 
-Optparse counter_ex_opt[1] = {
+Optparse sensor_ex_opt[1] = {
     {
         .longname = "accumulator",
         .shortname = 'a',
-- 
GitLab


From 4510bf4f56001a8cc1b97d3cc898d857c494b946 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 14:08:42 +0000
Subject: [PATCH 152/229] fix: make tests

---
 tests/info_reader.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 19d9c0a..5000f48 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -19,7 +19,7 @@
 *******************************************************/
 
 #include "small_test.h"
-#include "./../src/info_reader.h"
+#include "./../lib/info_reader.h"
 
 TFUNCTION(test_replace_first, {
     // useful variables :
-- 
GitLab


From 9ef7c81ca0b0ca2d3cd09340d8c357f3f6655524 Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Wed, 8 Feb 2023 23:13:54 +0100
Subject: [PATCH 153/229] gitlab CI config

---
 .gitlab-ci.yml | 14 ++++++++++++++
 1 file changed, 14 insertions(+)
 create mode 100644 .gitlab-ci.yml

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..cac871a
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,14 @@
+job-build
+  stage: build
+  script:
+    - ./configure.sh
+    - make
+
+job-build-test
+  stage: build
+  script:
+    - ./configure.sh
+    - make tests
+
+workflow:
+  name: 'Pipeline for branch: $CI_COMMIT_BRANCH'
-- 
GitLab


From 30c61950fbca95eb6f6aeab88e9e248262dca19a Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Sat, 11 Feb 2023 19:37:59 +0100
Subject: [PATCH 154/229] fix gitlab ci

---
 .gitlab-ci.yml | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index cac871a..91608c4 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,12 +1,12 @@
-job-build
+job-build:
   stage: build
   script:
     - ./configure.sh
     - make
 
-job-build-test
+job-build-test:
   stage: build
-  script:
+  script: 
     - ./configure.sh
     - make tests
 
-- 
GitLab


From cb334bb6906bdf513dfc09b635565e5832db09ab Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 13:26:09 +0000
Subject: [PATCH 155/229] update Copyright date

---
 configure.sh                 |  3 +++
 doc/sensor_ex.c              | 20 ++++++++++++++++++++
 doc/sensor_ex.h              | 20 ++++++++++++++++++++
 src/counters.c               |  2 +-
 src/counters.h               |  2 +-
 src/counters_option.sh       |  2 +-
 src/infiniband.c             |  2 +-
 src/infiniband.h             |  2 +-
 src/load.c                   |  2 +-
 src/load.h                   |  2 +-
 src/mojitos.c                |  3 +--
 src/network.c                |  2 +-
 src/network.h                |  2 +-
 src/temperature.c            |  2 +-
 src/temperature.h            |  2 +-
 src/util.h                   |  2 +-
 tools/update-readme-usage.sh |  3 +++
 17 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/configure.sh b/configure.sh
index 62f297a..196aaf8 100755
--- a/configure.sh
+++ b/configure.sh
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
 try() { "$@" || die "cannot $*"; }
 die() { yell "$*"; exit 111; }
 yell() { echo "$0: $*" >&2; }
diff --git a/doc/sensor_ex.c b/doc/sensor_ex.c
index 6b10076..d37cbeb 100644
--- a/doc/sensor_ex.c
+++ b/doc/sensor_ex.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
 /*
  * compilation:
  *
diff --git a/doc/sensor_ex.h b/doc/sensor_ex.h
index a040558..9fd95d3 100644
--- a/doc/sensor_ex.h
+++ b/doc/sensor_ex.h
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
 /*
  * Example of a basic sensor: an accumulator
 **/
diff --git a/src/counters.c b/src/counters.c
index d42ceae..1a7027e 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/counters.h b/src/counters.h
index 0304a07..4374cd1 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/counters_option.sh b/src/counters_option.sh
index 7c99eba..38cee08 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+# Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
 linux_include=/usr/include/linux/perf_event.h
 
diff --git a/src/infiniband.c b/src/infiniband.c
index 303795e..2314e1d 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/infiniband.h b/src/infiniband.h
index fac05f8..e30d78b 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/load.c b/src/load.c
index 1c049ce..64502e5 100644
--- a/src/load.c
+++ b/src/load.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2019-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2019-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/load.h b/src/load.h
index 038b263..6d8d298 100644
--- a/src/load.h
+++ b/src/load.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/mojitos.c b/src/mojitos.c
index 3ecf111..4274b6a 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -1,6 +1,5 @@
 /*******************************************************
-
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/network.c b/src/network.c
index 543a053..74d8bb9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/network.h b/src/network.h
index 994651a..a158dbb 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/temperature.c b/src/temperature.c
index acc0702..bcddb22 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/temperature.h b/src/temperature.h
index 8609dba..e70554d 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/util.h b/src/util.h
index 23978c1..e422d07 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
index b9f16de..ad2f88f 100755
--- a/tools/update-readme-usage.sh
+++ b/tools/update-readme-usage.sh
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
 die() { yell "$*"; exit 111; }
 try() { "$@" || die "cannot $*"; }
 yell() { echo "$0: $*" >&2; }
-- 
GitLab


From 285d4169ca478de59203f7dc70365d0c55028e7e Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 13:42:53 +0000
Subject: [PATCH 156/229] update option

---
 README.md      | 2 +-
 src/amd_rapl.h | 2 +-
 src/rapl.h     | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index 10f5aaf..fddb2b1 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,7 @@ SENSORS:
 	system load
 -d|--net-dev <net_dev>
 	network monitoring (if network_device is X, tries to detect it automatically)
--r|--rapl
+-r|--intel-rapl
 	RAPL
 -c|--cpu-temp
 	processor temperature
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 1a16db8..e58cc16 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -34,7 +34,7 @@ Sensor amd_rapl = {
 Optparse amd_rapl_opt[1] = {
     {
         .longname = "amd-rapl",
-        .shortname = 'a',
+        .shortname = 'r',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
         .usage_msg = "AMD RAPL",
diff --git a/src/rapl.h b/src/rapl.h
index a02624d..7720f07 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -33,11 +33,11 @@ Sensor rapl = {
 
 Optparse rapl_opt[1] = {
     {
-        .longname = "rapl",
+        .longname = "intel-rapl",
         .shortname = 'r',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "RAPL",
+        .usage_msg = "INTEL RAPL",
     },
 };
 
-- 
GitLab


From bed45ca8c3fbc4c2b54590427c4e28ffc17dd684 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 14:19:14 +0000
Subject: [PATCH 157/229] standardise the names of structures

---
 README.md              |  2 +-
 doc/info_reader_ex.c   |  2 +-
 doc/sensor_ex.c        |  9 ++++----
 src/amd_rapl.c         | 52 +++++++++++++++++++++---------------------
 src/counters.c         | 22 +++++++++---------
 src/counters_option.sh |  6 ++---
 src/infiniband.c       |  6 +++--
 src/network.c          |  9 ++++----
 src/rapl.c             | 16 ++++++-------
 src/temperature.c      | 13 ++++++-----
 tests/amd_rapl.c       | 26 ++++++++++-----------
 11 files changed, 84 insertions(+), 79 deletions(-)

diff --git a/README.md b/README.md
index fddb2b1..95b6d7e 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ SENSORS:
 -d|--net-dev <net_dev>
 	network monitoring (if network_device is X, tries to detect it automatically)
 -r|--intel-rapl
-	RAPL
+	INTEL RAPL
 -c|--cpu-temp
 	processor temperature
 ```
diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 2e76251..f1e6d96 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -20,7 +20,7 @@
 
 
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
-#include "./../src/info_reader.h"
+#include "./../lib/info_reader.h"
 
 #define MAX_PROCS 64
 
diff --git a/doc/sensor_ex.c b/doc/sensor_ex.c
index d37cbeb..5fc8eeb 100644
--- a/doc/sensor_ex.c
+++ b/doc/sensor_ex.c
@@ -60,9 +60,10 @@ gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og obj/util.o obj/mo
 
 #define NB_SENSOR 3
 
-struct accumulator_t {
+struct Accumulator {
     int v[NB_SENSOR];
 };
+typedef struct Accumulator Accumulator;
 
 void _get_acc(int v[NB_SENSOR])
 {
@@ -77,7 +78,7 @@ unsigned int init_acc(char *none, void **ptr)
     /* there is none in this case, so this parameter is not used */
     UNUSED(none);
 
-    struct accumulator_t *state = malloc(sizeof(struct accumulator_t));
+    Accumulator *state = malloc(sizeof(Accumulator));
 
     for (int i = 0; i < NB_SENSOR; i++) {
         state->v[i] = -1;
@@ -91,7 +92,7 @@ unsigned int init_acc(char *none, void **ptr)
 
 unsigned int get_acc(uint64_t *results, void *ptr)
 {
-    struct accumulator_t *state = (struct accumulator_t *)ptr;
+    Accumulator *state = (Accumulator *)ptr;
 
     _get_acc(state->v);
 
@@ -113,7 +114,7 @@ void label_acc(char **labels, void *none)
 
 void clean_acc(void *ptr)
 {
-    struct accumulator_t *state = (struct accumulator_t *)ptr;
+    Accumulator *state = (Accumulator *)ptr;
 
     if (state == NULL) {
         return;
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 805e698..34ccb47 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -41,7 +41,7 @@ static const uint64_t energy_core_msr = 0xC001029A;
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
 
-struct cpu_sensor_t {
+struct CpuSensor {
     unsigned int cpu_id;
     unsigned int package_id;
     unsigned int core_id;
@@ -52,13 +52,13 @@ struct cpu_sensor_t {
     unsigned int energy_units;
     uint64_t core_energy;
 };
-typedef struct cpu_sensor_t cpu_sensor_t;
+typedef struct CpuSensor CpuSensor;
 
-struct _amd_rapl_t {
-    cpu_sensor_t *sensors;
+struct AmdRapl {
+    CpuSensor *sensors;
     unsigned int sensor_count;
 };
-typedef struct _amd_rapl_t _amd_rapl_t;
+typedef struct AmdRapl AmdRapl;
 
 // -----------------------------INFO_READER
 
@@ -75,19 +75,19 @@ static GenericPointer uint_allocator(char *s)
 
 static void _set_cpu_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->cpu_id = (unsigned int) data;
 }
 
 static void _set_package_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->package_id = (unsigned int) data;
 }
 
 static void _set_core_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->core_id = (unsigned int) data;
 }
 
@@ -98,13 +98,13 @@ static KeyFinder keys[NB_KEYS] = {
 };
 
 
-static unsigned int parse_cpuinfo(cpu_sensor_t *storage, unsigned int capacity)
+static unsigned int parse_cpuinfo(CpuSensor *storage, unsigned int capacity)
 {
     Parser parser = {
         .storage = (GenericPointer) storage,
         .nb_stored = 0,
         .capacity = capacity,
-        .storage_struct_size = sizeof(cpu_sensor_t),
+        .storage_struct_size = sizeof(CpuSensor),
         .keys = keys,
         .nb_keys = NB_KEYS,
         .file = fopen(cpuinfo, "r")
@@ -171,9 +171,9 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 // -----------------------------------DEBUG
 
 #ifdef DEBUG
-void debug_print_sensor(cpu_sensor_t *sensor)
+void debug_print_sensor(CpuSensor *sensor)
 {
-    //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
+    //CASSERT(sizeof(CpuSensor) == 56, amd_rapl_c);
     printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
@@ -185,7 +185,7 @@ void debug_print_sensor(cpu_sensor_t *sensor)
           );
 }
 
-void debug_print_amd_rapl(_amd_rapl_t *rapl)
+void debug_print_amd_rapl(AmdRapl *rapl)
 {
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         debug_print_sensor(&rapl->sensors[i]);
@@ -213,7 +213,7 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, cpu_sensor_t *sensors, unsigned int nb_sensor)
+void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, CpuSensor *sensors, unsigned int nb_sensor)
 {
     unsigned int nb_package = 0;
     unsigned int nb_core = 0;
@@ -238,7 +238,7 @@ char *get_name(unsigned int cpu_id)
     return name;
 }
 
-void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
+void update_cpu_sensor(CpuSensor *sensor, uint64_t *energy_consumed)
 {
     sensor->energy_units = read_unit(sensor->fd);
     uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
@@ -248,7 +248,7 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
+unsigned int is_duplicate(CpuSensor *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
 {
     if (map[sensor->core_id][sensor->package_id] == 1) {
         return 0;
@@ -257,7 +257,7 @@ unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned in
     return 1;
 }
 
-void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
+void init_cpu_sensor(CpuSensor *sensor, CpuSensor *cpu_info)
 {
     static char filename[BUFFER_SIZE];
     snprintf(filename,BUFFER_SIZE, base_str, cpu_info->cpu_id);
@@ -269,18 +269,18 @@ void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
         exit(127);
     }
 
-    memcpy(sensor, cpu_info, sizeof(cpu_sensor_t));
+    memcpy(sensor, cpu_info, sizeof(CpuSensor));
     sensor->name = get_name(sensor->cpu_id);
     sensor->fd = fd;
 }
 
-void clean_cpu_sensor(cpu_sensor_t *sensor)
+void clean_cpu_sensor(CpuSensor *sensor)
 {
     close(sensor->fd);
     free(sensor->name);
 }
 
-void free_amd_rapl(_amd_rapl_t *rapl)
+void free_amd_rapl(AmdRapl *rapl)
 {
     free(rapl->sensors);
     free(rapl);
@@ -299,7 +299,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    cpu_sensor_t *cpu_information = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    CpuSensor *cpu_information = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor));
     if (parse_cpuinfo(cpu_information, max_cpus)) {
         free(cpu_information);
         PANIC(1, "cpuinfo");
@@ -311,7 +311,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned char cpu_map[nb_core][nb_package];
     memset(cpu_map, 0, sizeof(cpu_map));
-    cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    CpuSensor *sensors = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
@@ -322,7 +322,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     }
     free(cpu_information);
 
-    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+    AmdRapl *rapl = (AmdRapl *) calloc(1, sizeof(AmdRapl));
     rapl->sensors = sensors;
     rapl->sensor_count = sensor_count;
     *ptr = (void *) rapl;
@@ -332,7 +332,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
 unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         update_cpu_sensor(&rapl->sensors[i], &results[i]);
     }
@@ -341,7 +341,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 
 void label_amd_rapl(char **labels, void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         labels[i] = rapl->sensors[i].name;
     }
@@ -349,7 +349,7 @@ void label_amd_rapl(char **labels, void *ptr)
 
 void clean_amd_rapl(void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         clean_cpu_sensor(&rapl->sensors[i]);
diff --git a/src/counters.c b/src/counters.c
index 1a7027e..e809f88 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -30,7 +30,7 @@
 #include "util.h"
 
 
-struct _counter_t {
+struct Counter {
     int nbcores;
     int nbperf;
     int **counters;
@@ -40,7 +40,7 @@ struct _counter_t {
     int *perf_indexes;
 
 };
-typedef struct _counter_t *counter_t;
+typedef struct Counter Counter;
 
 #include "counters_option.h"
 
@@ -105,7 +105,7 @@ static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
     return res;
 }
 
-counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+Counter *_init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
@@ -113,7 +113,7 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
     pe.size = sizeof(struct perf_event_attr);
     pe.disabled = 1;
 
-    counter_t counters = malloc(sizeof(struct _counter_t));
+    Counter *counters = malloc(sizeof(struct Counter));
     counters->nbperf = nb_perf;
     counters->nbcores = nbcores;
     counters->counters = malloc(nb_perf * sizeof(int *));
@@ -133,7 +133,7 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
 
 void clean_counters(void *ptr)
 {
-    counter_t counters = (counter_t) ptr;
+    Counter *counters = (Counter *) ptr;
 
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -151,7 +151,7 @@ void clean_counters(void *ptr)
     free(counters);
 }
 
-void start_counters(counter_t counters)
+void start_counters(Counter *counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -160,7 +160,7 @@ void start_counters(counter_t counters)
     }
 }
 
-void reset_counters(counter_t counters)
+void reset_counters(Counter *counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -169,7 +169,7 @@ void reset_counters(counter_t counters)
     }
 }
 
-void _get_counters(counter_t counters, uint64_t *values)
+void _get_counters(Counter *counters, uint64_t *values)
 {
     for (int i = 0; i < counters->nbperf; i++) {
         uint64_t accu = 0;
@@ -202,7 +202,7 @@ unsigned int init_counters(char *args, void **state)
     __u32 *perf_type;
     __u64 *perf_key;
     perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
-    counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
+    Counter *fd = _init_counters(nb_perf, perf_type, perf_key);
     free(perf_type);
     free(perf_key);
 
@@ -218,7 +218,7 @@ unsigned int init_counters(char *args, void **state)
 
 unsigned int get_counters(uint64_t *results, void *ptr)
 {
-    counter_t state = (counter_t) ptr;
+    Counter *state = (Counter *) ptr;
 
     _get_counters(state, state->tmp_counters_values);
 
@@ -232,7 +232,7 @@ unsigned int get_counters(uint64_t *results, void *ptr)
 
 void label_counters(char **labels, void *ptr)
 {
-    counter_t state = (counter_t) ptr;
+    Counter *state = (Counter *) ptr;
 
     for (int i = 0; i < state->nbperf; i++) {
         labels[i] = perf_static_info[state->perf_indexes[i]].name;
diff --git a/src/counters_option.sh b/src/counters_option.sh
index 38cee08..76f9275 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -6,13 +6,13 @@
 linux_include=/usr/include/linux/perf_event.h
 
 echo '
-typedef struct counter_option {
+typedef struct CounterOption{
     char *name;
     __u32 perf_type;
     __u64 perf_key;
-} counter_option;
+} CounterOption;
 
-static counter_option perf_static_info[] = {'
+static CounterOption perf_static_info[] = {'
 
 nb=0
 
diff --git a/src/infiniband.c b/src/infiniband.c
index 2314e1d..bbc0fee 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -27,11 +27,13 @@
 
 #define NB_SENSOR 4
 
-struct network_t {
+struct Network {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
 };
+typedef struct Network Network;
+
 unsigned int _get_network(uint64_t *results, int *sources);
 
 
@@ -60,7 +62,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
                          "%s/port_xmit_data"
                         };
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+    Network *state = malloc(sizeof(Network));
 
     char buffer[1024];
     for (int i = 0; i < NB_SENSOR; i++) {
diff --git a/src/network.c b/src/network.c
index 74d8bb9..d361d47 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,11 +28,12 @@
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
-struct network_t {
+struct Network {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
 };
+typedef struct Network Network;
 
 unsigned int _get_network(uint64_t *results, int *sources)
 {
@@ -92,7 +93,7 @@ unsigned int init_network(char *dev, void **ptr)
                          "/sys/class/net/%s/statistics/tx_bytes"
                         };
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+    Network *state = malloc(sizeof(Network));
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
@@ -108,7 +109,7 @@ unsigned int init_network(char *dev, void **ptr)
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
-    struct network_t *state = (struct network_t *) ptr;
+    Network *state = (Network *) ptr;
     _get_network(state->tmp_values, state->sources);
 
     for (int i = 0; i < NB_SENSOR; i++) {
@@ -121,7 +122,7 @@ unsigned int get_network(uint64_t *results, void *ptr)
 
 void clean_network(void *ptr)
 {
-    struct network_t *state = (struct network_t *) ptr;
+    Network *state = (Network *) ptr;
 
     if (state == NULL) {
         return;
diff --git a/src/rapl.c b/src/rapl.c
index 8a04d31..5d7eca7 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -52,7 +52,7 @@ void test_append(char *name, int i)
 }
 
 
-struct _rapl_t {
+struct IntelRapl {
     unsigned int nb;
     char **names;
     int *fids;
@@ -60,10 +60,10 @@ struct _rapl_t {
     uint64_t *tmp_values;
 
 };
-typedef struct _rapl_t _rapl_t;
+typedef struct IntelRapl IntelRapl;
 
 
-void add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
+void add_rapl_source(IntelRapl *rapl, char *name, char *energy_uj)
 {
     rapl->nb += 1;
     rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
@@ -85,7 +85,7 @@ void add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
 }
 
 
-void _get_rapl(uint64_t *values, _rapl_t *rapl)
+void _get_rapl(uint64_t *values, IntelRapl *rapl)
 {
     static char buffer[512];
 
@@ -104,7 +104,7 @@ void _get_rapl(uint64_t *values, _rapl_t *rapl)
 unsigned int init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    _rapl_t *rapl = malloc(sizeof(_rapl_t));
+    IntelRapl *rapl = malloc(sizeof(IntelRapl));
     rapl->nb = 0;
     rapl->names = NULL;
     rapl->fids = NULL;
@@ -161,7 +161,7 @@ unsigned int init_rapl(char *none, void **ptr)
 
 unsigned int get_rapl(uint64_t *results, void *ptr)
 {
-    _rapl_t *state = (_rapl_t *) ptr;
+    IntelRapl *state = (IntelRapl *) ptr;
     _get_rapl(state->tmp_values, state);
 
     for (unsigned int i = 0; i < state->nb; i++) {
@@ -174,7 +174,7 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 
 void clean_rapl(void *ptr)
 {
-    _rapl_t *rapl = (_rapl_t *) ptr;
+    IntelRapl *rapl = (IntelRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->nb; i++) {
         free(rapl->names[i]);
@@ -191,7 +191,7 @@ void clean_rapl(void *ptr)
 
 void label_rapl(char **labels, void *ptr)
 {
-    _rapl_t *rapl = (_rapl_t *) ptr;
+    IntelRapl *rapl = (IntelRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->nb; i++) {
         labels[i] = rapl->names[i];
diff --git a/src/temperature.c b/src/temperature.c
index bcddb22..a9cf74b 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -26,11 +26,12 @@
 #include <stdint.h>
 #include "util.h"
 
-struct temperature_t {
+struct Temperature {
     char **label_list;
     int *fid_list;
     int nb_elem;
 };
+typedef struct Temperature Temperature;
 
 int get_string(char *filename, char *buffer, int max_size)
 {
@@ -61,7 +62,7 @@ void add_to_list(char ***list_name, char *source, int nb_elem)
 
 }
 
-void add_temperature_sensor(int id_rep, struct temperature_t *state)
+void add_temperature_sensor(int id_rep, Temperature *state)
 {
     static int key = 0;
     static char buffer_filename[512];
@@ -109,7 +110,7 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 unsigned int init_temperature(char *args, void **ptr)
 {
     UNUSED(args);
-    struct temperature_t *state = malloc(sizeof(struct temperature_t));
+    Temperature *state = malloc(sizeof(Temperature));
     state->nb_elem = 0;
     state->label_list = NULL;
     state->fid_list = NULL;
@@ -136,7 +137,7 @@ unsigned int init_temperature(char *args, void **ptr)
 
 unsigned int get_temperature(uint64_t *results, void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
     static char buffer[512];
 
     for (int i = 0; i < state->nb_elem; i++) {
@@ -152,7 +153,7 @@ unsigned int get_temperature(uint64_t *results, void *ptr)
 
 void clean_temperature(void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
 
     for (int i = 0; i < state->nb_elem; i++) {
         free(state->label_list[i]);
@@ -166,7 +167,7 @@ void clean_temperature(void *ptr)
 
 void label_temperature(char **labels, void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
 
     for (int i = 0; i < state->nb_elem; i++) {
         labels[i] = state->label_list[i];
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 0485099..7c05ab5 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -107,7 +107,7 @@ TFUNCTION(test_get_name, {
 #define NONE 0
 #define DUMMY_SENSOR(__sensor, __cpu_id, __name) \
 do {                                             \
-  __sensor = (cpu_sensor_t) {                    \
+  __sensor = (CpuSensor) {                    \
     .cpu_id = __cpu_id,                          \
     .package_id = NONE,                          \
     .core_id = NONE,                             \
@@ -120,15 +120,15 @@ do {                                             \
 
 #define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
 do {                                                   \
-    __rapl = (_amd_rapl_t) {                           \
+    __rapl = (AmdRapl) {                           \
         .sensors = __sensors,                          \
         .sensor_count = __sensors_count                \
     };                                                 \
 } while(0);
 
 TFUNCTION(test_label_amd_rapl, {
-    cpu_sensor_t sensors[100];
-    _amd_rapl_t rapl;
+    CpuSensor sensors[100];
+    AmdRapl rapl;
     char *results[100];
     char expecteds[10][100];
     uint64_t nb = 0;
@@ -190,7 +190,7 @@ TFUNCTION(test_label_amd_rapl, {
 
 #define DUMMY_CPUINFO(__sensor, __cpu_id, __package_id, __core_id) \
 do {                                                               \
-    __sensor = (cpu_sensor_t) {                                    \
+    __sensor = (CpuSensor) {                                    \
         .cpu_id = __cpu_id,                                        \
         .package_id = __package_id,                                \
         .core_id = __core_id,                                      \
@@ -207,13 +207,13 @@ TFUNCTION(test_is_duplicate, {
     static const unsigned int max_cpu = 10;
 
     unsigned char map[nb_core][nb_package];
-    cpu_sensor_t cpu_information[max_cpu];
+    CpuSensor cpu_information[max_cpu];
     unsigned int results[max_cpu];
     unsigned int expecteds[max_cpu];
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
@@ -226,7 +226,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
     expecteds[0] = 1;
@@ -240,7 +240,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
     expecteds[0] = 1;
@@ -254,7 +254,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
     expecteds[0] = 1;
@@ -268,7 +268,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     expecteds[0] = 1;
@@ -282,7 +282,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     DUMMY_CPUINFO(cpu_information[2], 0, 1, 0);
@@ -317,7 +317,7 @@ TFILE_ENTRY_POINT(test_amd_rapl, {
 int main()
 {
     static const unsigned int time = 10;
-    _amd_rapl_t *rapl = NULL;
+    AmdRapl *rapl = NULL;
     unsigned int count_cpu = init_amd_rapl(NULL, (void **) &rapl);
     uint64_t results[count_cpu];
     char *labels[count_cpu];
-- 
GitLab


From 5bea42ec1eac091535f61c68fbfac721408905f1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 14:46:28 +0000
Subject: [PATCH 158/229] sprintf -> snprintf

---
 src/amd_rapl.c    |  3 ++-
 src/counters.c    |  2 +-
 src/infiniband.c  |  2 +-
 src/network.c     |  2 +-
 src/rapl.c        | 35 +++++++++++++++--------------------
 src/temperature.c | 22 ++++++++++++----------
 6 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 34ccb47..1e08517 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -161,6 +161,7 @@ uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
     // Joule * 1000000 -> uJoule
     return (uint64_t) (((double) raw * to_microjoule) / (double)(1U << unit));
 }
+
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
     // raw * (1 / (unit^2)) -> Joule
@@ -202,7 +203,7 @@ unsigned int get_nb_cpu()
 
     unsigned int n_cpu = 0;
     for (;; n_cpu++) {
-        sprintf(filename, base_str, n_cpu);
+        snprintf(filename, BUFFER_SIZE, base_str, n_cpu);
 
         int fd = open(filename, O_RDONLY);
         if (fd < 0) {
diff --git a/src/counters.c b/src/counters.c
index e809f88..8013ff8 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -52,7 +52,7 @@ void *show_all_counters(void *none1, size_t none2)
     UNUSED(none1);
     UNUSED(none2);
     exit(EXIT_SUCCESS);
-    return NULL;	/* not reached */
+    return NULL; /* not reached */
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
diff --git a/src/infiniband.c b/src/infiniband.c
index bbc0fee..aa4a8de 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -66,7 +66,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 
     char buffer[1024];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer, filenames[i], infi_path);
+        snprintf(buffer, 1024, filenames[i], infi_path);
         state->sources[i] = open(buffer, O_RDONLY);
     }
 
diff --git a/src/network.c b/src/network.c
index d361d47..977b92e 100644
--- a/src/network.c
+++ b/src/network.c
@@ -97,7 +97,7 @@ unsigned int init_network(char *dev, void **ptr)
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, filenames[i], dev);
+        sprintf(buffer2, 256, filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
     }
 
diff --git a/src/rapl.c b/src/rapl.c
index 5d7eca7..eb88553 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -28,6 +28,7 @@
 #include "util.h"
 
 #define MAX_HEADER 128
+#define BUFFER_SIZE 1024
 
 char *get_rapl_string(const char *filename)
 {
@@ -40,15 +41,16 @@ char *get_rapl_string(const char *filename)
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
     result[nb - 1] = 0;
-    return (result);
+    return result;
 }
 
-void test_append(char *name, int i)
+void append(char *name, int i, size_t buffer_size)
 {
-    //char last = name[strlen(name)-1];
-    //if (last>='0' && last <= '9')
-    //  return;
-    sprintf(name + strlen(name), "%d", i);
+    size_t name_len = strlen(name);
+    char* ptr = name + name_len;
+
+    size_t remaining_space = buffer_size - name_len;
+    snprintf(ptr, remaining_space, "%d", i);
 }
 
 
@@ -109,40 +111,33 @@ unsigned int init_rapl(char *none, void **ptr)
     rapl->names = NULL;
     rapl->fids = NULL;
 
-    char buffer[1024];
+    char buffer[BUFFER_SIZE];
     char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
     char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
     for (unsigned int i = 0;; i++) {
-        sprintf(buffer, name_base, i, "name");
+        snprintf(buffer, BUFFER_SIZE, name_base, i, "name");
         char *tmp = get_rapl_string(buffer);
 
         if (tmp == NULL) {
             break;
         }
 
-        //printf("%s\n", tmp);
-        test_append(tmp, i);
-        //printf("%s -> %s\n", buffer, tmp);
-
-        sprintf(buffer, name_base, i, "energy_uj");
+        append(tmp, i, MAX_HEADER);
+        snprintf(buffer, BUFFER_SIZE, name_base, i, "energy_uj");
         add_rapl_source(rapl, tmp, buffer);
         free(tmp);
 
         for (unsigned int j = 0;; j++) {
-            sprintf(buffer, name_sub, i, i, j, "name");
+            snprintf(buffer, BUFFER_SIZE, name_sub, i, i, j, "name");
             char *tmp_sub = get_rapl_string(buffer);
 
             if (tmp_sub == NULL) {
                 break;
             }
 
-            //printf("%s\n", tmp_sub);
-            test_append(tmp_sub, i);
-            //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-            sprintf(buffer, name_sub, i, i, j, "energy_uj");
+            append(tmp_sub, i, MAX_HEADER);
+            snprintf(buffer, BUFFER_SIZE, name_sub, i, i, j, "energy_uj");
             add_rapl_source(rapl, tmp_sub, buffer);
 
             free(tmp_sub);
diff --git a/src/temperature.c b/src/temperature.c
index a9cf74b..1dc1099 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -26,6 +26,8 @@
 #include <stdint.h>
 #include "util.h"
 
+#define BUFFER_SIZE 512
+
 struct Temperature {
     char **label_list;
     int *fid_list;
@@ -65,13 +67,13 @@ void add_to_list(char ***list_name, char *source, int nb_elem)
 void add_temperature_sensor(int id_rep, Temperature *state)
 {
     static int key = 0;
-    static char buffer_filename[512];
-    static char buffer_label[512];
+    static char buffer_filename[BUFFER_SIZE];
+    static char buffer_label[BUFFER_SIZE];
 
-    int delta = sprintf(buffer_label, "Temp_%d_", key);
+    int delta = snprintf(buffer_label, BUFFER_SIZE, "Temp_%d_", key);
 
     for (int i = 1;; i++) {
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+        snprintf(buffer_filename, BUFFER_SIZE, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
 
         if (get_string(buffer_filename, buffer_label + delta, 100) == -1) {
             break;
@@ -89,7 +91,7 @@ void add_temperature_sensor(int id_rep, Temperature *state)
 
         add_to_list(&state->label_list, buffer_label, state->nb_elem);
 
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+        snprintf(buffer_filename, BUFFER_SIZE, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
         state->fid_list = realloc(state->fid_list, (state->nb_elem + 1) * sizeof(int));
         int fd = open(buffer_filename, O_RDONLY);
 
@@ -116,11 +118,11 @@ unsigned int init_temperature(char *args, void **ptr)
     state->fid_list = NULL;
 
     char base_name[] = "/sys/class/hwmon/hwmon%d/name";
-    static char name[512];
-    static char buffer[512];
+    static char name[BUFFER_SIZE];
+    static char buffer[BUFFER_SIZE];
 
     int i = 0;
-    sprintf(name, base_name, i);
+    snprintf(name, BUFFER_SIZE, base_name, i);
 
     while (get_string(name, buffer, 8) != -1) {
         if (strcmp(buffer, "coretemp") == 0) {
@@ -128,7 +130,7 @@ unsigned int init_temperature(char *args, void **ptr)
         }
 
         i++;
-        sprintf(name, base_name, i);
+        snprintf(name, BUFFER_SIZE, base_name, i);
     }
 
     *ptr = (void *) state;
@@ -138,7 +140,7 @@ unsigned int init_temperature(char *args, void **ptr)
 unsigned int get_temperature(uint64_t *results, void *ptr)
 {
     Temperature *state = (Temperature *)ptr;
-    static char buffer[512];
+    static char buffer[BUFFER_SIZE];
 
     for (int i = 0; i < state->nb_elem; i++) {
         if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
-- 
GitLab


From b48e884b7ed6955647877134b5629036383c6879 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:05:13 +0000
Subject: [PATCH 159/229] format

---
 src/network.c | 2 +-
 src/rapl.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/network.c b/src/network.c
index 977b92e..37d2373 100644
--- a/src/network.c
+++ b/src/network.c
@@ -97,7 +97,7 @@ unsigned int init_network(char *dev, void **ptr)
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, 256, filenames[i], dev);
+        snprintf(buffer2, 256, filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
     }
 
diff --git a/src/rapl.c b/src/rapl.c
index eb88553..3d13367 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -47,7 +47,7 @@ char *get_rapl_string(const char *filename)
 void append(char *name, int i, size_t buffer_size)
 {
     size_t name_len = strlen(name);
-    char* ptr = name + name_len;
+    char *ptr = name + name_len;
 
     size_t remaining_space = buffer_size - name_len;
     snprintf(ptr, remaining_space, "%d", i);
-- 
GitLab


From eae0b09492c7c7442a8c0d4bf241747f32789b53 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:06:47 +0000
Subject: [PATCH 160/229] add authors

---
 AUTHORS | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/AUTHORS b/AUTHORS
index 0bfc663..13ddd11 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,4 @@
-Georges Da Costa georges.da-costa@irit.fr
\ No newline at end of file
+Georges Da Costa georges.da-costa@irit.fr
+Floréal Risso floreal.risso@univ-tlse3.fr
+Alexis Paronnaud alexis.paronnaud@univ-tlse3.fr
+Téo Tinarrage teo.tinarrage@univ-tlse3.fr
-- 
GitLab


From 290c3cfe5e58877f121c1e3050d29064a740d907 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:11:11 +0000
Subject: [PATCH 161/229] clear doc

---
 makefile | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/makefile b/makefile
index 950028c..646a015 100644
--- a/makefile
+++ b/makefile
@@ -62,7 +62,9 @@ format:
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
 		$(SRC_DIR)/counters_option.h \
-		$(TESTS_DIR)/run
+		$(TESTS_DIR)/run \
+		$(DOC_DIR)/test_main_ex \
+		$(DOC_DIR)/info_reader_ex
 
 readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
-- 
GitLab


From 27b4914943dd51aca0600f20b77659bb7532d86e Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Feb 2023 16:40:07 +0100
Subject: [PATCH 162/229] the README.md file now present all sensors

- add `--all` option to configure.sh
- makefile: readme is no longer a "all" dependency
- plus some minor changes
---
 README.md                    |  9 +++++++++
 configure.sh                 | 14 +++++++++++---
 makefile                     |  6 +++---
 tools/update-readme-usage.sh | 26 +++++++++++++++++++++++---
 4 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 10f5aaf..ac5b2d3 100644
--- a/README.md
+++ b/README.md
@@ -21,13 +21,22 @@ OPTIONS:
 -s|--overhead-stats
 	enable overhead statistics (nanoseconds).
 
+```
+
+The following is an exhaustive list of all the sensors (it is very likely
+that one will not have all the sensors activated in his build):
+```bash
 SENSORS:
+-a|--amd-rapl
+	AMD RAPL
 -p|--perf-list <perf_list>
 	performance counters
 	perf_list is a coma separated list of performance counters.
 	Ex: instructions,cache_misses
 -l|--list
 	list the available performance counters and quit
+-i|--monitor-infiniband <infiniband_path>
+	infiniband monitoring (if infiniband_path is X, tries to detect it automatically)
 -u|--sysload
 	system load
 -d|--net-dev <net_dev>
diff --git a/configure.sh b/configure.sh
index 62f297a..6b48fb5 100755
--- a/configure.sh
+++ b/configure.sh
@@ -23,18 +23,19 @@ debug=0
 target_hdr=src/sensors.h
 target_mk=sensors.mk
 
-nonsensor='counters_option|optparse|sensors|util|info_reader'
+nonsensor='counters_option|sensors|util'
 
 hdr_blacklist=$nonsensor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
+	printf -- 'Usage: %s [-la] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
 	printf -- '-e | --exclude      :   exclude sensor, can be called multiple times\n' >&2
 	printf -- '-i | --include      :   include sensor, can be called multiple times\n' >&2
 	printf -- '-l | --list-sensors :   list all sensors and exit\n' >&2
 	printf -- '-u | --unique       :   only include the specified sensor\n' >&2
 	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
+	printf -- '-a | --all          :   include all sensors, meant to be used only by the makefile\n' >&2
 	exit 1
 }
 
@@ -131,8 +132,15 @@ detect_caps() {
 	[ $(ls -1 /sys/class/hwmon | wc -l) -gt 0 ] && hdr_whitelist="${hdr_whitelist}|temperature"
 }
 
-detect_caps
+case $1 in
+--all|-a)
+	all=1
+	;;
+esac
 
+[ "$all" ] || detect_caps
+
+[ "$all" ] ||
 while [ "$1" ]; do
 	case $1 in
 	--include|-i)
diff --git a/makefile b/makefile
index 950028c..07c8061 100644
--- a/makefile
+++ b/makefile
@@ -24,7 +24,7 @@ LDFLAGS =
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-all: $(BIN) readme man
+all: $(BIN) man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
@@ -51,7 +51,7 @@ debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
 debug: $(BIN)
 
 tests:
-	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
+	$(CC) $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
 	$(TESTS_DIR)/run
 
 format:
@@ -70,6 +70,6 @@ readme: $(BIN)
 man: $(BIN)
 	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
 		'/^USAGE/ { $$0=usage } 1' \
-		doc/mojitos.pre.1 > doc/mojitos.1 2>/dev/null
+		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
 .PHONY: all clean mojitos debug format tests readme man
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
index b9f16de..c9e0797 100755
--- a/tools/update-readme-usage.sh
+++ b/tools/update-readme-usage.sh
@@ -5,8 +5,24 @@ try() { "$@" || die "cannot $*"; }
 yell() { echo "$0: $*" >&2; }
 echo() { printf '%s\n' "$*"; }
 
-usage=$(./bin/mojitos)
-[ -n "$usage" ] || die 'empty usage. try to recompile mojitos.'
+try ./configure.sh --all
+try make mojitos
+usage=$(
+	./bin/mojitos |
+		awk '
+			/^SENSORS/ {
+				$0 = ""
+				printf "```\n"
+				printf "\n"
+				printf "The following is an exhaustive list of all the sensors (it is very likely\n"
+				printf "that one will not have all the sensors activated in his build):\n"
+				printf "```bash\n"
+				printf "SENSORS:"
+			}
+			{ print }
+		'
+)
+[ -n "$usage" ] || die 'empty usage. cannot continue.'
 
 try awk -v "usage=$usage" '
 	/^Usage/ {
@@ -14,7 +30,11 @@ try awk -v "usage=$usage" '
 		del = 1
 	}
 	{
-		if (del == 1) {
+		if (del == 1 || del == 2) {
+			if (match($0, "^```")) {
+				del++
+			}
+		} else if (del == 3) {
 			if (match($0, "^```")) {
 				del = 0
 				print $0
-- 
GitLab


From 9544a1e31849f953c498ebaa861d27a004628c90 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Feb 2023 18:02:56 +0100
Subject: [PATCH 163/229] the option to dump all options is now a long option

---
 makefile      | 2 +-
 src/mojitos.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/makefile b/makefile
index 07c8061..cd9be75 100644
--- a/makefile
+++ b/makefile
@@ -68,7 +68,7 @@ readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
 
 man: $(BIN)
-	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
+	awk -v "usage=$$($(BIN_DIR)/$(BIN) --dump-opts)" \
 		'/^USAGE/ { $$0=usage } 1' \
 		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
diff --git a/src/mojitos.c b/src/mojitos.c
index 3ecf111..343ec21 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -24,6 +24,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include "util.h"
@@ -219,7 +220,7 @@ int main(int argc, char **argv)
         usage(argv);
     }
 
-    if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '1' && argv[1][2] == '\0') {
+    if (argc == 2 && strcmp(argv[1], "--dump-opts") == 0) {
         dumpopts(opts, NB_OPT, NB_SENSOR_OPT);
         exit(EXIT_SUCCESS);
     }
-- 
GitLab


From 927e0fe276ab52a3ef796cd3239734e49ea65ba4 Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Wed, 15 Feb 2023 10:48:41 +0100
Subject: [PATCH 164/229] trying different build options

---
 .gitignore     | 20 ++++++++++----------
 .gitlab-ci.yml | 28 ++++++++++++++++++++++++++++
 configure.sh   |  2 +-
 3 files changed, 39 insertions(+), 11 deletions(-)

diff --git a/.gitignore b/.gitignore
index dd136f4..c9b9c0e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,10 +1,10 @@
-src/counters_option.h
-src/captors.h
-tests/run
-bin
-obj
-*.swp
-*.swo
-.vscode
-doc/test_main_ex
-doc/info_reader_ex
+src/counters_option.h
+src/captors.h
+tests/run
+bin
+obj
+*.swp
+*.swo
+.vscode
+doc/test_main_ex
+doc/info_reader_ex
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 91608c4..2052da5 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,31 @@
+stages:
+  - build-option
+  - build
+
+job-build-counters:
+  stage: build-option
+  script:
+    - ./configure.sh -u counters
+    - make
+
+job-build-load:
+  stage: build-option
+  script:
+    - ./configure.sh -u load
+    - make
+
+job-build-network:
+  stage: build-option
+  script:
+    - ./configure.sh -u network
+    - make
+
+job-build-rapl:
+  stage: build-option
+  script:
+    - ./configure.sh -u rapl
+    - make
+
 job-build:
   stage: build
   script:
diff --git a/configure.sh b/configure.sh
index 2d21bf5..d272629 100755
--- a/configure.sh
+++ b/configure.sh
@@ -33,7 +33,7 @@ usage() {
 	printf -- '-i | --include      :   include captor, can be called multiple times\n' >&2
 	printf -- '-l | --list-captors :   list all captors and exit\n' >&2
 	printf -- '-u | --unique       :   only include the specified captor\n' >&2
-	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
+	printf -- '                        if this option is used, any use of `-e` or `-i` will be ignored\n' >&2
 	exit 1
 }
 
-- 
GitLab


From 4691e8d7633fe2a17c7c82e9ec5655e80da58b82 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Feb 2023 16:40:07 +0100
Subject: [PATCH 165/229] the README.md file now present all sensors

- add `--all` option to configure.sh
- makefile: readme is no longer a "all" dependency
- plus some minor changes
---
 README.md                    |  9 +++++++++
 configure.sh                 | 14 +++++++++++---
 makefile                     |  6 +++---
 tools/update-readme-usage.sh | 26 +++++++++++++++++++++++---
 4 files changed, 46 insertions(+), 9 deletions(-)

diff --git a/README.md b/README.md
index 95b6d7e..869c358 100644
--- a/README.md
+++ b/README.md
@@ -21,13 +21,22 @@ OPTIONS:
 -s|--overhead-stats
 	enable overhead statistics (nanoseconds).
 
+```
+
+The following is an exhaustive list of all the sensors (it is very likely
+that one will not have all the sensors activated in his build):
+```bash
 SENSORS:
+-a|--amd-rapl
+	AMD RAPL
 -p|--perf-list <perf_list>
 	performance counters
 	perf_list is a coma separated list of performance counters.
 	Ex: instructions,cache_misses
 -l|--list
 	list the available performance counters and quit
+-i|--monitor-infiniband <infiniband_path>
+	infiniband monitoring (if infiniband_path is X, tries to detect it automatically)
 -u|--sysload
 	system load
 -d|--net-dev <net_dev>
diff --git a/configure.sh b/configure.sh
index 196aaf8..3f82c3b 100755
--- a/configure.sh
+++ b/configure.sh
@@ -26,18 +26,19 @@ debug=0
 target_hdr=src/sensors.h
 target_mk=sensors.mk
 
-nonsensor='counters_option|optparse|sensors|util|info_reader'
+nonsensor='counters_option|sensors|util'
 
 hdr_blacklist=$nonsensor
 hdr_whitelist=''
 
 usage() {
-	printf -- 'Usage: %s [-l] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
+	printf -- 'Usage: %s [-la] [-e <sensor>] [-i <sensor>] [-u <sensor>]\n' "$(basename "$0")" >&2
 	printf -- '-e | --exclude      :   exclude sensor, can be called multiple times\n' >&2
 	printf -- '-i | --include      :   include sensor, can be called multiple times\n' >&2
 	printf -- '-l | --list-sensors :   list all sensors and exit\n' >&2
 	printf -- '-u | --unique       :   only include the specified sensor\n' >&2
 	printf -- '                        if this option is used, any usage of `-e` or `-i` will be ignored\n' >&2
+	printf -- '-a | --all          :   include all sensors, meant to be used only by the makefile\n' >&2
 	exit 1
 }
 
@@ -134,8 +135,15 @@ detect_caps() {
 	[ $(ls -1 /sys/class/hwmon | wc -l) -gt 0 ] && hdr_whitelist="${hdr_whitelist}|temperature"
 }
 
-detect_caps
+case $1 in
+--all|-a)
+	all=1
+	;;
+esac
 
+[ "$all" ] || detect_caps
+
+[ "$all" ] ||
 while [ "$1" ]; do
 	case $1 in
 	--include|-i)
diff --git a/makefile b/makefile
index 646a015..9d24542 100644
--- a/makefile
+++ b/makefile
@@ -24,7 +24,7 @@ LDFLAGS =
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
 
-all: $(BIN) readme man
+all: $(BIN) man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
@@ -51,7 +51,7 @@ debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
 debug: $(BIN)
 
 tests:
-	gcc $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
+	$(CC) $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
 	$(TESTS_DIR)/run
 
 format:
@@ -72,6 +72,6 @@ readme: $(BIN)
 man: $(BIN)
 	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
 		'/^USAGE/ { $$0=usage } 1' \
-		doc/mojitos.pre.1 > doc/mojitos.1 2>/dev/null
+		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
 .PHONY: all clean mojitos debug format tests readme man
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
index ad2f88f..2c1950e 100755
--- a/tools/update-readme-usage.sh
+++ b/tools/update-readme-usage.sh
@@ -8,8 +8,24 @@ try() { "$@" || die "cannot $*"; }
 yell() { echo "$0: $*" >&2; }
 echo() { printf '%s\n' "$*"; }
 
-usage=$(./bin/mojitos)
-[ -n "$usage" ] || die 'empty usage. try to recompile mojitos.'
+try ./configure.sh --all
+try make mojitos
+usage=$(
+	./bin/mojitos |
+		awk '
+			/^SENSORS/ {
+				$0 = ""
+				printf "```\n"
+				printf "\n"
+				printf "The following is an exhaustive list of all the sensors (it is very likely\n"
+				printf "that one will not have all the sensors activated in his build):\n"
+				printf "```bash\n"
+				printf "SENSORS:"
+			}
+			{ print }
+		'
+)
+[ -n "$usage" ] || die 'empty usage. cannot continue.'
 
 try awk -v "usage=$usage" '
 	/^Usage/ {
@@ -17,7 +33,11 @@ try awk -v "usage=$usage" '
 		del = 1
 	}
 	{
-		if (del == 1) {
+		if (del == 1 || del == 2) {
+			if (match($0, "^```")) {
+				del++
+			}
+		} else if (del == 3) {
 			if (match($0, "^```")) {
 				del = 0
 				print $0
-- 
GitLab


From 83536ab019b525c21714b1650c5bc255efa454ca Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Feb 2023 18:02:56 +0100
Subject: [PATCH 166/229] the option to dump all options is now a long option

---
 makefile      | 2 +-
 src/mojitos.c | 3 ++-
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/makefile b/makefile
index 9d24542..a197961 100644
--- a/makefile
+++ b/makefile
@@ -70,7 +70,7 @@ readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
 
 man: $(BIN)
-	awk -v "usage=$$($(BIN_DIR)/$(BIN) -1)" \
+	awk -v "usage=$$($(BIN_DIR)/$(BIN) --dump-opts)" \
 		'/^USAGE/ { $$0=usage } 1' \
 		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
diff --git a/src/mojitos.c b/src/mojitos.c
index 4274b6a..e8cb6fa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -23,6 +23,7 @@
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <unistd.h>
 #include "util.h"
@@ -218,7 +219,7 @@ int main(int argc, char **argv)
         usage(argv);
     }
 
-    if (argc == 2 && argv[1][0] == '-' && argv[1][1] == '1' && argv[1][2] == '\0') {
+    if (argc == 2 && strcmp(argv[1], "--dump-opts") == 0) {
         dumpopts(opts, NB_OPT, NB_SENSOR_OPT);
         exit(EXIT_SUCCESS);
     }
-- 
GitLab


From 5d36e20bd88712be509e2271c842411fc647f251 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Wed, 15 Feb 2023 19:08:53 +0100
Subject: [PATCH 167/229] remove bc(1) dependency in configure.sh

---
 configure.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.sh b/configure.sh
index 3f82c3b..4f6375b 100755
--- a/configure.sh
+++ b/configure.sh
@@ -63,9 +63,9 @@ gen_sensors_h() {
 		for sensor in $sensors; do
 			sed -n 's/.*'"${sensor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${sensor}.h"
 		done |
-			paste -s -d '+' |
-			bc
+			paste -s -d '+'
 	)
+	nb_sensor_opts=$(eval "echo \$(($nb_sensor_opts))")
 
 	dprint sensors >&2
 	dprint nb_sensor_opts >&2
-- 
GitLab


From af9d66eb766053d851018c3cad6e95ea29f680e0 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Tue, 7 Feb 2023 14:08:42 +0000
Subject: [PATCH 168/229] fix: make tests

---
 tests/info_reader.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 19d9c0a..5000f48 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -19,7 +19,7 @@
 *******************************************************/
 
 #include "small_test.h"
-#include "./../src/info_reader.h"
+#include "./../lib/info_reader.h"
 
 TFUNCTION(test_replace_first, {
     // useful variables :
-- 
GitLab


From a985ebc78334dec2a3b32e5882d2effa8353598f Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 13:26:09 +0000
Subject: [PATCH 169/229] update Copyright date

---
 configure.sh                 |  3 +++
 doc/sensor_ex.c              | 20 ++++++++++++++++++++
 doc/sensor_ex.h              | 20 ++++++++++++++++++++
 src/counters.c               |  2 +-
 src/counters.h               |  2 +-
 src/counters_option.sh       |  2 +-
 src/infiniband.c             |  2 +-
 src/infiniband.h             |  2 +-
 src/load.c                   |  2 +-
 src/load.h                   |  2 +-
 src/mojitos.c                |  3 +--
 src/network.c                |  2 +-
 src/network.h                |  2 +-
 src/temperature.c            |  2 +-
 src/temperature.h            |  2 +-
 src/util.h                   |  2 +-
 tools/update-readme-usage.sh |  3 +++
 17 files changed, 59 insertions(+), 14 deletions(-)

diff --git a/configure.sh b/configure.sh
index 6b48fb5..3f82c3b 100755
--- a/configure.sh
+++ b/configure.sh
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
 try() { "$@" || die "cannot $*"; }
 die() { yell "$*"; exit 111; }
 yell() { echo "$0: $*" >&2; }
diff --git a/doc/sensor_ex.c b/doc/sensor_ex.c
index 6b10076..d37cbeb 100644
--- a/doc/sensor_ex.c
+++ b/doc/sensor_ex.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
 /*
  * compilation:
  *
diff --git a/doc/sensor_ex.h b/doc/sensor_ex.h
index a040558..9fd95d3 100644
--- a/doc/sensor_ex.h
+++ b/doc/sensor_ex.h
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
 /*
  * Example of a basic sensor: an accumulator
 **/
diff --git a/src/counters.c b/src/counters.c
index d42ceae..1a7027e 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/counters.h b/src/counters.h
index 0304a07..4374cd1 100644
--- a/src/counters.h
+++ b/src/counters.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/counters_option.sh b/src/counters_option.sh
index 7c99eba..38cee08 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 # SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+# Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
 linux_include=/usr/include/linux/perf_event.h
 
diff --git a/src/infiniband.c b/src/infiniband.c
index 303795e..2314e1d 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/infiniband.h b/src/infiniband.h
index fac05f8..e30d78b 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/load.c b/src/load.c
index 1c049ce..64502e5 100644
--- a/src/load.c
+++ b/src/load.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2019-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2019-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/load.h b/src/load.h
index 038b263..6d8d298 100644
--- a/src/load.h
+++ b/src/load.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/mojitos.c b/src/mojitos.c
index 343ec21..e8cb6fa 100644
--- a/src/mojitos.c
+++ b/src/mojitos.c
@@ -1,6 +1,5 @@
 /*******************************************************
-
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/network.c b/src/network.c
index 543a053..74d8bb9 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/network.h b/src/network.h
index 994651a..a158dbb 100644
--- a/src/network.h
+++ b/src/network.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2019 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/temperature.c b/src/temperature.c
index acc0702..bcddb22 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/temperature.h b/src/temperature.h
index 8609dba..e70554d 100644
--- a/src/temperature.h
+++ b/src/temperature.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2018-2021 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/src/util.h b/src/util.h
index 23978c1..e422d07 100644
--- a/src/util.h
+++ b/src/util.h
@@ -1,5 +1,5 @@
 /*******************************************************
- Copyright (C) 2022-2023 Georges Da Costa <georges.da-costa@irit.fr>
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
     This file is part of Mojitos.
 
diff --git a/tools/update-readme-usage.sh b/tools/update-readme-usage.sh
index c9e0797..2c1950e 100755
--- a/tools/update-readme-usage.sh
+++ b/tools/update-readme-usage.sh
@@ -1,5 +1,8 @@
 #!/bin/sh
 
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
 die() { yell "$*"; exit 111; }
 try() { "$@" || die "cannot $*"; }
 yell() { echo "$0: $*" >&2; }
-- 
GitLab


From c24d82e19ac6b9587c00434ebcfffa188d6d61cd Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 13:42:53 +0000
Subject: [PATCH 170/229] update option

---
 README.md      | 2 +-
 src/amd_rapl.h | 2 +-
 src/rapl.h     | 4 ++--
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/README.md b/README.md
index ac5b2d3..954e7e0 100644
--- a/README.md
+++ b/README.md
@@ -41,7 +41,7 @@ SENSORS:
 	system load
 -d|--net-dev <net_dev>
 	network monitoring (if network_device is X, tries to detect it automatically)
--r|--rapl
+-r|--intel-rapl
 	RAPL
 -c|--cpu-temp
 	processor temperature
diff --git a/src/amd_rapl.h b/src/amd_rapl.h
index 1a16db8..e58cc16 100644
--- a/src/amd_rapl.h
+++ b/src/amd_rapl.h
@@ -34,7 +34,7 @@ Sensor amd_rapl = {
 Optparse amd_rapl_opt[1] = {
     {
         .longname = "amd-rapl",
-        .shortname = 'a',
+        .shortname = 'r',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
         .usage_msg = "AMD RAPL",
diff --git a/src/rapl.h b/src/rapl.h
index a02624d..7720f07 100644
--- a/src/rapl.h
+++ b/src/rapl.h
@@ -33,11 +33,11 @@ Sensor rapl = {
 
 Optparse rapl_opt[1] = {
     {
-        .longname = "rapl",
+        .longname = "intel-rapl",
         .shortname = 'r',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "RAPL",
+        .usage_msg = "INTEL RAPL",
     },
 };
 
-- 
GitLab


From e3c98657d45ec85eaa22ba237c17f60410f43542 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 14:19:14 +0000
Subject: [PATCH 171/229] standardise the names of structures

---
 README.md              |  2 +-
 doc/info_reader_ex.c   |  2 +-
 doc/sensor_ex.c        |  9 ++++----
 src/amd_rapl.c         | 52 +++++++++++++++++++++---------------------
 src/counters.c         | 22 +++++++++---------
 src/counters_option.sh |  6 ++---
 src/infiniband.c       |  6 +++--
 src/network.c          |  9 ++++----
 src/rapl.c             | 16 ++++++-------
 src/temperature.c      | 13 ++++++-----
 tests/amd_rapl.c       | 26 ++++++++++-----------
 11 files changed, 84 insertions(+), 79 deletions(-)

diff --git a/README.md b/README.md
index 954e7e0..869c358 100644
--- a/README.md
+++ b/README.md
@@ -42,7 +42,7 @@ SENSORS:
 -d|--net-dev <net_dev>
 	network monitoring (if network_device is X, tries to detect it automatically)
 -r|--intel-rapl
-	RAPL
+	INTEL RAPL
 -c|--cpu-temp
 	processor temperature
 ```
diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index 2e76251..f1e6d96 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -20,7 +20,7 @@
 
 
 // ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
-#include "./../src/info_reader.h"
+#include "./../lib/info_reader.h"
 
 #define MAX_PROCS 64
 
diff --git a/doc/sensor_ex.c b/doc/sensor_ex.c
index d37cbeb..5fc8eeb 100644
--- a/doc/sensor_ex.c
+++ b/doc/sensor_ex.c
@@ -60,9 +60,10 @@ gcc -std=gnu99 -Wall -Wpedantic -I./lib -I./doc -I./src -g -Og obj/util.o obj/mo
 
 #define NB_SENSOR 3
 
-struct accumulator_t {
+struct Accumulator {
     int v[NB_SENSOR];
 };
+typedef struct Accumulator Accumulator;
 
 void _get_acc(int v[NB_SENSOR])
 {
@@ -77,7 +78,7 @@ unsigned int init_acc(char *none, void **ptr)
     /* there is none in this case, so this parameter is not used */
     UNUSED(none);
 
-    struct accumulator_t *state = malloc(sizeof(struct accumulator_t));
+    Accumulator *state = malloc(sizeof(Accumulator));
 
     for (int i = 0; i < NB_SENSOR; i++) {
         state->v[i] = -1;
@@ -91,7 +92,7 @@ unsigned int init_acc(char *none, void **ptr)
 
 unsigned int get_acc(uint64_t *results, void *ptr)
 {
-    struct accumulator_t *state = (struct accumulator_t *)ptr;
+    Accumulator *state = (Accumulator *)ptr;
 
     _get_acc(state->v);
 
@@ -113,7 +114,7 @@ void label_acc(char **labels, void *none)
 
 void clean_acc(void *ptr)
 {
-    struct accumulator_t *state = (struct accumulator_t *)ptr;
+    Accumulator *state = (Accumulator *)ptr;
 
     if (state == NULL) {
         return;
diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 805e698..34ccb47 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -41,7 +41,7 @@ static const uint64_t energy_core_msr = 0xC001029A;
 // ------------------------------FILE_PATHS
 static const char *base_str = "/dev/cpu/%d/msr";
 
-struct cpu_sensor_t {
+struct CpuSensor {
     unsigned int cpu_id;
     unsigned int package_id;
     unsigned int core_id;
@@ -52,13 +52,13 @@ struct cpu_sensor_t {
     unsigned int energy_units;
     uint64_t core_energy;
 };
-typedef struct cpu_sensor_t cpu_sensor_t;
+typedef struct CpuSensor CpuSensor;
 
-struct _amd_rapl_t {
-    cpu_sensor_t *sensors;
+struct AmdRapl {
+    CpuSensor *sensors;
     unsigned int sensor_count;
 };
-typedef struct _amd_rapl_t _amd_rapl_t;
+typedef struct AmdRapl AmdRapl;
 
 // -----------------------------INFO_READER
 
@@ -75,19 +75,19 @@ static GenericPointer uint_allocator(char *s)
 
 static void _set_cpu_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->cpu_id = (unsigned int) data;
 }
 
 static void _set_package_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->package_id = (unsigned int) data;
 }
 
 static void _set_core_id(GenericPointer storage, GenericPointer data)
 {
-    cpu_sensor_t *cpu = (cpu_sensor_t *) storage;
+    CpuSensor *cpu = (CpuSensor *) storage;
     cpu->core_id = (unsigned int) data;
 }
 
@@ -98,13 +98,13 @@ static KeyFinder keys[NB_KEYS] = {
 };
 
 
-static unsigned int parse_cpuinfo(cpu_sensor_t *storage, unsigned int capacity)
+static unsigned int parse_cpuinfo(CpuSensor *storage, unsigned int capacity)
 {
     Parser parser = {
         .storage = (GenericPointer) storage,
         .nb_stored = 0,
         .capacity = capacity,
-        .storage_struct_size = sizeof(cpu_sensor_t),
+        .storage_struct_size = sizeof(CpuSensor),
         .keys = keys,
         .nb_keys = NB_KEYS,
         .file = fopen(cpuinfo, "r")
@@ -171,9 +171,9 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 // -----------------------------------DEBUG
 
 #ifdef DEBUG
-void debug_print_sensor(cpu_sensor_t *sensor)
+void debug_print_sensor(CpuSensor *sensor)
 {
-    //CASSERT(sizeof(cpu_sensor_t) == 56, amd_rapl_c);
+    //CASSERT(sizeof(CpuSensor) == 56, amd_rapl_c);
     printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
            sensor->cpu_id,
            sensor->package_id,
@@ -185,7 +185,7 @@ void debug_print_sensor(cpu_sensor_t *sensor)
           );
 }
 
-void debug_print_amd_rapl(_amd_rapl_t *rapl)
+void debug_print_amd_rapl(AmdRapl *rapl)
 {
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         debug_print_sensor(&rapl->sensors[i]);
@@ -213,7 +213,7 @@ unsigned int get_nb_cpu()
     return n_cpu;
 }
 
-void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, cpu_sensor_t *sensors, unsigned int nb_sensor)
+void get_arch(unsigned int *ret_nb_package, unsigned int *ret_nb_core, CpuSensor *sensors, unsigned int nb_sensor)
 {
     unsigned int nb_package = 0;
     unsigned int nb_core = 0;
@@ -238,7 +238,7 @@ char *get_name(unsigned int cpu_id)
     return name;
 }
 
-void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
+void update_cpu_sensor(CpuSensor *sensor, uint64_t *energy_consumed)
 {
     sensor->energy_units = read_unit(sensor->fd);
     uint64_t raw_core_energy = read_raw_core_energy(sensor->fd);
@@ -248,7 +248,7 @@ void update_cpu_sensor(cpu_sensor_t *sensor, uint64_t *energy_consumed)
     sensor->core_energy = core_energy;
 }
 
-unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
+unsigned int is_duplicate(CpuSensor *sensor,unsigned int nb_core, unsigned int nb_package, unsigned char map[nb_core][nb_package])
 {
     if (map[sensor->core_id][sensor->package_id] == 1) {
         return 0;
@@ -257,7 +257,7 @@ unsigned int is_duplicate(cpu_sensor_t *sensor,unsigned int nb_core, unsigned in
     return 1;
 }
 
-void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
+void init_cpu_sensor(CpuSensor *sensor, CpuSensor *cpu_info)
 {
     static char filename[BUFFER_SIZE];
     snprintf(filename,BUFFER_SIZE, base_str, cpu_info->cpu_id);
@@ -269,18 +269,18 @@ void init_cpu_sensor(cpu_sensor_t *sensor, cpu_sensor_t *cpu_info)
         exit(127);
     }
 
-    memcpy(sensor, cpu_info, sizeof(cpu_sensor_t));
+    memcpy(sensor, cpu_info, sizeof(CpuSensor));
     sensor->name = get_name(sensor->cpu_id);
     sensor->fd = fd;
 }
 
-void clean_cpu_sensor(cpu_sensor_t *sensor)
+void clean_cpu_sensor(CpuSensor *sensor)
 {
     close(sensor->fd);
     free(sensor->name);
 }
 
-void free_amd_rapl(_amd_rapl_t *rapl)
+void free_amd_rapl(AmdRapl *rapl)
 {
     free(rapl->sensors);
     free(rapl);
@@ -299,7 +299,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
         exit(127);
     }
 
-    cpu_sensor_t *cpu_information = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    CpuSensor *cpu_information = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor));
     if (parse_cpuinfo(cpu_information, max_cpus)) {
         free(cpu_information);
         PANIC(1, "cpuinfo");
@@ -311,7 +311,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
     unsigned char cpu_map[nb_core][nb_package];
     memset(cpu_map, 0, sizeof(cpu_map));
-    cpu_sensor_t *sensors = (cpu_sensor_t *) calloc(max_cpus, sizeof(cpu_sensor_t));
+    CpuSensor *sensors = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor));
 
     unsigned int sensor_count = 0;
     for (unsigned int i = 0; i < max_cpus; i++) {
@@ -322,7 +322,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     }
     free(cpu_information);
 
-    _amd_rapl_t *rapl = (_amd_rapl_t *) calloc(1, sizeof(_amd_rapl_t));
+    AmdRapl *rapl = (AmdRapl *) calloc(1, sizeof(AmdRapl));
     rapl->sensors = sensors;
     rapl->sensor_count = sensor_count;
     *ptr = (void *) rapl;
@@ -332,7 +332,7 @@ unsigned int init_amd_rapl(char *none, void **ptr)
 
 unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         update_cpu_sensor(&rapl->sensors[i], &results[i]);
     }
@@ -341,7 +341,7 @@ unsigned int get_amd_rapl(uint64_t *results, void *ptr)
 
 void label_amd_rapl(char **labels, void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
     for (unsigned int i = 0; i < rapl->sensor_count; i++) {
         labels[i] = rapl->sensors[i].name;
     }
@@ -349,7 +349,7 @@ void label_amd_rapl(char **labels, void *ptr)
 
 void clean_amd_rapl(void *ptr)
 {
-    _amd_rapl_t *rapl = (_amd_rapl_t *) ptr;
+    AmdRapl *rapl = (AmdRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->sensor_count; ++i) {
         clean_cpu_sensor(&rapl->sensors[i]);
diff --git a/src/counters.c b/src/counters.c
index 1a7027e..e809f88 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -30,7 +30,7 @@
 #include "util.h"
 
 
-struct _counter_t {
+struct Counter {
     int nbcores;
     int nbperf;
     int **counters;
@@ -40,7 +40,7 @@ struct _counter_t {
     int *perf_indexes;
 
 };
-typedef struct _counter_t *counter_t;
+typedef struct Counter Counter;
 
 #include "counters_option.h"
 
@@ -105,7 +105,7 @@ static long perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
     return res;
 }
 
-counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
+Counter *_init_counters(const int nb_perf, const __u32 *types, const __u64 *names)
 {
     struct perf_event_attr pe;
     unsigned int nbcores = sysconf(_SC_NPROCESSORS_ONLN);
@@ -113,7 +113,7 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
     pe.size = sizeof(struct perf_event_attr);
     pe.disabled = 1;
 
-    counter_t counters = malloc(sizeof(struct _counter_t));
+    Counter *counters = malloc(sizeof(struct Counter));
     counters->nbperf = nb_perf;
     counters->nbcores = nbcores;
     counters->counters = malloc(nb_perf * sizeof(int *));
@@ -133,7 +133,7 @@ counter_t _init_counters(const int nb_perf, const __u32 *types, const __u64 *nam
 
 void clean_counters(void *ptr)
 {
-    counter_t counters = (counter_t) ptr;
+    Counter *counters = (Counter *) ptr;
 
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -151,7 +151,7 @@ void clean_counters(void *ptr)
     free(counters);
 }
 
-void start_counters(counter_t counters)
+void start_counters(Counter *counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -160,7 +160,7 @@ void start_counters(counter_t counters)
     }
 }
 
-void reset_counters(counter_t counters)
+void reset_counters(Counter *counters)
 {
     for (int counter = 0; counter < counters->nbperf; counter++) {
         for (int core = 0; core < counters->nbcores; core++) {
@@ -169,7 +169,7 @@ void reset_counters(counter_t counters)
     }
 }
 
-void _get_counters(counter_t counters, uint64_t *values)
+void _get_counters(Counter *counters, uint64_t *values)
 {
     for (int i = 0; i < counters->nbperf; i++) {
         uint64_t accu = 0;
@@ -202,7 +202,7 @@ unsigned int init_counters(char *args, void **state)
     __u32 *perf_type;
     __u64 *perf_key;
     perf_type_key(&perf_type, &perf_key, perf_indexes, nb_perf);
-    counter_t fd = _init_counters(nb_perf, perf_type, perf_key);
+    Counter *fd = _init_counters(nb_perf, perf_type, perf_key);
     free(perf_type);
     free(perf_key);
 
@@ -218,7 +218,7 @@ unsigned int init_counters(char *args, void **state)
 
 unsigned int get_counters(uint64_t *results, void *ptr)
 {
-    counter_t state = (counter_t) ptr;
+    Counter *state = (Counter *) ptr;
 
     _get_counters(state, state->tmp_counters_values);
 
@@ -232,7 +232,7 @@ unsigned int get_counters(uint64_t *results, void *ptr)
 
 void label_counters(char **labels, void *ptr)
 {
-    counter_t state = (counter_t) ptr;
+    Counter *state = (Counter *) ptr;
 
     for (int i = 0; i < state->nbperf; i++) {
         labels[i] = perf_static_info[state->perf_indexes[i]].name;
diff --git a/src/counters_option.sh b/src/counters_option.sh
index 38cee08..76f9275 100644
--- a/src/counters_option.sh
+++ b/src/counters_option.sh
@@ -6,13 +6,13 @@
 linux_include=/usr/include/linux/perf_event.h
 
 echo '
-typedef struct counter_option {
+typedef struct CounterOption{
     char *name;
     __u32 perf_type;
     __u64 perf_key;
-} counter_option;
+} CounterOption;
 
-static counter_option perf_static_info[] = {'
+static CounterOption perf_static_info[] = {'
 
 nb=0
 
diff --git a/src/infiniband.c b/src/infiniband.c
index 2314e1d..bbc0fee 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -27,11 +27,13 @@
 
 #define NB_SENSOR 4
 
-struct network_t {
+struct Network {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
 };
+typedef struct Network Network;
+
 unsigned int _get_network(uint64_t *results, int *sources);
 
 
@@ -60,7 +62,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
                          "%s/port_xmit_data"
                         };
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+    Network *state = malloc(sizeof(Network));
 
     char buffer[1024];
     for (int i = 0; i < NB_SENSOR; i++) {
diff --git a/src/network.c b/src/network.c
index 74d8bb9..d361d47 100644
--- a/src/network.c
+++ b/src/network.c
@@ -28,11 +28,12 @@
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
-struct network_t {
+struct Network {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
 };
+typedef struct Network Network;
 
 unsigned int _get_network(uint64_t *results, int *sources)
 {
@@ -92,7 +93,7 @@ unsigned int init_network(char *dev, void **ptr)
                          "/sys/class/net/%s/statistics/tx_bytes"
                         };
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+    Network *state = malloc(sizeof(Network));
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
@@ -108,7 +109,7 @@ unsigned int init_network(char *dev, void **ptr)
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
-    struct network_t *state = (struct network_t *) ptr;
+    Network *state = (Network *) ptr;
     _get_network(state->tmp_values, state->sources);
 
     for (int i = 0; i < NB_SENSOR; i++) {
@@ -121,7 +122,7 @@ unsigned int get_network(uint64_t *results, void *ptr)
 
 void clean_network(void *ptr)
 {
-    struct network_t *state = (struct network_t *) ptr;
+    Network *state = (Network *) ptr;
 
     if (state == NULL) {
         return;
diff --git a/src/rapl.c b/src/rapl.c
index 8a04d31..5d7eca7 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -52,7 +52,7 @@ void test_append(char *name, int i)
 }
 
 
-struct _rapl_t {
+struct IntelRapl {
     unsigned int nb;
     char **names;
     int *fids;
@@ -60,10 +60,10 @@ struct _rapl_t {
     uint64_t *tmp_values;
 
 };
-typedef struct _rapl_t _rapl_t;
+typedef struct IntelRapl IntelRapl;
 
 
-void add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
+void add_rapl_source(IntelRapl *rapl, char *name, char *energy_uj)
 {
     rapl->nb += 1;
     rapl->names = realloc(rapl->names, sizeof(char **)*rapl->nb);
@@ -85,7 +85,7 @@ void add_rapl_source(_rapl_t *rapl, char *name, char *energy_uj)
 }
 
 
-void _get_rapl(uint64_t *values, _rapl_t *rapl)
+void _get_rapl(uint64_t *values, IntelRapl *rapl)
 {
     static char buffer[512];
 
@@ -104,7 +104,7 @@ void _get_rapl(uint64_t *values, _rapl_t *rapl)
 unsigned int init_rapl(char *none, void **ptr)
 {
     UNUSED(none);
-    _rapl_t *rapl = malloc(sizeof(_rapl_t));
+    IntelRapl *rapl = malloc(sizeof(IntelRapl));
     rapl->nb = 0;
     rapl->names = NULL;
     rapl->fids = NULL;
@@ -161,7 +161,7 @@ unsigned int init_rapl(char *none, void **ptr)
 
 unsigned int get_rapl(uint64_t *results, void *ptr)
 {
-    _rapl_t *state = (_rapl_t *) ptr;
+    IntelRapl *state = (IntelRapl *) ptr;
     _get_rapl(state->tmp_values, state);
 
     for (unsigned int i = 0; i < state->nb; i++) {
@@ -174,7 +174,7 @@ unsigned int get_rapl(uint64_t *results, void *ptr)
 
 void clean_rapl(void *ptr)
 {
-    _rapl_t *rapl = (_rapl_t *) ptr;
+    IntelRapl *rapl = (IntelRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->nb; i++) {
         free(rapl->names[i]);
@@ -191,7 +191,7 @@ void clean_rapl(void *ptr)
 
 void label_rapl(char **labels, void *ptr)
 {
-    _rapl_t *rapl = (_rapl_t *) ptr;
+    IntelRapl *rapl = (IntelRapl *) ptr;
 
     for (unsigned int i = 0; i < rapl->nb; i++) {
         labels[i] = rapl->names[i];
diff --git a/src/temperature.c b/src/temperature.c
index bcddb22..a9cf74b 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -26,11 +26,12 @@
 #include <stdint.h>
 #include "util.h"
 
-struct temperature_t {
+struct Temperature {
     char **label_list;
     int *fid_list;
     int nb_elem;
 };
+typedef struct Temperature Temperature;
 
 int get_string(char *filename, char *buffer, int max_size)
 {
@@ -61,7 +62,7 @@ void add_to_list(char ***list_name, char *source, int nb_elem)
 
 }
 
-void add_temperature_sensor(int id_rep, struct temperature_t *state)
+void add_temperature_sensor(int id_rep, Temperature *state)
 {
     static int key = 0;
     static char buffer_filename[512];
@@ -109,7 +110,7 @@ void add_temperature_sensor(int id_rep, struct temperature_t *state)
 unsigned int init_temperature(char *args, void **ptr)
 {
     UNUSED(args);
-    struct temperature_t *state = malloc(sizeof(struct temperature_t));
+    Temperature *state = malloc(sizeof(Temperature));
     state->nb_elem = 0;
     state->label_list = NULL;
     state->fid_list = NULL;
@@ -136,7 +137,7 @@ unsigned int init_temperature(char *args, void **ptr)
 
 unsigned int get_temperature(uint64_t *results, void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
     static char buffer[512];
 
     for (int i = 0; i < state->nb_elem; i++) {
@@ -152,7 +153,7 @@ unsigned int get_temperature(uint64_t *results, void *ptr)
 
 void clean_temperature(void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
 
     for (int i = 0; i < state->nb_elem; i++) {
         free(state->label_list[i]);
@@ -166,7 +167,7 @@ void clean_temperature(void *ptr)
 
 void label_temperature(char **labels, void *ptr)
 {
-    struct temperature_t *state = (struct temperature_t *)ptr;
+    Temperature *state = (Temperature *)ptr;
 
     for (int i = 0; i < state->nb_elem; i++) {
         labels[i] = state->label_list[i];
diff --git a/tests/amd_rapl.c b/tests/amd_rapl.c
index 0485099..7c05ab5 100644
--- a/tests/amd_rapl.c
+++ b/tests/amd_rapl.c
@@ -107,7 +107,7 @@ TFUNCTION(test_get_name, {
 #define NONE 0
 #define DUMMY_SENSOR(__sensor, __cpu_id, __name) \
 do {                                             \
-  __sensor = (cpu_sensor_t) {                    \
+  __sensor = (CpuSensor) {                    \
     .cpu_id = __cpu_id,                          \
     .package_id = NONE,                          \
     .core_id = NONE,                             \
@@ -120,15 +120,15 @@ do {                                             \
 
 #define DUMMY_RAPL(__rapl, __sensors, __sensors_count) \
 do {                                                   \
-    __rapl = (_amd_rapl_t) {                           \
+    __rapl = (AmdRapl) {                           \
         .sensors = __sensors,                          \
         .sensor_count = __sensors_count                \
     };                                                 \
 } while(0);
 
 TFUNCTION(test_label_amd_rapl, {
-    cpu_sensor_t sensors[100];
-    _amd_rapl_t rapl;
+    CpuSensor sensors[100];
+    AmdRapl rapl;
     char *results[100];
     char expecteds[10][100];
     uint64_t nb = 0;
@@ -190,7 +190,7 @@ TFUNCTION(test_label_amd_rapl, {
 
 #define DUMMY_CPUINFO(__sensor, __cpu_id, __package_id, __core_id) \
 do {                                                               \
-    __sensor = (cpu_sensor_t) {                                    \
+    __sensor = (CpuSensor) {                                    \
         .cpu_id = __cpu_id,                                        \
         .package_id = __package_id,                                \
         .core_id = __core_id,                                      \
@@ -207,13 +207,13 @@ TFUNCTION(test_is_duplicate, {
     static const unsigned int max_cpu = 10;
 
     unsigned char map[nb_core][nb_package];
-    cpu_sensor_t cpu_information[max_cpu];
+    CpuSensor cpu_information[max_cpu];
     unsigned int results[max_cpu];
     unsigned int expecteds[max_cpu];
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     expecteds[0] = 1;
     expecteds[1] = 0;
@@ -226,7 +226,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 1);
     expecteds[0] = 1;
@@ -240,7 +240,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 0);
     expecteds[0] = 1;
@@ -254,7 +254,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 1, 0);
     expecteds[0] = 1;
@@ -268,7 +268,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 1, 1);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     expecteds[0] = 1;
@@ -282,7 +282,7 @@ TFUNCTION(test_is_duplicate, {
 
     // -- Setup
     memset(map, NONE, sizeof(map));
-    memset(cpu_information,NONE, sizeof(cpu_sensor_t) * max_cpu);
+    memset(cpu_information,NONE, sizeof(CpuSensor) * max_cpu);
     DUMMY_CPUINFO(cpu_information[0], 0, 0, 0);
     DUMMY_CPUINFO(cpu_information[1], 0, 0, 1);
     DUMMY_CPUINFO(cpu_information[2], 0, 1, 0);
@@ -317,7 +317,7 @@ TFILE_ENTRY_POINT(test_amd_rapl, {
 int main()
 {
     static const unsigned int time = 10;
-    _amd_rapl_t *rapl = NULL;
+    AmdRapl *rapl = NULL;
     unsigned int count_cpu = init_amd_rapl(NULL, (void **) &rapl);
     uint64_t results[count_cpu];
     char *labels[count_cpu];
-- 
GitLab


From d5978ba397b79ecc3442e96e10bdb62177b7f868 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 14:46:28 +0000
Subject: [PATCH 172/229] sprintf -> snprintf

---
 src/amd_rapl.c    |  3 ++-
 src/counters.c    |  2 +-
 src/infiniband.c  |  2 +-
 src/network.c     |  2 +-
 src/rapl.c        | 35 +++++++++++++++--------------------
 src/temperature.c | 22 ++++++++++++----------
 6 files changed, 32 insertions(+), 34 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 34ccb47..1e08517 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -161,6 +161,7 @@ uint64_t raw_to_microjoule(uint64_t raw, unsigned int unit)
     // Joule * 1000000 -> uJoule
     return (uint64_t) (((double) raw * to_microjoule) / (double)(1U << unit));
 }
+
 uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 {
     // raw * (1 / (unit^2)) -> Joule
@@ -202,7 +203,7 @@ unsigned int get_nb_cpu()
 
     unsigned int n_cpu = 0;
     for (;; n_cpu++) {
-        sprintf(filename, base_str, n_cpu);
+        snprintf(filename, BUFFER_SIZE, base_str, n_cpu);
 
         int fd = open(filename, O_RDONLY);
         if (fd < 0) {
diff --git a/src/counters.c b/src/counters.c
index e809f88..8013ff8 100644
--- a/src/counters.c
+++ b/src/counters.c
@@ -52,7 +52,7 @@ void *show_all_counters(void *none1, size_t none2)
     UNUSED(none1);
     UNUSED(none2);
     exit(EXIT_SUCCESS);
-    return NULL;	/* not reached */
+    return NULL; /* not reached */
 }
 
 void perf_type_key(__u32 **perf_type, __u64 **perf_key, int *indexes, int nb)
diff --git a/src/infiniband.c b/src/infiniband.c
index bbc0fee..aa4a8de 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -66,7 +66,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
 
     char buffer[1024];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer, filenames[i], infi_path);
+        snprintf(buffer, 1024, filenames[i], infi_path);
         state->sources[i] = open(buffer, O_RDONLY);
     }
 
diff --git a/src/network.c b/src/network.c
index d361d47..977b92e 100644
--- a/src/network.c
+++ b/src/network.c
@@ -97,7 +97,7 @@ unsigned int init_network(char *dev, void **ptr)
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, filenames[i], dev);
+        sprintf(buffer2, 256, filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
     }
 
diff --git a/src/rapl.c b/src/rapl.c
index 5d7eca7..eb88553 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -28,6 +28,7 @@
 #include "util.h"
 
 #define MAX_HEADER 128
+#define BUFFER_SIZE 1024
 
 char *get_rapl_string(const char *filename)
 {
@@ -40,15 +41,16 @@ char *get_rapl_string(const char *filename)
     int nb = read(fd, result, MAX_HEADER);
     close(fd);
     result[nb - 1] = 0;
-    return (result);
+    return result;
 }
 
-void test_append(char *name, int i)
+void append(char *name, int i, size_t buffer_size)
 {
-    //char last = name[strlen(name)-1];
-    //if (last>='0' && last <= '9')
-    //  return;
-    sprintf(name + strlen(name), "%d", i);
+    size_t name_len = strlen(name);
+    char* ptr = name + name_len;
+
+    size_t remaining_space = buffer_size - name_len;
+    snprintf(ptr, remaining_space, "%d", i);
 }
 
 
@@ -109,40 +111,33 @@ unsigned int init_rapl(char *none, void **ptr)
     rapl->names = NULL;
     rapl->fids = NULL;
 
-    char buffer[1024];
+    char buffer[BUFFER_SIZE];
     char *name_base = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/%s";
     char *name_sub = "/sys/devices/virtual/powercap/intel-rapl/intel-rapl:%d/intel-rapl:%d:%d/%s";
 
     for (unsigned int i = 0;; i++) {
-        sprintf(buffer, name_base, i, "name");
+        snprintf(buffer, BUFFER_SIZE, name_base, i, "name");
         char *tmp = get_rapl_string(buffer);
 
         if (tmp == NULL) {
             break;
         }
 
-        //printf("%s\n", tmp);
-        test_append(tmp, i);
-        //printf("%s -> %s\n", buffer, tmp);
-
-        sprintf(buffer, name_base, i, "energy_uj");
+        append(tmp, i, MAX_HEADER);
+        snprintf(buffer, BUFFER_SIZE, name_base, i, "energy_uj");
         add_rapl_source(rapl, tmp, buffer);
         free(tmp);
 
         for (unsigned int j = 0;; j++) {
-            sprintf(buffer, name_sub, i, i, j, "name");
+            snprintf(buffer, BUFFER_SIZE, name_sub, i, i, j, "name");
             char *tmp_sub = get_rapl_string(buffer);
 
             if (tmp_sub == NULL) {
                 break;
             }
 
-            //printf("%s\n", tmp_sub);
-            test_append(tmp_sub, i);
-            //printf("%s -> %s\n", buffer, tmp_sub);
-
-
-            sprintf(buffer, name_sub, i, i, j, "energy_uj");
+            append(tmp_sub, i, MAX_HEADER);
+            snprintf(buffer, BUFFER_SIZE, name_sub, i, i, j, "energy_uj");
             add_rapl_source(rapl, tmp_sub, buffer);
 
             free(tmp_sub);
diff --git a/src/temperature.c b/src/temperature.c
index a9cf74b..1dc1099 100644
--- a/src/temperature.c
+++ b/src/temperature.c
@@ -26,6 +26,8 @@
 #include <stdint.h>
 #include "util.h"
 
+#define BUFFER_SIZE 512
+
 struct Temperature {
     char **label_list;
     int *fid_list;
@@ -65,13 +67,13 @@ void add_to_list(char ***list_name, char *source, int nb_elem)
 void add_temperature_sensor(int id_rep, Temperature *state)
 {
     static int key = 0;
-    static char buffer_filename[512];
-    static char buffer_label[512];
+    static char buffer_filename[BUFFER_SIZE];
+    static char buffer_label[BUFFER_SIZE];
 
-    int delta = sprintf(buffer_label, "Temp_%d_", key);
+    int delta = snprintf(buffer_label, BUFFER_SIZE, "Temp_%d_", key);
 
     for (int i = 1;; i++) {
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
+        snprintf(buffer_filename, BUFFER_SIZE, "/sys/class/hwmon/hwmon%d/temp%d_label", id_rep, i);
 
         if (get_string(buffer_filename, buffer_label + delta, 100) == -1) {
             break;
@@ -89,7 +91,7 @@ void add_temperature_sensor(int id_rep, Temperature *state)
 
         add_to_list(&state->label_list, buffer_label, state->nb_elem);
 
-        sprintf(buffer_filename, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
+        snprintf(buffer_filename, BUFFER_SIZE, "/sys/class/hwmon/hwmon%d/temp%d_input", id_rep, i);
         state->fid_list = realloc(state->fid_list, (state->nb_elem + 1) * sizeof(int));
         int fd = open(buffer_filename, O_RDONLY);
 
@@ -116,11 +118,11 @@ unsigned int init_temperature(char *args, void **ptr)
     state->fid_list = NULL;
 
     char base_name[] = "/sys/class/hwmon/hwmon%d/name";
-    static char name[512];
-    static char buffer[512];
+    static char name[BUFFER_SIZE];
+    static char buffer[BUFFER_SIZE];
 
     int i = 0;
-    sprintf(name, base_name, i);
+    snprintf(name, BUFFER_SIZE, base_name, i);
 
     while (get_string(name, buffer, 8) != -1) {
         if (strcmp(buffer, "coretemp") == 0) {
@@ -128,7 +130,7 @@ unsigned int init_temperature(char *args, void **ptr)
         }
 
         i++;
-        sprintf(name, base_name, i);
+        snprintf(name, BUFFER_SIZE, base_name, i);
     }
 
     *ptr = (void *) state;
@@ -138,7 +140,7 @@ unsigned int init_temperature(char *args, void **ptr)
 unsigned int get_temperature(uint64_t *results, void *ptr)
 {
     Temperature *state = (Temperature *)ptr;
-    static char buffer[512];
+    static char buffer[BUFFER_SIZE];
 
     for (int i = 0; i < state->nb_elem; i++) {
         if (pread(state->fid_list[i], buffer, 100, 0) < 0) {
-- 
GitLab


From 8546c84fb3145e6dbbe80b035aa6afc5ac602b9d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:05:13 +0000
Subject: [PATCH 173/229] format

---
 src/network.c | 2 +-
 src/rapl.c    | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/network.c b/src/network.c
index 977b92e..37d2373 100644
--- a/src/network.c
+++ b/src/network.c
@@ -97,7 +97,7 @@ unsigned int init_network(char *dev, void **ptr)
 
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
-        sprintf(buffer2, 256, filenames[i], dev);
+        snprintf(buffer2, 256, filenames[i], dev);
         state->sources[i] = open(buffer2, O_RDONLY);
     }
 
diff --git a/src/rapl.c b/src/rapl.c
index eb88553..3d13367 100644
--- a/src/rapl.c
+++ b/src/rapl.c
@@ -47,7 +47,7 @@ char *get_rapl_string(const char *filename)
 void append(char *name, int i, size_t buffer_size)
 {
     size_t name_len = strlen(name);
-    char* ptr = name + name_len;
+    char *ptr = name + name_len;
 
     size_t remaining_space = buffer_size - name_len;
     snprintf(ptr, remaining_space, "%d", i);
-- 
GitLab


From 8e57326b26cd88dd37b615c1d19275bb4b1bf3f4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:06:47 +0000
Subject: [PATCH 174/229] add authors

---
 AUTHORS | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/AUTHORS b/AUTHORS
index 0bfc663..13ddd11 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,4 @@
-Georges Da Costa georges.da-costa@irit.fr
\ No newline at end of file
+Georges Da Costa georges.da-costa@irit.fr
+Floréal Risso floreal.risso@univ-tlse3.fr
+Alexis Paronnaud alexis.paronnaud@univ-tlse3.fr
+Téo Tinarrage teo.tinarrage@univ-tlse3.fr
-- 
GitLab


From c27d5e1f5677eba93117e50ec76d31bc0d8b7c13 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ3-tlse.fr>
Date: Mon, 13 Feb 2023 15:11:11 +0000
Subject: [PATCH 175/229] clear doc

---
 makefile | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/makefile b/makefile
index cd9be75..a197961 100644
--- a/makefile
+++ b/makefile
@@ -62,7 +62,9 @@ format:
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
 		$(SRC_DIR)/counters_option.h \
-		$(TESTS_DIR)/run
+		$(TESTS_DIR)/run \
+		$(DOC_DIR)/test_main_ex \
+		$(DOC_DIR)/info_reader_ex
 
 readme: $(BIN)
 	sh ./tools/update-readme-usage.sh
-- 
GitLab


From 9edca7def641888d20204f5afb390434a5f33a5d Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Wed, 15 Feb 2023 19:08:53 +0100
Subject: [PATCH 176/229] remove bc(1) dependency in configure.sh

---
 configure.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/configure.sh b/configure.sh
index 3f82c3b..4f6375b 100755
--- a/configure.sh
+++ b/configure.sh
@@ -63,9 +63,9 @@ gen_sensors_h() {
 		for sensor in $sensors; do
 			sed -n 's/.*'"${sensor}"'_opt\[\([0-9]\+\)\].*/\1/p' "src/${sensor}.h"
 		done |
-			paste -s -d '+' |
-			bc
+			paste -s -d '+'
 	)
+	nb_sensor_opts=$(eval "echo \$(($nb_sensor_opts))")
 
 	dprint sensors >&2
 	dprint nb_sensor_opts >&2
-- 
GitLab


From de5e735b03a1b8820dd3d2df9bd62438bb1b8463 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Thu, 16 Feb 2023 18:24:28 +0100
Subject: [PATCH 177/229] add quotation marks

---
 configure.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/configure.sh b/configure.sh
index 4f6375b..21c94ef 100755
--- a/configure.sh
+++ b/configure.sh
@@ -107,7 +107,7 @@ gen_sensors_mk() {
 
 detect_caps() {
 	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
-	[ -d /sys/class/infiniband ] && hdr_whitelist=${hdr_whitelist}|infiniband
+	[ -d /sys/class/infiniband ] && hdr_whitelist="${hdr_whitelist}|infiniband"
 	[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
 
 	if [ -r /proc/net/route ]; then
-- 
GitLab


From 82dc9a2e4bf08ff775bd255159fb04bb3e7346d5 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 11:50:56 +0100
Subject: [PATCH 178/229] add some error checking

---
 src/network.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/network.c b/src/network.c
index aee5659..0f23206 100644
--- a/src/network.c
+++ b/src/network.c
@@ -17,14 +17,17 @@
     along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
 
  *******************************************************/
-#include <unistd.h>
+#include <errno.h>
 #include <fcntl.h>
-#include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
-#include <stdint.h>
+#include <unistd.h>
+
 #include "util.h"
 
+#define NB_MAX_DEV 8
 #define NB_SENSOR 4
 
 static char *route = "/proc/net/route";
@@ -39,6 +42,8 @@ struct network_t {
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
     char labels[NB_SENSOR][128];
+    char dev[NB_MAX_DEV][128];
+    int ndev;
 };
 
 unsigned int _get_network(uint64_t *results, int *sources)
@@ -103,7 +108,14 @@ unsigned int init_network(char *dev, void **ptr)
     char buffer2[256];
     for (int i = 0; i < NB_SENSOR; i++) {
         snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
-        state->sources[i] = open(buffer2, O_RDONLY);
+        errno = 0;
+        int fd = open(buffer2, O_RDONLY);
+        if (fd < 0) {
+            perror("init_network: open");
+            free(state);
+            return 0;
+        }
+        state->sources[i] = fd;
         snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
-- 
GitLab


From 1cb227e7cd0d3f6562d06f4266017176daca4ecc Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 17:21:13 +0100
Subject: [PATCH 179/229] add MIN() and MAX() macros to util.h

---
 src/util.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/src/util.h b/src/util.h
index 23978c1..b1fa6e3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -38,6 +38,8 @@
         exit(code);                          \
     } while (0)
 
+#define MIN(a, b) ((a) < (b) ? (a) : (b))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
 
 /**
  * @brief Substracts lhs by rhs, assuming that lhs is a cyclic increment from rhs,
-- 
GitLab


From 5b82667289ec077d9ed9c5658b72d572810fed08 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 20 Feb 2023 17:21:22 +0100
Subject: [PATCH 180/229] network sensor can now detect multiple routes from
 /proc/net/route

note that there is a hard limit to the number of devices the sensor can
watch. this limit is defined by "NB_MAX_DEV" (value of 8 for now)
---
 src/network.c | 170 +++++++++++++++++++++++++++++++++++++-------------
 1 file changed, 125 insertions(+), 45 deletions(-)

diff --git a/src/network.c b/src/network.c
index 0f23206..33fdadf 100644
--- a/src/network.c
+++ b/src/network.c
@@ -38,18 +38,18 @@ char *_labels_network[NB_SENSOR] = {
     "%s:txb",
 };
 struct network_t {
-    uint64_t values[NB_SENSOR];
-    uint64_t tmp_values[NB_SENSOR];
-    int sources[NB_SENSOR];
-    char labels[NB_SENSOR][128];
-    char dev[NB_MAX_DEV][128];
+    uint64_t values[NB_MAX_DEV][NB_SENSOR];
+    uint64_t tmp_values[NB_MAX_DEV][NB_SENSOR];
+    int sources[NB_MAX_DEV][NB_SENSOR];
+    char labels[NB_MAX_DEV][NB_SENSOR][128];
+    char devs[NB_MAX_DEV][128];
     int ndev;
 };
 
-unsigned int _get_network(uint64_t *results, int *sources)
+static void _get_network(uint64_t *results, int *sources)
 {
     if (sources == NULL) {
-        return 0;
+        return;
     }
 
     char buffer[128];
@@ -62,16 +62,47 @@ unsigned int _get_network(uint64_t *results, int *sources)
 
         results[i] = strtoull(buffer, NULL, 10);
     }
+}
+
+static int strchr_refill(int fd, char *buf, int len, char **s, char c)
+{
+    *s = strchr(*s, c);
+
+    if (*s == NULL) {
+        int nbytes = read(fd, buf, len - 1);
+        if (nbytes < 0) {
+            perror("read");
+            return -1;
+        }
+        buf[len - 1] = '\0';
+
+        /* whole file read */
+        if (nbytes == 0) {
+            return 0;
+        }
+
+        *s = strchr(buf, c);
+    }
 
-    return NB_SENSOR;
+    return 1;
 }
 
 unsigned int init_network(char *dev, void **ptr)
 {
     if (dev == NULL) {
-        return 0;
+        exit(1);
     }
 
+    char *filenames[] = {
+        "/sys/class/net/%s/statistics/rx_packets",
+        "/sys/class/net/%s/statistics/rx_bytes",
+        "/sys/class/net/%s/statistics/tx_packets",
+        "/sys/class/net/%s/statistics/tx_bytes",
+    };
+
+    struct network_t *state = malloc(sizeof(struct network_t));
+    memset(state, '\0', sizeof(*state));
+
     if (strcmp(dev, "X") == 0) {
         int fd = open(route, O_RDONLY);
 
@@ -83,59 +114,104 @@ unsigned int init_network(char *dev, void **ptr)
 
         char buffer[1000];
 
-        if (read(fd, buffer, 999) < 0 ) {
-            perror("read");
+        /* skip first line */
+        char *s = buffer;
+        int ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+        if (ret != 1) {
             close(fd);
+            free(state);
             exit(1);
         }
+        s++;
 
-        char *start_of_dev = strchr(buffer, '\n') + 1;
-        char *end_of_dev = strchr(start_of_dev, '\t');
-        *end_of_dev = '\0';
-        dev = start_of_dev;
-        close(fd);
-    }
+        char *start_of_dev = s;
+        /* jump to the end of the device name */
+        ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+        if (ret != 1) {
+            close(fd);
+            free(state);
+            exit(1);
+        }
 
-    char *filenames[] = {
-        "/sys/class/net/%s/statistics/rx_packets",
-        "/sys/class/net/%s/statistics/rx_bytes",
-        "/sys/class/net/%s/statistics/tx_packets",
-        "/sys/class/net/%s/statistics/tx_bytes",
-    };
+        state->ndev++;	// ndev should be equal to 1 at this point
+        memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+               MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+
+        for (;;) {
+            /* jump to the next line */
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\n');
+            if (ret != 1) {
+                break;
+            }
+            s++;
+
+            start_of_dev = s;
+            ret = strchr_refill(fd, buffer, sizeof(buffer), &s, '\t');
+            if (ret != 1) {
+                break;
+            }
+
+            /* compare dev name to the previously saved one */
+            if (strncmp(start_of_dev, state->devs[state->ndev - 1], s - start_of_dev) != 0) {
+                if (state->ndev >= NB_MAX_DEV) {
+                    fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
+                    break;
+                }
+                state->ndev++;
+                memcpy(&(state->devs[state->ndev - 1]), start_of_dev,
+                       MIN((size_t)(sizeof(state->devs[0]) - 1), (size_t)(s - start_of_dev)));
+            }
+        }
 
-    struct network_t *state = malloc(sizeof(struct network_t));
+        close(fd);
+    } else {
+        state->ndev = 1;
+        memcpy(&(state->devs[0]), dev, strlen(dev) + 1);
+    }
 
     char buffer2[256];
-    for (int i = 0; i < NB_SENSOR; i++) {
-        snprintf(buffer2, sizeof(buffer2), filenames[i], dev);
-        errno = 0;
-        int fd = open(buffer2, O_RDONLY);
-        if (fd < 0) {
-            perror("init_network: open");
-            free(state);
-            return 0;
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            snprintf(buffer2, sizeof(buffer2), filenames[j], state->devs[i]);
+            errno = 0;
+            int fd = open(buffer2, O_RDONLY);
+            if (fd < 0) {
+                fprintf(stderr, "init_network: open: %s: %.*s\n", strerror(errno),
+                        (int)sizeof(buffer2), buffer2);
+                free(state);
+                exit(1);
+            }
+            state->sources[i][j] = fd;
+            snprintf(state->labels[i][j], sizeof(state->labels[i][j]), _labels_network[j],
+                     state->devs[i]);
         }
-        state->sources[i] = fd;
-        snprintf(state->labels[i], sizeof(state->labels[i]), _labels_network[i], dev);
     }
 
     *ptr = (void *) state;
-    _get_network(state->values, state->sources);
 
-    return NB_SENSOR;
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->values[i], state->sources[i]);
+    }
+
+    return state->ndev * NB_SENSOR;
 }
 
 unsigned int get_network(uint64_t *results, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
-    _get_network(state->tmp_values, state->sources);
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        _get_network(state->tmp_values[i], state->sources[i]);
+
+        for (int j = 0; j < NB_SENSOR; j++) {
+            results[i*NB_SENSOR + j] = modulo_substraction(state->tmp_values[i][j], state->values[i][j]);
+        }
+
+        memcpy(&(state->values[i]), &(state->tmp_values[i]),
+               NB_SENSOR * sizeof(state->values[i][0]));
     }
 
-    memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
-    return NB_SENSOR;
+    return state->ndev * NB_SENSOR;
 }
 
 void clean_network(void *ptr)
@@ -146,8 +222,10 @@ void clean_network(void *ptr)
         return;
     }
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        close(state->sources[i]);
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            close(state->sources[i][j]);
+        }
     }
 
     free(state);
@@ -157,7 +235,9 @@ void label_network(char **labels, void *ptr)
 {
     struct network_t *state = (struct network_t *) ptr;
 
-    for (int i = 0; i < NB_SENSOR; i++) {
-        labels[i] = state->labels[i];
+    for (int i = 0; i < state->ndev; i++) {
+        for (int j = 0; j < NB_SENSOR; j++) {
+            labels[i*NB_SENSOR + j] = state->labels[i][j];
+        }
     }
 }
-- 
GitLab


From a0c1db322c0c5e6525724a56998c6af634ef322e Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 21 Feb 2023 11:26:50 +0100
Subject: [PATCH 181/229] fix infiniband

---
 src/infiniband.c | 64 ++++++++++++++++++++++++++++++++++++++++++------
 src/infiniband.h |  6 +++--
 2 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/src/infiniband.c b/src/infiniband.c
index aa4a8de..6a5a6b4 100644
--- a/src/infiniband.c
+++ b/src/infiniband.c
@@ -17,25 +17,44 @@
     along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
 
  *******************************************************/
-#include <stdlib.h>
 #include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
 #include <glob.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "util.h"
 
 #define NB_SENSOR 4
 
-struct Network {
+struct Infiniband {
     uint64_t values[NB_SENSOR];
     uint64_t tmp_values[NB_SENSOR];
     int sources[NB_SENSOR];
 };
-typedef struct Network Network;
+typedef struct Infiniband Infiniband;
+
+unsigned int _get_infiniband(uint64_t *results, int *sources)
+{
+    if (sources == NULL) {
+        return 0;
+    }
+
+    char buffer[128];
 
-unsigned int _get_network(uint64_t *results, int *sources);
+    for (int i = 0; i < NB_SENSOR; i++) {
+        if (pread(sources[i], buffer, 127, 0) < 0) {
+            perror("pread");
+            exit(1);
+        }
 
+        results[i] = strtoull(buffer, NULL, 10);
+    }
+
+    return NB_SENSOR;
+}
 
 unsigned int init_infiniband(char *infi_path, void **ptr)
 {
@@ -50,6 +69,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
         glob("/sys/class/infiniband/*/ports/*/counters/", 0, NULL, &res);
 
         if (res.gl_pathc == 0) {
+            fprintf(stderr, "No infiniband found.\n");
             return 0;
         }
 
@@ -62,7 +82,7 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
                          "%s/port_xmit_data"
                         };
 
-    Network *state = malloc(sizeof(Network));
+    Infiniband *state = malloc(sizeof(Infiniband));
 
     char buffer[1024];
     for (int i = 0; i < NB_SENSOR; i++) {
@@ -71,11 +91,39 @@ unsigned int init_infiniband(char *infi_path, void **ptr)
     }
 
     *ptr = (void *) state;
-    _get_network(state->values, state->sources);
+    _get_infiniband(state->values, state->sources);
 
     return NB_SENSOR;
 }
 
+unsigned int get_infiniband(uint64_t *results, void *ptr)
+{
+    Infiniband *state = (Infiniband *) ptr;
+    _get_infiniband(state->tmp_values, state->sources);
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        results[i] = modulo_substraction(state->tmp_values[i], state->values[i]);
+    }
+
+    memcpy(state->values, state->tmp_values, NB_SENSOR * sizeof(uint64_t));
+    return NB_SENSOR;
+}
+
+void clean_infiniband(void *ptr)
+{
+    Infiniband *state = (Infiniband *) ptr;
+
+    if (state == NULL) {
+        return;
+    }
+
+    for (int i = 0; i < NB_SENSOR; i++) {
+        close(state->sources[i]);
+    }
+
+    free(state);
+}
+
 char *_labels_infiniband[NB_SENSOR] = {"irxp", "irxb", "itxp", "itxb"};
 void label_infiniband(char **labels, void *none)
 {
diff --git a/src/infiniband.h b/src/infiniband.h
index e30d78b..8098cf5 100644
--- a/src/infiniband.h
+++ b/src/infiniband.h
@@ -19,12 +19,14 @@
  *******************************************************/
 
 unsigned int init_infiniband(char *infi_path, void **ptr);
+unsigned int get_infiniband(uint64_t *results, void *ptr);
+void clean_infiniband(void *ptr);
 void label_infiniband(char **labels, void *);
 
 Sensor infiniband = {
     .init = init_infiniband,
-    .get = NULL,
-    .clean = NULL,
+    .get = get_infiniband,
+    .clean = clean_infiniband,
     .label = label_infiniband,
     .nb_opt = 1,
 };
-- 
GitLab


From afec2006a9bab8dfda94ef4ddb05d3c1708792c0 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 21 Feb 2023 16:03:02 +0100
Subject: [PATCH 182/229] add "install" and "uninstall" make targets

---
 makefile | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/makefile b/makefile
index a197961..dc852f4 100644
--- a/makefile
+++ b/makefile
@@ -7,6 +7,7 @@ BIN_DIR = bin
 TESTS_DIR = tests
 
 BIN = mojitos
+PREFIX = /usr/local
 
 CAPTOR_OBJ =
 
@@ -74,4 +75,16 @@ man: $(BIN)
 		'/^USAGE/ { $$0=usage } 1' \
 		doc/$(BIN).pre.1 > doc/$(BIN).1 2>/dev/null
 
-.PHONY: all clean mojitos debug format tests readme man
+install: $(BIN) man
+	mkdir -p $(PREFIX)/bin
+	cp $(BIN_DIR)/$(BIN) $(PREFIX)/bin/.
+	chmod 755 $(PREFIX)/bin/$(BIN)
+	mkdir -p $(PREFIX)/share/man/man1
+	cp $(DOC_DIR)/$(BIN).1 $(PREFIX)/share/man/man1/.
+	chmod 644 $(PREFIX)/share/man/man1/$(BIN).1
+
+uninstall:
+	rm -f $(PREFIX)/bin/$(BIN)
+	rm -f $(PREFIX)/share/man/man1/$(BIN).1
+
+.PHONY: all clean mojitos debug format tests readme man install uninstall
-- 
GitLab


From 44b132bf26e445016c9bd6fb75373847d0188b03 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 21 Feb 2023 16:50:00 +0100
Subject: [PATCH 183/229] revise build system (makefile and sensors.mk)

Make it more posix compliant (remove '%.o: %.c %.h' usage, which is
not posix).

Sadly, it appears to not support well separate directories for object and
source files: inference rules do not work, and it recompiles everything
at each invocation even though there is not necessarily any change within
the source files.
---
 configure.sh |  5 +++++
 makefile     | 26 ++++++++++++++++----------
 2 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/configure.sh b/configure.sh
index 21c94ef..747a078 100755
--- a/configure.sh
+++ b/configure.sh
@@ -103,6 +103,11 @@ gen_sensors_mk() {
 		printf '$(OBJ_DIR)/%s.o ' "$sensor"
 	done
 	printf '\n'
+	for sensor in $sensors; do
+		printf '$(OBJ_DIR)/%s.o: $(SRC_DIR)/%s.c $(SRC_DIR)/%s.h $(SRC_DIR)/util.h\n' \
+			"$sensor" "$sensor" "$sensor"
+		printf '\t$(CC) $(CFLAGS) -c $< -o $@\n'
+	done
 }
 
 detect_caps() {
diff --git a/makefile b/makefile
index dc852f4..bd26308 100644
--- a/makefile
+++ b/makefile
@@ -9,14 +9,6 @@ TESTS_DIR = tests
 BIN = mojitos
 PREFIX = /usr/local
 
-CAPTOR_OBJ =
-
-include ./sensors.mk
-
-OBJ =  \
-	$(CAPTOR_OBJ) \
-	$(OBJ_DIR)/util.o
-
 CC = gcc
 CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
 CFLAGS = $(CPPFLAGS) -O3 -Werror
@@ -24,9 +16,23 @@ LDFLAGS =
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-
 all: $(BIN) man
 
+CAPTOR_OBJ =
+
+include ./sensors.mk
+
+OBJ =  \
+	$(CAPTOR_OBJ) \
+	$(OBJ_DIR)/util.o
+
+options:
+	@echo BIN: $(BIN)
+	@echo CC: $(CC)
+	@echo CFLAGS: $(CFLAGS)
+	@echo LDFLAGS: $(LDFLAGS)
+	@echo OBJ: $(OBJ)
+
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
 
@@ -36,7 +42,7 @@ $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
 $(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
-$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c $(SRC_DIR)/%.h
+$(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
 $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
-- 
GitLab


From 745d90b59eadf5e4072c8a6a3ed86d745a674d2a Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Feb 2023 18:58:48 +0100
Subject: [PATCH 184/229] unfinished sensor

---
 src/nvidia_gpu.c | 324 +++++++++++++++++++++++++++++++++++++++++++++++
 src/nvidia_gpu.h |   0
 2 files changed, 324 insertions(+)
 create mode 100644 src/nvidia_gpu.c
 create mode 100644 src/nvidia_gpu.h

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
new file mode 100644
index 0000000..75f0915
--- /dev/null
+++ b/src/nvidia_gpu.c
@@ -0,0 +1,324 @@
+#include <stdio.h>
+#include <stdint.h>
+#include <nvml.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "util.h"
+
+
+// -----------------------------SENSOR_KIND
+typedef enum {
+    CLOCK_SENSOR       = 0,
+    MEMORY_SENSOR      = 1,
+    UTILIZATION_SENSOR = 2,
+
+    COUNT_SENSOR       = 3,
+} SENSOR_KIND;
+
+typedef unsigned int (Initializer) (nvmlDevice_t, void **);
+typedef unsigned int (Getter)      (nvmlDevice_t, uint64_t *, void *);
+typedef void         (Cleaner)     (void *);
+
+typedef struct {
+    void *data;
+
+    Initializer *init;
+    Getter *get;
+    Cleaner *clean;
+} ISensor;
+
+// ----------------------------CLOCK_SENSOR
+// -- All existing clocks
+#if NVML_CLOCK_COUNT != 4
+#error "NVML_CLOCK_COUNT must be equal 4";
+#endif
+
+// -- SM : Streaming Multiprocessor
+static const nvmlClockType_t clocks[NVML_CLOCK_COUNT] = {NVML_CLOCK_GRAPHICS, NVML_CLOCK_SM, NVML_CLOCK_MEM, NVML_CLOCK_VIDEO};
+static const char *clock_names[NVML_CLOCK_COUNT] = {"Graphics", "SM", "Memory", "Video"};
+
+// -- Must contain the clocks compatible with the device
+typedef struct {
+    nvmlClockType_t clocks[NVML_CLOCK_COUNT];
+    unsigned int count;
+} ClockData;
+
+unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
+{
+    ClockData tmp = {0};
+    nvmlReturn_t result;
+    unsigned int clock;
+
+    // -- Test all clocks
+    for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
+        if ((result = nvmlDeviceGetClockInfo(device, clocks[i], &clock)) == NVML_SUCCESS) {
+            tmp.clocks[tmp.count] = clocks[i];
+            tmp.count += 1;
+        } else {
+            fprintf(stderr, "Failed to get %s clock : %s", clock_names[i], nvmlErrorString(result));
+        }
+    }
+
+    // -- No clock avaible
+    if (tmp.count == 0) {
+        return 0;
+    }
+
+    *data = calloc(1, sizeof(ClockData));
+    memcpy(*data, &tmp, sizeof (ClockData));
+    return tmp.count;
+}
+
+unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data)
+{
+    ClockData *clock_data = (ClockData *) data;
+    nvmlReturn_t err;
+    unsigned int clock;
+
+    for (unsigned int i = 0; i < clock_data->count; i++) {
+        nvmlClockType_t clock_type = clock_data->clocks[i];
+
+        if((err = nvmlDeviceGetClockInfo(device, clock_type, &clock)) != NVML_SUCCESS) {
+            fprintf(stderr, "Failed to get %s clock : %s", clock_names[clock_type], nvmlErrorString(err));
+            exit(99);
+        }
+        results[i] = clock;
+    }
+    return clock_data->count;
+}
+
+void clean_clock_sensor(void* data)
+{
+    free(data);
+}
+
+// ---------------------------MEMORY_SENSOR
+typedef enum {
+    FREE_MEMORY  = 0U,
+    USED_MEMORY  = 1U,
+    TOTAL_MEMORY = 2U,
+ 
+    COUNT_MEMORY = 3U,
+} MemoryKind;
+static const char *memory_names[COUNT_MEMORY] = {"Free", "Used", "Total"};
+
+unsigned int init_memory_sensor(nvmlDevice_t device, void **none)
+{
+    UNUSED(none);
+
+    nvmlMemory_t memory;
+    nvmlReturn_t result;
+    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+        return 0;
+    }
+
+    return COUNT_MEMORY;
+}
+
+unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *none)
+{
+    UNUSED(none);
+
+    nvmlMemory_t memory;
+    nvmlReturn_t result;
+    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+        exit(99);
+    }
+
+    results[FREE_MEMORY] = memory.free;
+    results[USED_MEMORY] = memory.used;
+    results[TOTAL_MEMORY] = memory.total;
+    return COUNT_MEMORY;
+}
+
+
+void clean_memory_sensor(void *none)
+{
+    UNUSED(none);
+}
+
+// ----------------------UTILIZATION_SENSOR
+typedef enum {
+    GPU_UTILIZATION    = 0U,
+    MEMORY_UTILIZATION = 1U,
+
+    COUNT_UTILIZATION  = 2U,
+} UtilizationKind;
+
+static const char *utilization_names[COUNT_UTILIZATION] = {"Gpu", "Memory"};
+
+unsigned int init_utilization_sensor(nvmlDevice_t device, void **none);
+{
+    UNUSED(none);
+
+    nvmlReturn_t result;
+    nvmlUtilization_t utilization;
+    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+        return 0;
+    }
+
+    return COUNT_UTILIZATION;
+}
+
+unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void* none)
+{
+    UNUSED(none);
+
+    nvmlReturn_t result;
+    nvmlUtilization_t utilization;
+    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+        exit(99);
+    }
+
+    results[GPU_UTILIZATION] = utilization.gpu;
+    results[MEMORY_UTILIZATION] = utilization.memory;
+    return COUNT_UTILIZATION;
+}
+
+void clean_utilization_sensor(void* none)
+{
+    UNUSED(none);
+}
+
+// ----------------------------ERROR_SENSOR
+// TODO
+
+// ----------------------------------------
+
+typedef struct {
+    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
+    nvmlDevice_t device;
+
+    ISensor sensors[COUNT_SENSOR];
+    unsigned int count;
+} Device;
+
+typedef struct {
+    Device *devices;
+    unsigned int count;
+} NvidiaSensor;
+
+// -------------------------AVAIBLE_SENSORS
+static const ISensor avaible_sensors[COUNT_SENSOR] = {
+    {.init = init_clock_sensor, .get = get_clock_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_memory_sensor, .get = get_memory_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_utilization_sensor, .get = get_utilization_sensor, .clean = clean_memory_sensor, .data = NULL};
+};
+
+// ------------------------DEVICE_FUNCTIONS
+
+unsigned int init_device(unsigned int device_idx, Device *device) {
+    nvmlReturn_t result;
+    nvmlDevice_t nvml_device;
+    if ((result = nvmlDeviceGetByIndex(i, &nvml_device) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device handle for device %d: %s\n", device_idx, nvmlErrorString(result));
+        return 0;
+    }
+
+    if ((result = nvmlDeviceGetName(nvml_device, device->name, NVML_DEVICE_NAME_BUFFER_SIZE))) {
+        fprintf(stderr, "Failed to get device name for device %d: %s\n", device_idx, nvmlErrorString(result));
+        return 0;
+    }
+
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < COUNT_SENSOR; i++) {
+        void* data;
+        if (avaible_sensors.init(nvml_device, &data) != 0) {
+            ISensor *sensor = &device->sensors[count];
+            memcpy(sensor, &avaible_sensors[i], sizeof(ISensor));
+            sensor->data = data;
+            count += 1;
+        }
+    }
+
+    device->device = nvml_device;
+    device->count = count;
+    return count;
+}
+
+unsigned int get_device(Device *device, uint64_t *results) {
+    unsigned int count;
+    nvmlDevice_t nvml_device = device->device;
+    for (unsigned int i = 0; i < device->count; i++) {
+        unsigned int result = device->sensor.get(nvml_device, &device->sensor.data, results);
+        count += result;
+        results += result;
+    }
+
+    return count;
+}
+void clean_device(Device *device) {
+    for (unsigned int i = 0; i < device->count; i++) {
+        device->sensor.clean(&device->sensor.data);
+    }
+}
+
+// ------------------------NVIDIA_INTERFACE
+
+unsigned int init_nvidia_sensor(char *none, void **ptr)
+{
+    UNUSED(none);
+    UNUSED(ptr);
+
+    nvmlReturn_t result;
+    if ((result = nvmlInit()) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to initialize NVML: %s\n", nvmlErrorString(result));
+        exit(1);
+    }
+
+    unsigned int avaible_device_count;
+    if ((result = nvmlDeviceGetCount(&avaible_device_count)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device count : %s\n", nvmlErrorString(result));
+        nvmlShutdown();
+        exit(1);
+    }
+
+    Device* devices = calloc(avaible_device_count, sizeof(Device));
+
+    unsigned int sensor_count = 0;
+    unsigned int device_count = 0;
+    for (unsigned int i = 0; i < avaible_device_count; i++) {
+        unsigned int initialized_count;
+        if ((initialized_count = init_device(&devices[device_count])) != 0) {
+            sensor_count += initialized_count;
+            device_count += 1;
+        }
+    }
+
+    NvidiaSensor *nvidia = (NvidiaSensor*) calloc(1, sizeof(NvidiaSensor));
+    nvidia->devices = devices;
+    nvidia->count = device_count;
+
+    *ptr = (void*) nvidia;
+    return count;
+}
+
+
+unsigned int get_nvidia_sensor(uint64_t *results, void *ptr) {
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    unsigned count = 0;
+
+    for (unsigned int i = 0; i < nvidia.count; i++) {
+        unsigned int result = get_device(&nvidia->devices[i], results);
+        results += result;
+        count += result;
+    }
+
+    return count;
+}
+void label_nvidia_sensor(char **labels, void *ptr);
+
+void clean_nvidia_sensor(void *ptr)
+{
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        clean_device(&nvidia->device[i]);
+    }
+    nvmlShutdown();
+}
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
new file mode 100644
index 0000000..e69de29
-- 
GitLab


From 54bba401354dcbfc30804bea721e9a563b50c778 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 6 Mar 2023 15:20:44 +0100
Subject: [PATCH 185/229] working sensor

---
 src/nvidia_gpu.c | 345 ++++++++++++++++++++++++++++++++++++-----------
 src/nvidia_gpu.h |  43 ++++++
 2 files changed, 309 insertions(+), 79 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 75f0915..22f65a1 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -1,3 +1,23 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
 #include <stdio.h>
 #include <stdint.h>
 #include <nvml.h>
@@ -6,7 +26,6 @@
 
 #include "util.h"
 
-
 // -----------------------------SENSOR_KIND
 typedef enum {
     CLOCK_SENSOR       = 0,
@@ -16,47 +35,82 @@ typedef enum {
     COUNT_SENSOR       = 3,
 } SENSOR_KIND;
 
-typedef unsigned int (Initializer) (nvmlDevice_t, void **);
-typedef unsigned int (Getter)      (nvmlDevice_t, uint64_t *, void *);
-typedef void         (Cleaner)     (void *);
+typedef struct Device Device;
+typedef struct NvidiaSensor NvidiaSensor;
+typedef struct ISensor ISensor;
+typedef struct Sensor Sensor;
 
-typedef struct {
-    void *data;
+// -- Sensor interface
+typedef unsigned int (Initializer) (const Device *, void **);
+typedef unsigned int (Getter)      (uint64_t *, const Device *, void *);
+typedef unsigned int (Labeller)    (char **, void *);
+typedef void         (Cleaner)     (void *);
 
+struct ISensor {
     Initializer *init;
     Getter *get;
+    Labeller *label;
     Cleaner *clean;
-} ISensor;
+};
+
+// -- Sensor
+struct Sensor {
+    void *data;
+    const ISensor *fun;
+};
+
+// -- Device: represents a gpu
+struct Device {
+    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
+    nvmlDevice_t device;
+    unsigned int idx;
+
+    Sensor sensors[COUNT_SENSOR];
+    unsigned int count;
+};
+
+// -- NvidiaSensor: represents the devices
+struct NvidiaSensor {
+    Device *devices;
+    unsigned int count;
+};
+
+// -- Label template
+static const char *label_template = "gpu%u_%s_%s";
 
 // ----------------------------CLOCK_SENSOR
-// -- All existing clocks
-#if NVML_CLOCK_COUNT != 4
-#error "NVML_CLOCK_COUNT must be equal 4";
-#endif
 
+#define CLOCK_LABEL_SIZE 25
+
+// -- All existing clocks
 // -- SM : Streaming Multiprocessor
 static const nvmlClockType_t clocks[NVML_CLOCK_COUNT] = {NVML_CLOCK_GRAPHICS, NVML_CLOCK_SM, NVML_CLOCK_MEM, NVML_CLOCK_VIDEO};
-static const char *clock_names[NVML_CLOCK_COUNT] = {"Graphics", "SM", "Memory", "Video"};
+static const char *clock_names[NVML_CLOCK_COUNT] = {"graphics", "sm", "memory", "video"};
+static const char *clock_base_name = "clk";
 
 // -- Must contain the clocks compatible with the device
 typedef struct {
     nvmlClockType_t clocks[NVML_CLOCK_COUNT];
+    char labels[NVML_CLOCK_COUNT][CLOCK_LABEL_SIZE];
     unsigned int count;
 } ClockData;
 
-unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
+unsigned int init_clock_sensor(const Device *device, void **data)
 {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
     ClockData tmp = {0};
     nvmlReturn_t result;
     unsigned int clock;
 
     // -- Test all clocks
     for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
-        if ((result = nvmlDeviceGetClockInfo(device, clocks[i], &clock)) == NVML_SUCCESS) {
+        if ((result = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
+            snprintf(tmp.labels[tmp.count], CLOCK_LABEL_SIZE, label_template, device_idx, clock_base_name, clock_names[i]);
             tmp.clocks[tmp.count] = clocks[i];
             tmp.count += 1;
         } else {
-            fprintf(stderr, "Failed to get %s clock : %s", clock_names[i], nvmlErrorString(result));
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(result));
         }
     }
 
@@ -70,8 +124,9 @@ unsigned int init_clock_sensor(nvmlDevice_t device, void** data)
     return tmp.count;
 }
 
-unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data)
+unsigned int get_clock_sensor(uint64_t *results, const Device *device, void *data)
 {
+    const nvmlDevice_t nvml_device = device->device;
     ClockData *clock_data = (ClockData *) data;
     nvmlReturn_t err;
     unsigned int clock;
@@ -79,8 +134,8 @@ unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data
     for (unsigned int i = 0; i < clock_data->count; i++) {
         nvmlClockType_t clock_type = clock_data->clocks[i];
 
-        if((err = nvmlDeviceGetClockInfo(device, clock_type, &clock)) != NVML_SUCCESS) {
-            fprintf(stderr, "Failed to get %s clock : %s", clock_names[clock_type], nvmlErrorString(err));
+        if((err = nvmlDeviceGetClockInfo(nvml_device, clock_type, &clock)) != NVML_SUCCESS) {
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[clock_type], nvmlErrorString(err));
             exit(99);
         }
         results[i] = clock;
@@ -88,42 +143,69 @@ unsigned int get_clock_sensor(nvmlDevice_t device, uint64_t *results, void* data
     return clock_data->count;
 }
 
-void clean_clock_sensor(void* data)
+unsigned int label_clock_sensor(char **labels, void *data)
+{
+    ClockData *clock_data = (ClockData *) data;
+
+    for (unsigned int i = 0; i < clock_data->count; i++) {
+        labels[i] = clock_data->labels[i];
+    }
+
+    return clock_data->count;
+}
+
+void clean_clock_sensor(void *data)
 {
     free(data);
 }
 
 // ---------------------------MEMORY_SENSOR
+#define MEMORY_LABEL_SIZE 25
+
 typedef enum {
     FREE_MEMORY  = 0U,
     USED_MEMORY  = 1U,
     TOTAL_MEMORY = 2U,
- 
+
     COUNT_MEMORY = 3U,
 } MemoryKind;
-static const char *memory_names[COUNT_MEMORY] = {"Free", "Used", "Total"};
 
-unsigned int init_memory_sensor(nvmlDevice_t device, void **none)
+static const char *memory_names[COUNT_MEMORY] = {"free", "used", "total"};
+static const char *memory_base_name = "mem";
+
+typedef struct {
+    char labels[COUNT_MEMORY][MEMORY_LABEL_SIZE];
+} MemoryData;
+
+unsigned int init_memory_sensor(const Device *device, void **data)
 {
-    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
 
     nvmlMemory_t memory;
     nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
         return 0;
     }
 
+    MemoryData *memory_data = (MemoryData *) calloc(1, sizeof(MemoryData));
+    for (unsigned int i = 0; i < COUNT_MEMORY; i++) {
+        snprintf(memory_data->labels[i], MEMORY_LABEL_SIZE, label_template, device_idx, memory_base_name, memory_names[i]);
+    }
+
+    *data = (void *) memory_data;
     return COUNT_MEMORY;
 }
 
-unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *none)
+unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *none)
 {
     UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
 
     nvmlMemory_t memory;
     nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(device, &memory)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
         exit(99);
     }
@@ -135,12 +217,23 @@ unsigned int get_memory_sensor(nvmlDevice_t device, uint64_t *results, void *non
 }
 
 
-void clean_memory_sensor(void *none)
+unsigned int label_memory_sensor(char **labels, void* data)
 {
-    UNUSED(none);
+    MemoryData *memory_data = (MemoryData *) data;
+
+    for (unsigned int i = 0; i < COUNT_MEMORY; i++) {
+        labels[i] = memory_data->labels[i];
+    }
+
+    return COUNT_MEMORY;
+}
+void clean_memory_sensor(void *data)
+{
+  free(data);
 }
 
 // ----------------------UTILIZATION_SENSOR
+#define UTILIZATION_LABEL_SIZE 35
 typedef enum {
     GPU_UTILIZATION    = 0U,
     MEMORY_UTILIZATION = 1U,
@@ -148,29 +241,42 @@ typedef enum {
     COUNT_UTILIZATION  = 2U,
 } UtilizationKind;
 
-static const char *utilization_names[COUNT_UTILIZATION] = {"Gpu", "Memory"};
+typedef struct {
+  char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
+} UtilizationData;
+
+static const char *utilization_names[COUNT_UTILIZATION] = {"gpu", "memory"};
+static const char *utilization_base_name = "utilization";
 
-unsigned int init_utilization_sensor(nvmlDevice_t device, void **none);
+unsigned int init_utilization_sensor(const Device *device, void **data)
 {
-    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
 
     nvmlReturn_t result;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
         return 0;
     }
 
+    UtilizationData *utilization_data = (UtilizationData *) calloc(1, sizeof(UtilizationData));
+    for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
+snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
+    }
+
+    *data = (void *) utilization_data;
     return COUNT_UTILIZATION;
 }
 
-unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void* none)
+unsigned int get_utilization_sensor(uint64_t *results, const Device *device, void *none)
 {
     UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
 
     nvmlReturn_t result;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(device, &utilization)) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
         exit(99);
     }
@@ -180,9 +286,19 @@ unsigned int get_utilization_sensor(nvmlDevice_t device, uint64_t *results, void
     return COUNT_UTILIZATION;
 }
 
-void clean_utilization_sensor(void* none)
+unsigned int label_utilization_sensor(char **labels, void* data)
 {
-    UNUSED(none);
+    UtilizationData *utilization_data = (UtilizationData *) data;
+
+    for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
+        labels[i] = utilization_data->labels[i];
+    }
+
+    return COUNT_UTILIZATION;
+}
+void clean_utilization_sensor(void *data)
+{
+    free(data);
 }
 
 // ----------------------------ERROR_SENSOR
@@ -190,32 +306,21 @@ void clean_utilization_sensor(void* none)
 
 // ----------------------------------------
 
-typedef struct {
-    char name[NVML_DEVICE_NAME_BUFFER_SIZE];
-    nvmlDevice_t device;
-
-    ISensor sensors[COUNT_SENSOR];
-    unsigned int count;
-} Device;
-
-typedef struct {
-    Device *devices;
-    unsigned int count;
-} NvidiaSensor;
 
 // -------------------------AVAIBLE_SENSORS
 static const ISensor avaible_sensors[COUNT_SENSOR] = {
-    {.init = init_clock_sensor, .get = get_clock_sensor, .clean = clean_memory_sensor, .data = NULL};
-    {.init = init_memory_sensor, .get = get_memory_sensor, .clean = clean_memory_sensor, .data = NULL};
-    {.init = init_utilization_sensor, .get = get_utilization_sensor, .clean = clean_memory_sensor, .data = NULL};
+    {.init = init_clock_sensor, .get = get_clock_sensor, .label = label_clock_sensor, .clean = clean_clock_sensor},
+    {.init = init_memory_sensor, .get = get_memory_sensor, .label = label_memory_sensor, .clean = clean_memory_sensor},
+    {.init = init_utilization_sensor, .get = get_utilization_sensor, .label = label_utilization_sensor, .clean = clean_utilization_sensor},
 };
 
 // ------------------------DEVICE_FUNCTIONS
 
-unsigned int init_device(unsigned int device_idx, Device *device) {
+unsigned int init_device(unsigned int device_idx, Device *device)
+{
     nvmlReturn_t result;
     nvmlDevice_t nvml_device;
-    if ((result = nvmlDeviceGetByIndex(i, &nvml_device) != NVML_SUCCESS) {
+    if ((result = nvmlDeviceGetHandleByIndex(device_idx, &nvml_device)) != NVML_SUCCESS) {
         fprintf(stderr, "Failed to get device handle for device %d: %s\n", device_idx, nvmlErrorString(result));
         return 0;
     }
@@ -225,39 +330,62 @@ unsigned int init_device(unsigned int device_idx, Device *device) {
         return 0;
     }
 
-    unsigned int count = 0;
+    device->device = nvml_device;
+    device->idx = device_idx;
+
+    unsigned int sensor_count = 0;
+    unsigned int total_count = 0;
+
     for (unsigned int i = 0; i < COUNT_SENSOR; i++) {
-        void* data;
-        if (avaible_sensors.init(nvml_device, &data) != 0) {
-            ISensor *sensor = &device->sensors[count];
-            memcpy(sensor, &avaible_sensors[i], sizeof(ISensor));
-            sensor->data = data;
-            count += 1;
+        Sensor *sensor = &device->sensors[sensor_count];
+        sensor->fun = &avaible_sensors[i];
+        unsigned int count;
+
+        if ((count = sensor->fun->init(device, &sensor->data)) != 0) {
+            sensor_count += 1;
+            total_count += count;
         }
     }
 
-    device->device = nvml_device;
-    device->count = count;
-    return count;
+    device->count = sensor_count;
+    return total_count;
 }
 
-unsigned int get_device(Device *device, uint64_t *results) {
-    unsigned int count;
-    nvmlDevice_t nvml_device = device->device;
+unsigned int get_device(uint64_t *results, Device *device)
+{
+    unsigned int count = 0;
     for (unsigned int i = 0; i < device->count; i++) {
-        unsigned int result = device->sensor.get(nvml_device, &device->sensor.data, results);
+        Sensor *sensor = &device->sensors[i];
+        unsigned int result = sensor->fun->get(results, device, sensor->data);
         count += result;
         results += result;
     }
 
     return count;
 }
-void clean_device(Device *device) {
+
+unsigned int label_device(char **labels, Device *device)
+{
+    unsigned int count = 0;
+    for (unsigned int i = 0; i < device->count; i++) {
+        Sensor *sensor = &device->sensors[i];
+        unsigned int result = sensor->fun->label(labels, sensor->data);
+        labels += result;
+        count += result;
+    }
+
+    return count;
+}
+
+void clean_device(Device *device)
+{
     for (unsigned int i = 0; i < device->count; i++) {
-        device->sensor.clean(&device->sensor.data);
+        Sensor *sensor = &device->sensors[i];
+        sensor->fun->clean(sensor->data);
     }
 }
 
+
 // ------------------------NVIDIA_INTERFACE
 
 unsigned int init_nvidia_sensor(char *none, void **ptr)
@@ -278,47 +406,106 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
         exit(1);
     }
 
-    Device* devices = calloc(avaible_device_count, sizeof(Device));
+    Device *devices = calloc(avaible_device_count, sizeof(Device));
 
     unsigned int sensor_count = 0;
     unsigned int device_count = 0;
     for (unsigned int i = 0; i < avaible_device_count; i++) {
         unsigned int initialized_count;
-        if ((initialized_count = init_device(&devices[device_count])) != 0) {
+        if ((initialized_count = init_device(i, &devices[device_count])) != 0) {
             sensor_count += initialized_count;
             device_count += 1;
         }
     }
 
-    NvidiaSensor *nvidia = (NvidiaSensor*) calloc(1, sizeof(NvidiaSensor));
+    NvidiaSensor *nvidia = (NvidiaSensor *) calloc(1, sizeof(NvidiaSensor));
     nvidia->devices = devices;
     nvidia->count = device_count;
 
-    *ptr = (void*) nvidia;
-    return count;
+    *ptr = (void *) nvidia;
+    return sensor_count;
 }
 
 
-unsigned int get_nvidia_sensor(uint64_t *results, void *ptr) {
+unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
+{
     NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
     unsigned count = 0;
 
-    for (unsigned int i = 0; i < nvidia.count; i++) {
-        unsigned int result = get_device(&nvidia->devices[i], results);
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        unsigned int result = get_device(results, &nvidia->devices[i]);
         results += result;
         count += result;
     }
 
     return count;
 }
-void label_nvidia_sensor(char **labels, void *ptr);
+
+unsigned int label_nvidia_sensor(char **labels, void *ptr) {
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    unsigned count = 0;
+
+    for (unsigned int i = 0; i < nvidia->count; i++) {
+        unsigned int result = label_device(labels, &nvidia->devices[i]);
+        labels += result;
+        count += result;
+    }
+
+    return count;
+}
 
 void clean_nvidia_sensor(void *ptr)
 {
     NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
-        clean_device(&nvidia->device[i]);
+        clean_device(&nvidia->devices[i]);
     }
+
+    free(nvidia->devices);
+    free(nvidia);
     nvmlShutdown();
 }
+
+// -------------------------------TEST_MAIN
+
+#ifdef __NVIDIA__MAIN__TEST
+int main()
+{
+    void *ptr = NULL;
+    char *none = NULL;
+
+    unsigned int sensor_count = init_nvidia_sensor(none, &ptr);
+
+    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    printf("%d\n", nvidia->count);
+    printf("%u\n", sensor_count);
+
+  
+
+    uint64_t results[sensor_count];
+    char *labels[sensor_count];
+
+    memset(results, 0, sensor_count * sizeof(uint64_t));
+    memset(labels, 0, sensor_count * sizeof(char**));
+
+
+    unsigned count_label = label_nvidia_sensor(labels, ptr);
+    unsigned count_get = get_nvidia_sensor(results, ptr);
+    printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
+
+    
+    for (unsigned int i = 0; i < sensor_count; i++) {
+        printf("%s ", labels[i]);
+    }
+    printf("\n");
+    for (unsigned int i = 0; i < sensor_count; i++) {
+        printf("%lu ", results[i]);
+    }
+    printf("\n");
+    printf("sensor_count: %d\n", sensor_count);
+
+    clean_nvidia_sensor(ptr);
+}
+#endif
+
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index e69de29..6f2419e 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -0,0 +1,43 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_nvidia_sensor(char *, void **);
+unsigned int get_nvidia_sensor(uint64_t *results, void *);
+void clean_nvidia_sensor(void *);
+void label_nvidia_sensor(char **labels, void *);
+
+
+Sensor nvidia_gpu = {
+    .init = init_nvidia_sensor,
+    .get = get_nvidia_sensor,
+    .clean = clean_nvidia_sensor,
+    .label = label_nvidia_sensor,
+    .nb_opt = 1,
+};
+
+Optparse nvidia_gpu_opt[1] = {
+    {
+        .longname = "nvidia",
+        .shortname = 'n',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "NVIDIA GPU",
+    },
+};
-- 
GitLab


From 5b6f0ec8b3ac06859e2f5294e1210ddefdb393de Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 6 Mar 2023 15:51:47 +0100
Subject: [PATCH 186/229] pedantic

---
 src/nvidia_gpu.c | 55 ++++++++++++++++++++++++++----------------------
 src/nvidia_gpu.h | 18 ++++++++--------
 2 files changed, 39 insertions(+), 34 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 22f65a1..479eecb 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -20,10 +20,14 @@
 
 #include <stdio.h>
 #include <stdint.h>
-#include <nvml.h>
 #include <stdlib.h>
 #include <string.h>
 
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wpedantic"
+#include <nvml.h>
+#pragma GCC diagnostic pop
+
 #include "util.h"
 
 // -----------------------------SENSOR_KIND
@@ -36,7 +40,7 @@ typedef enum {
 } SENSOR_KIND;
 
 typedef struct Device Device;
-typedef struct NvidiaSensor NvidiaSensor;
+typedef struct NvidiaGpu NvidiaGpu;
 typedef struct ISensor ISensor;
 typedef struct Sensor Sensor;
 
@@ -69,8 +73,8 @@ struct Device {
     unsigned int count;
 };
 
-// -- NvidiaSensor: represents the devices
-struct NvidiaSensor {
+// -- NvidiaGpu: represents the devices
+struct NvidiaGpu {
     Device *devices;
     unsigned int count;
 };
@@ -217,7 +221,7 @@ unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *no
 }
 
 
-unsigned int label_memory_sensor(char **labels, void* data)
+unsigned int label_memory_sensor(char **labels, void *data)
 {
     MemoryData *memory_data = (MemoryData *) data;
 
@@ -229,7 +233,7 @@ unsigned int label_memory_sensor(char **labels, void* data)
 }
 void clean_memory_sensor(void *data)
 {
-  free(data);
+    free(data);
 }
 
 // ----------------------UTILIZATION_SENSOR
@@ -242,7 +246,7 @@ typedef enum {
 } UtilizationKind;
 
 typedef struct {
-  char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
+    char labels[COUNT_UTILIZATION][UTILIZATION_LABEL_SIZE];
 } UtilizationData;
 
 static const char *utilization_names[COUNT_UTILIZATION] = {"gpu", "memory"};
@@ -262,7 +266,7 @@ unsigned int init_utilization_sensor(const Device *device, void **data)
 
     UtilizationData *utilization_data = (UtilizationData *) calloc(1, sizeof(UtilizationData));
     for (unsigned int i = 0; i < COUNT_UTILIZATION; i++) {
-snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
+        snprintf(utilization_data->labels[i], UTILIZATION_LABEL_SIZE, label_template, device_idx, utilization_base_name, utilization_names[i]);
     }
 
     *data = (void *) utilization_data;
@@ -286,7 +290,7 @@ unsigned int get_utilization_sensor(uint64_t *results, const Device *device, voi
     return COUNT_UTILIZATION;
 }
 
-unsigned int label_utilization_sensor(char **labels, void* data)
+unsigned int label_utilization_sensor(char **labels, void *data)
 {
     UtilizationData *utilization_data = (UtilizationData *) data;
 
@@ -388,7 +392,7 @@ void clean_device(Device *device)
 
 // ------------------------NVIDIA_INTERFACE
 
-unsigned int init_nvidia_sensor(char *none, void **ptr)
+unsigned int init_nvidia_gpu(char *none, void **ptr)
 {
     UNUSED(none);
     UNUSED(ptr);
@@ -418,7 +422,7 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
         }
     }
 
-    NvidiaSensor *nvidia = (NvidiaSensor *) calloc(1, sizeof(NvidiaSensor));
+    NvidiaGpu *nvidia = (NvidiaGpu *) calloc(1, sizeof(NvidiaGpu));
     nvidia->devices = devices;
     nvidia->count = device_count;
 
@@ -427,9 +431,9 @@ unsigned int init_nvidia_sensor(char *none, void **ptr)
 }
 
 
-unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
+unsigned int get_nvidia_gpu(uint64_t *results, void *ptr)
 {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     unsigned count = 0;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
@@ -441,8 +445,9 @@ unsigned int get_nvidia_sensor(uint64_t *results, void *ptr)
     return count;
 }
 
-unsigned int label_nvidia_sensor(char **labels, void *ptr) {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+unsigned int label_nvidia_gpu(char **labels, void *ptr)
+{
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     unsigned count = 0;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
@@ -454,9 +459,9 @@ unsigned int label_nvidia_sensor(char **labels, void *ptr) {
     return count;
 }
 
-void clean_nvidia_sensor(void *ptr)
+void clean_nvidia_gpu(void *ptr)
 {
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
 
     for (unsigned int i = 0; i < nvidia->count; i++) {
         clean_device(&nvidia->devices[i]);
@@ -475,26 +480,26 @@ int main()
     void *ptr = NULL;
     char *none = NULL;
 
-    unsigned int sensor_count = init_nvidia_sensor(none, &ptr);
+    unsigned int sensor_count = init_nvidia_gpu(none, &ptr);
 
-    NvidiaSensor *nvidia = (NvidiaSensor *) ptr;
+    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
     printf("%d\n", nvidia->count);
     printf("%u\n", sensor_count);
 
-  
+
 
     uint64_t results[sensor_count];
     char *labels[sensor_count];
 
     memset(results, 0, sensor_count * sizeof(uint64_t));
-    memset(labels, 0, sensor_count * sizeof(char**));
+    memset(labels, 0, sensor_count * sizeof(char **));
 
 
-    unsigned count_label = label_nvidia_sensor(labels, ptr);
-    unsigned count_get = get_nvidia_sensor(results, ptr);
+    unsigned count_label = label_nvidia_gpu(labels, ptr);
+    unsigned count_get = get_nvidia_gpu(results, ptr);
     printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
 
-    
+
     for (unsigned int i = 0; i < sensor_count; i++) {
         printf("%s ", labels[i]);
     }
@@ -505,7 +510,7 @@ int main()
     printf("\n");
     printf("sensor_count: %d\n", sensor_count);
 
-    clean_nvidia_sensor(ptr);
+    clean_nvidia_gpu(ptr);
 }
 #endif
 
diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index 6f2419e..c741055 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -18,23 +18,23 @@
 
  *******************************************************/
 
-unsigned int init_nvidia_sensor(char *, void **);
-unsigned int get_nvidia_sensor(uint64_t *results, void *);
-void clean_nvidia_sensor(void *);
-void label_nvidia_sensor(char **labels, void *);
+unsigned int init_nvidia_gpu(char *, void **);
+unsigned int get_nvidia_gpu(uint64_t *results, void *);
+void clean_nvidia_gpu(void *);
+void label_nvidia_gpu(char **labels, void *);
 
 
 Sensor nvidia_gpu = {
-    .init = init_nvidia_sensor,
-    .get = get_nvidia_sensor,
-    .clean = clean_nvidia_sensor,
-    .label = label_nvidia_sensor,
+    .init = init_nvidia_gpu,
+    .get = get_nvidia_gpu,
+    .clean = clean_nvidia_gpu,
+    .label = label_nvidia_gpu,
     .nb_opt = 1,
 };
 
 Optparse nvidia_gpu_opt[1] = {
     {
-        .longname = "nvidia",
+        .longname = "nvidia-gpu",
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-- 
GitLab


From 5c6076ad0729836751c1a1284357d69a9e26bf46 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 7 Mar 2023 09:04:34 +0100
Subject: [PATCH 187/229] temp change of the make file

---
 makefile | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/makefile b/makefile
index a197961..81a4e41 100644
--- a/makefile
+++ b/makefile
@@ -17,9 +17,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib -I/usr/local/cuda/include
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS =
+LDFLAGS = -L/usr/local/cuda/lib64 -lnvidia-ml
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
@@ -27,7 +27,7 @@ ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 all: $(BIN) man
 
 $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
-	$(CC) $(LDFLAGS) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o
+	$(CC) -o $(BIN_DIR)/$(BIN) $(OBJ) $(OBJ_DIR)/$(BIN).o $(LDFLAGS)
 
 $(OBJ): $(OBJ_DIR)
 $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
-- 
GitLab


From 8709019f8d0c1c986ec94ce25792d7942b2ece87 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Tue, 7 Mar 2023 11:36:46 +0100
Subject: [PATCH 188/229] compare new dev name to all saved ones

---
 src/network.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/network.c b/src/network.c
index 33fdadf..cea2a89 100644
--- a/src/network.c
+++ b/src/network.c
@@ -64,6 +64,10 @@ static void _get_network(uint64_t *results, int *sources)
     }
 }
 
+/*
+ * read from fd len chars and store them into buf
+ * make *s points to the first occurence of c into buf
+*/
 static int strchr_refill(int fd, char *buf, int len, char **s, char c)
 {
     *s = strchr(*s, c);
@@ -152,7 +156,13 @@ unsigned int init_network(char *dev, void **ptr)
             }
 
             /* compare dev name to the previously saved one */
-            if (strncmp(start_of_dev, state->devs[state->ndev - 1], s - start_of_dev) != 0) {
+            int newdev = 1;
+            for (int i = 0; i < state->ndev && newdev; i++) {
+	            if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
+	            	newdev = 0;
+	            }
+            }
+            if (newdev) {
                 if (state->ndev >= NB_MAX_DEV) {
                     fprintf(stderr, "Maximum amount of network devices exceeded (%d).\n", NB_MAX_DEV);
                     break;
-- 
GitLab


From 38fe56fc0d5de9d32dd906fc261eef2521f62d82 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 7 Mar 2023 12:56:44 +0100
Subject: [PATCH 189/229] debug help

---
 src/nvidia_gpu.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 479eecb..0be83ce 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -18,6 +18,8 @@
 
  *******************************************************/
 
+// -- test :
+// gcc -std=gnu99 -Wall -Wextra -Wpedantic -fsanitize=address -D__NVIDIA__MAIN__TEST nvidia_gpu.c -I/lib -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lnvidia-ml
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -300,6 +302,7 @@ unsigned int label_utilization_sensor(char **labels, void *data)
 
     return COUNT_UTILIZATION;
 }
+
 void clean_utilization_sensor(void *data)
 {
     free(data);
-- 
GitLab


From b6bd0080167596b8c8af6d7bd28b29fb705810f7 Mon Sep 17 00:00:00 2001
From: TwilCynder <twilcynder@gmail.com>
Date: Tue, 7 Mar 2023 17:26:01 +0100
Subject: [PATCH 190/229] small merge

---
 README.md | 12 ------------
 1 file changed, 12 deletions(-)

diff --git a/README.md b/README.md
index 95b6d7e..30b840a 100644
--- a/README.md
+++ b/README.md
@@ -22,20 +22,8 @@ OPTIONS:
 	enable overhead statistics (nanoseconds).
 
 SENSORS:
--p|--perf-list <perf_list>
-	performance counters
-	perf_list is a coma separated list of performance counters.
-	Ex: instructions,cache_misses
--l|--list
-	list the available performance counters and quit
--u|--sysload
-	system load
--d|--net-dev <net_dev>
-	network monitoring (if network_device is X, tries to detect it automatically)
 -r|--intel-rapl
 	INTEL RAPL
--c|--cpu-temp
-	processor temperature
 ```
 
 ## Installation Instructions
-- 
GitLab


From 2622d3c0087d88ec10da2fd87dae8d8fd4624578 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 08:28:36 +0100
Subject: [PATCH 191/229] fix print uint64_t format

---
 src/amd_rapl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 1e08517..253711f 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -120,7 +120,7 @@ uint64_t read_msr(int fd, uint64_t msr)
 {
     uint64_t data;
     if (pread(fd, &data, sizeof data, msr) != sizeof data) {
-        fprintf(stderr, "read_msr(%ld):", msr);
+        fprintf(stderr, "read_msr(%"PRIu64"):", msr);
         perror("pread");
         exit(127);
     }
@@ -175,7 +175,7 @@ uint64_t raw_to_joule(uint64_t raw, uint64_t unit)
 void debug_print_sensor(CpuSensor *sensor)
 {
     //CASSERT(sizeof(CpuSensor) == 56, amd_rapl_c);
-    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %ld\n",
+    printf("cpu_id : %d, package_id : %d, core_id : %d, name : %s, fd: %d,  energy_units : %d, core_energy: %"PRIu64"\n",
            sensor->cpu_id,
            sensor->package_id,
            sensor->core_id,
-- 
GitLab


From 73936d2860b2b91689380450f438b07f2123b04b Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 09:27:42 +0100
Subject: [PATCH 192/229] add msg

---
 src/nvidia_gpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index c741055..681a028 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -38,6 +38,6 @@ Optparse nvidia_gpu_opt[1] = {
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "NVIDIA GPU",
+        .usage_msg = "provides basic gpu information",
     },
 };
-- 
GitLab


From d19aa35ecc91d47c143fd503abf5ff776eceaf48 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 09:37:45 +0100
Subject: [PATCH 193/229] fix include

---
 src/amd_rapl.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 253711f..f08c5a7 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -25,6 +25,7 @@
 #include <string.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <inttypes.h>
 
 #include "info_reader.h"
 #include "util.h"
-- 
GitLab


From bfb4c16b6334e029f1871396a200615d248004b4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 10:02:36 +0100
Subject: [PATCH 194/229] add the detection of nvidia

---
 configure.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/configure.sh b/configure.sh
index 21c94ef..24a379d 100755
--- a/configure.sh
+++ b/configure.sh
@@ -115,6 +115,10 @@ detect_caps() {
 		[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
 	fi
 
+	if [ -e /usr/local/cuda/lib64 ] && [ -e /usr/local/cuda/include ]; then
+		hdr_whitelist="${hdr_whitelist}|nvidia_gpu"
+	fi
+
 	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
 	vendor_lc=$(echo "$vendor" | tr 'A-Z' 'a-z')
 	case $vendor_lc in
-- 
GitLab


From 1a5443e32e004050a96ad27dddfd0bfcef66d05e Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:11:27 +0100
Subject: [PATCH 195/229] temperature/power

---
 src/nvidia_gpu.c | 155 +++++++++++++++++++++++++++++++++++++++++------
 1 file changed, 137 insertions(+), 18 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 0be83ce..5f4a460 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -37,8 +37,10 @@ typedef enum {
     CLOCK_SENSOR       = 0,
     MEMORY_SENSOR      = 1,
     UTILIZATION_SENSOR = 2,
+    POWER_SENSOR       = 3,
+    TEMPERATURE_SENSOR = 4,
 
-    COUNT_SENSOR       = 3,
+    COUNT_SENSOR       = 5,
 } SENSOR_KIND;
 
 typedef struct Device Device;
@@ -83,6 +85,7 @@ struct NvidiaGpu {
 
 // -- Label template
 static const char *label_template = "gpu%u_%s_%s";
+static const char *short_label_template = "gpu%u_%s";
 
 // ----------------------------CLOCK_SENSOR
 
@@ -106,17 +109,17 @@ unsigned int init_clock_sensor(const Device *device, void **data)
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
     ClockData tmp = {0};
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     unsigned int clock;
 
     // -- Test all clocks
     for (unsigned int i = 0; i < NVML_CLOCK_COUNT; i++) {
-        if ((result = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
+        if ((err = nvmlDeviceGetClockInfo(nvml_device, clocks[i], &clock)) == NVML_SUCCESS) {
             snprintf(tmp.labels[tmp.count], CLOCK_LABEL_SIZE, label_template, device_idx, clock_base_name, clock_names[i]);
             tmp.clocks[tmp.count] = clocks[i];
             tmp.count += 1;
         } else {
-            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(result));
+            fprintf(stderr, "Failed to get %s clock : %s\n", clock_names[i], nvmlErrorString(err));
         }
     }
 
@@ -189,9 +192,9 @@ unsigned int init_memory_sensor(const Device *device, void **data)
     const unsigned int device_idx = device->idx;
 
     nvmlMemory_t memory;
-    nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(err));
         return 0;
     }
 
@@ -210,9 +213,9 @@ unsigned int get_memory_sensor(uint64_t *results, const Device *device, void *no
     const nvmlDevice_t nvml_device = device->device;
 
     nvmlMemory_t memory;
-    nvmlReturn_t result;
-    if ((result = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(result));
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetMemoryInfo(nvml_device, &memory)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device memory : %s\n", nvmlErrorString(err));
         exit(99);
     }
 
@@ -259,10 +262,10 @@ unsigned int init_utilization_sensor(const Device *device, void **data)
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+    if ((err = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(err));
         return 0;
     }
 
@@ -280,10 +283,10 @@ unsigned int get_utilization_sensor(uint64_t *results, const Device *device, voi
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
-    nvmlReturn_t result;
+    nvmlReturn_t err;
     nvmlUtilization_t utilization;
-    if ((result = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
-        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(result));
+    if ((err = nvmlDeviceGetUtilizationRates(nvml_device, &utilization)) != NVML_SUCCESS) {
+        fprintf(stderr, "Failed to get device utilization: %s\n", nvmlErrorString(err));
         exit(99);
     }
 
@@ -308,8 +311,122 @@ void clean_utilization_sensor(void *data)
     free(data);
 }
 
-// ----------------------------ERROR_SENSOR
-// TODO
+// ----------------------------POWER_SENSOR
+
+#define POWER_LABEL_SIZE 25
+#define COUNT_POWER 1
+
+static const char *power_base_name = "power";
+
+typedef struct {
+  char label[POWER_LABEL_SIZE];
+} PowerData;
+
+
+unsigned int init_power_sensor(const Device *device, void** data) {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
+
+    unsigned int power;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
+      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+      return 0;
+    }
+
+    PowerData *power_data = (PowerData *) calloc(1, sizeof(PowerData));
+    snprintf(power_data->label, POWER_LABEL_SIZE, short_label_template, device_idx, power_base_name);
+
+    *data = (void *) power_data;
+    return COUNT_POWER;
+}
+
+unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none) {
+    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+
+    unsigned int power;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
+      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+      exit(99);
+    }
+
+    *results = power;
+    return COUNT_POWER;
+}
+
+unsigned int label_power_sensor(char** labels, void *data) {
+    PowerData *power_data = (PowerData *) data;
+    *labels = power_data->label;
+    return COUNT_POWER;
+}
+
+void clean_power_sensor(void *data) {
+    free(data);
+}
+
+// ----------------------TEMPERATURE_SENSOR
+
+
+#define TEMPERATURE_LABEL_SIZE 35
+#define COUNT_TEMPERATURE 1
+
+static const char *temperature_base_name = "temperature";
+
+typedef struct {
+  char label[TEMPERATURE_LABEL_SIZE];
+} TemperatureData;
+
+unsigned int init_temperature_sensor(const Device *device, void** data) {
+    const nvmlDevice_t nvml_device = device->device;
+    const unsigned int device_idx = device->idx;
+
+    unsigned int temperature;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetTemperature(nvml_device, NVML_TEMPERATURE_GPU, &temperature)) != NVML_SUCCESS) {
+        printf("Failed to get the device temperature: %s\n", nvmlErrorString(err));
+        return 0;
+    }
+
+    TemperatureData *temperature_data = (TemperatureData *) calloc(1, sizeof(TemperatureData));
+    snprintf(temperature_data->label, TEMPERATURE_LABEL_SIZE, short_label_template, device_idx, temperature_base_name);
+
+    *data = (void *) temperature_data;
+    return COUNT_TEMPERATURE;
+}
+
+unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none) {
+    UNUSED(none);
+    const nvmlDevice_t nvml_device = device->device;
+
+    unsigned int temperature;
+    nvmlReturn_t err;
+    if ((err = nvmlDeviceGetTemperature(nvml_device, NVML_TEMPERATURE_GPU, &temperature)) != NVML_SUCCESS) {
+        printf("Failed to get the device temperature: %s\n", nvmlErrorString(err));
+        exit(99);
+    }
+
+    *results = temperature;
+    return COUNT_TEMPERATURE;
+}
+
+unsigned int label_temperature_sensor(char** labels, void *data) {
+    TemperatureData *temperature_data = (TemperatureData *) data;
+    *labels = temperature_data->label;
+    return COUNT_TEMPERATURE;
+}
+
+void clean_temperature_sensor(void *data) {
+    free(data);
+}
+// // Get the temperature
+// result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temperature);
+// if (NVML_SUCCESS != result) {
+//   printf("Failed to get temperature for device %d: %s\n", i, nvmlErrorString(result));
+//   continue;
+// }
+// printf("\t - temperature: %u\n", temperature);
 
 // ----------------------------------------
 
@@ -319,6 +436,8 @@ static const ISensor avaible_sensors[COUNT_SENSOR] = {
     {.init = init_clock_sensor, .get = get_clock_sensor, .label = label_clock_sensor, .clean = clean_clock_sensor},
     {.init = init_memory_sensor, .get = get_memory_sensor, .label = label_memory_sensor, .clean = clean_memory_sensor},
     {.init = init_utilization_sensor, .get = get_utilization_sensor, .label = label_utilization_sensor, .clean = clean_utilization_sensor},
+    {.init = init_power_sensor, .get = get_power_sensor, .label = label_power_sensor, .clean = clean_power_sensor},
+    {.init = init_temperature_sensor, .get = get_temperature_sensor, .label = label_temperature_sensor, .clean = clean_temperature_sensor},
 };
 
 // ------------------------DEVICE_FUNCTIONS
-- 
GitLab


From 73e90167bb968cee8a90b903c829fed3da0bf812 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:11:56 +0100
Subject: [PATCH 196/229] doc nvidia

---
 doc/nvidia-gpu.md | 58 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 58 insertions(+)
 create mode 100644 doc/nvidia-gpu.md

diff --git a/doc/nvidia-gpu.md b/doc/nvidia-gpu.md
new file mode 100644
index 0000000..8c54afd
--- /dev/null
+++ b/doc/nvidia-gpu.md
@@ -0,0 +1,58 @@
+# Nvidia Gpu
+
+The `nvidia-gpu` sensor provides basic information about the gpu. Depending on
+the driver version it is possible that not all sensors are supported, so an
+error message will be written to `stderr` but the execution will continue.
+
+For more information you can consult the [nvidia nvml api](https://docs.nvidia.com/deploy/index.html).
+
+## [Clock](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g805c0647be9996589fc5e3f6ff680c64)
+
+All speeds are in Mhz.
+
+|Output  |Description                    |
+|--------|-------------------------------|
+|graphics|Graphics clock                 |
+|sm      |Streaming Multiprocessor clock |
+|memory  |Memory clock                   |
+|video   |Video encoder/decoder clock    |
+
+## [Memory](https://docs.nvidia.com/deploy/nvml-api/structnvmlMemory__t.html#structnvmlMemory__t)
+
+All values are in bytes.
+
+|Output  |Description                          |
+|--------|-------------------------------------|
+|free    |Unallocated device memory            |
+|used    |Sum of Reserved and Allocated memory |
+|total   |Total physical device memory         |
+
+
+## [Utilization](https://docs.nvidia.com/deploy/nvml-api/structnvmlUtilization__t.html#structnvmlUtilization__t)
+
+Utilization information for a device. Each sample period may be between 1
+second and 1/6 second, depending on the product being queried.
+
+All values are a percent of time over the past sample period.
+
+|Output  |Description          |
+|--------|---------------------|
+|gpu     | Usage of the GPU    |
+|memory  | Usage of the Memory |
+
+## [Power](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceQueries.html#group__nvmlDeviceQueries_1g7ef7dff0ff14238d08a19ad7fb23fc87)
+
+Retrieves power usage for this GPU in milliwatts and its associated circuitry (e.g. memory)
+
+|Output  |Description              |
+|--------|-------------------------|
+|power   | Power consumption in mW |
+
+## [Temperature](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g2650b526841fa38b8f293c2d509a1de0)
+
+Temperature of the GPU.
+
+|Output      |Description                 |
+|------------|----------------------------|
+|temperature | Temperature of the GPU die |
+
-- 
GitLab


From 7a99793661194c32f5b366aca7f9e2289dc7dde7 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 13:18:49 +0100
Subject: [PATCH 197/229] fix line

---
 doc/nvidia-gpu.md | 1 -
 1 file changed, 1 deletion(-)

diff --git a/doc/nvidia-gpu.md b/doc/nvidia-gpu.md
index 8c54afd..5a5cebc 100644
--- a/doc/nvidia-gpu.md
+++ b/doc/nvidia-gpu.md
@@ -49,7 +49,6 @@ Retrieves power usage for this GPU in milliwatts and its associated circuitry (e
 |power   | Power consumption in mW |
 
 ## [Temperature](https://docs.nvidia.com/deploy/nvml-api/group__nvmlDeviceEnumvs.html#group__nvmlDeviceEnumvs_1g2650b526841fa38b8f293c2d509a1de0)
-
 Temperature of the GPU.
 
 |Output      |Description                 |
-- 
GitLab


From 8e1a6b567cd3270e38f74a8290112b71da6c9feb Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 14:08:11 +0100
Subject: [PATCH 198/229] fix name

---
 doc/{nvidia-gpu.md => nvidia_gpu.md} | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
 rename doc/{nvidia-gpu.md => nvidia_gpu.md} (97%)

diff --git a/doc/nvidia-gpu.md b/doc/nvidia_gpu.md
similarity index 97%
rename from doc/nvidia-gpu.md
rename to doc/nvidia_gpu.md
index 5a5cebc..15cc8aa 100644
--- a/doc/nvidia-gpu.md
+++ b/doc/nvidia_gpu.md
@@ -1,6 +1,6 @@
 # Nvidia Gpu
 
-The `nvidia-gpu` sensor provides basic information about the gpu. Depending on
+The `nvidia_gpu` sensor provides basic information about the gpu. Depending on
 the driver version it is possible that not all sensors are supported, so an
 error message will be written to `stderr` but the execution will continue.
 
-- 
GitLab


From 22721bfe5886ec3159ca34091e593a172511ce05 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 13 Mar 2023 14:09:41 +0100
Subject: [PATCH 199/229] format

---
 src/nvidia_gpu.c | 36 ++++++++++++++++++++++--------------
 1 file changed, 22 insertions(+), 14 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 5f4a460..17d77f5 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -319,19 +319,20 @@ void clean_utilization_sensor(void *data)
 static const char *power_base_name = "power";
 
 typedef struct {
-  char label[POWER_LABEL_SIZE];
+    char label[POWER_LABEL_SIZE];
 } PowerData;
 
 
-unsigned int init_power_sensor(const Device *device, void** data) {
+unsigned int init_power_sensor(const Device *device, void **data)
+{
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
     unsigned int power;
     nvmlReturn_t err;
     if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
-      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
-      return 0;
+        printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+        return 0;
     }
 
     PowerData *power_data = (PowerData *) calloc(1, sizeof(PowerData));
@@ -341,28 +342,31 @@ unsigned int init_power_sensor(const Device *device, void** data) {
     return COUNT_POWER;
 }
 
-unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none) {
+unsigned int get_power_sensor(uint64_t *results, const Device *device, void *none)
+{
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
     unsigned int power;
     nvmlReturn_t err;
     if ((err = nvmlDeviceGetPowerUsage(nvml_device, &power)) != NVML_SUCCESS) {
-      printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
-      exit(99);
+        printf("Failed to get the device power consumption: %s\n", nvmlErrorString(err));
+        exit(99);
     }
 
     *results = power;
     return COUNT_POWER;
 }
 
-unsigned int label_power_sensor(char** labels, void *data) {
+unsigned int label_power_sensor(char **labels, void *data)
+{
     PowerData *power_data = (PowerData *) data;
     *labels = power_data->label;
     return COUNT_POWER;
 }
 
-void clean_power_sensor(void *data) {
+void clean_power_sensor(void *data)
+{
     free(data);
 }
 
@@ -375,10 +379,11 @@ void clean_power_sensor(void *data) {
 static const char *temperature_base_name = "temperature";
 
 typedef struct {
-  char label[TEMPERATURE_LABEL_SIZE];
+    char label[TEMPERATURE_LABEL_SIZE];
 } TemperatureData;
 
-unsigned int init_temperature_sensor(const Device *device, void** data) {
+unsigned int init_temperature_sensor(const Device *device, void **data)
+{
     const nvmlDevice_t nvml_device = device->device;
     const unsigned int device_idx = device->idx;
 
@@ -396,7 +401,8 @@ unsigned int init_temperature_sensor(const Device *device, void** data) {
     return COUNT_TEMPERATURE;
 }
 
-unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none) {
+unsigned int get_temperature_sensor(uint64_t *results, const Device *device, void *none)
+{
     UNUSED(none);
     const nvmlDevice_t nvml_device = device->device;
 
@@ -411,13 +417,15 @@ unsigned int get_temperature_sensor(uint64_t *results, const Device *device, voi
     return COUNT_TEMPERATURE;
 }
 
-unsigned int label_temperature_sensor(char** labels, void *data) {
+unsigned int label_temperature_sensor(char **labels, void *data)
+{
     TemperatureData *temperature_data = (TemperatureData *) data;
     *labels = temperature_data->label;
     return COUNT_TEMPERATURE;
 }
 
-void clean_temperature_sensor(void *data) {
+void clean_temperature_sensor(void *data)
+{
     free(data);
 }
 // // Get the temperature
-- 
GitLab


From 6ac893561fca6e5b433a3b9ab779a61c11b13744 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Mar 2023 14:17:48 +0100
Subject: [PATCH 200/229] add doc to "network" sensor explaining #interfaces
 hard-limit in use

---
 doc/network.md | 8 ++++++++
 1 file changed, 8 insertions(+)
 create mode 100644 doc/network.md

diff --git a/doc/network.md b/doc/network.md
new file mode 100644
index 0000000..b5d1e68
--- /dev/null
+++ b/doc/network.md
@@ -0,0 +1,8 @@
+This sensor can autodetect interfaces in use by giving the special
+interface name "X".  But the total number of interfaces it can autodetect
+is currently under a hard-limit.  This hard-limit can be changed by
+modifying this line in `src/network.c`:
+
+```c
+#define NB_MAX_DEV 8
+```
-- 
GitLab


From 1e6746bee0c8e7f867c778f50369e3a17d3f5ddb Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 13 Mar 2023 15:36:34 +0100
Subject: [PATCH 201/229] configure.sh: avoid cd(1) and ls(1) in ls_sensors()

---
 configure.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/configure.sh b/configure.sh
index 747a078..203fd04 100755
--- a/configure.sh
+++ b/configure.sh
@@ -43,16 +43,16 @@ usage() {
 }
 
 ls_sensors() {
-	try cd src
+	[ -d src ] || die 'fatal: the "src" directory does not exit.'
 
 	[ -z "$hdr_whitelist" ] && hdr_whitelist='.*'
 	dprint hdr_blacklist >&2
 	dprint hdr_whitelist >&2
 
-	ls -1 *.h |
-		grep -xEv "($hdr_blacklist)\.h" |
-		grep -xE  "($hdr_whitelist)\.h" |
-		sed 's/\.h$//'
+	try find src -type f -name '*.h' |
+		sed 's,src/\(.*\)\.h,\1,' |
+		grep -xEv "($hdr_blacklist)" |
+		grep -xE  "($hdr_whitelist)"
 }
 
 # gen_sensors_h(sensor, nb_sensors)
-- 
GitLab


From 856c5a6e577428882179c3dceba4aeaf1bb7192d Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 08:56:20 +0100
Subject: [PATCH 202/229] auto config nvidia

---
 configure.sh | 79 +++++++++++++++++++++++++++++-----------------------
 makefile     |  6 ++--
 2 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/configure.sh b/configure.sh
index 24a379d..207cf07 100755
--- a/configure.sh
+++ b/configure.sh
@@ -4,12 +4,15 @@
 # Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
 try() { "$@" || die "cannot $*"; }
-die() { yell "$*"; exit 111; }
+die() {
+	yell "$*"
+	exit 111
+}
 yell() { echo "$0: $*" >&2; }
 echo() { printf '%s\n' "$*"; }
 isnum() {
 	case "${1#[+-]}" in
-	*[!0-9]*|'') return 1 ;;
+	*[!0-9]* | '') return 1 ;;
 	*) return 0 ;;
 	esac
 }
@@ -51,7 +54,7 @@ ls_sensors() {
 
 	ls -1 *.h |
 		grep -xEv "($hdr_blacklist)\.h" |
-		grep -xE  "($hdr_whitelist)\.h" |
+		grep -xE "($hdr_whitelist)\.h" |
 		sed 's/\.h$//'
 }
 
@@ -86,10 +89,10 @@ gen_sensors_h() {
 	printf '    int opt_idx = offset;\n'
 	for sensor in $sensors; do
 		cat <<-!
-		    for (int i = 0; i < ${sensor}.nb_opt; i++) {
-		        opts[opt_idx++] = ${sensor}_opt[i];
-		    }
-		    sensors[(*nb_defined)++] = ${sensor};
+			    for (int i = 0; i < ${sensor}.nb_opt; i++) {
+			        opts[opt_idx++] = ${sensor}_opt[i];
+			    }
+			    sensors[(*nb_defined)++] = ${sensor};
 		!
 	done
 	printf '    assert((offset + *nb_defined) <= len);\n'
@@ -117,6 +120,8 @@ detect_caps() {
 
 	if [ -e /usr/local/cuda/lib64 ] && [ -e /usr/local/cuda/include ]; then
 		hdr_whitelist="${hdr_whitelist}|nvidia_gpu"
+		NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml"
+		NVML_IFLAGS="-I/usr/local/cuda/include"
 	fi
 
 	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
@@ -140,7 +145,7 @@ detect_caps() {
 }
 
 case $1 in
---all|-a)
+--all | -a)
 	all=1
 	;;
 esac
@@ -148,30 +153,33 @@ esac
 [ "$all" ] || detect_caps
 
 [ "$all" ] ||
-while [ "$1" ]; do
-	case $1 in
-	--include|-i)
-		shift; [ "$1" ] || usage
-		hdr_whitelist="${hdr_whitelist}|${1}"
-		;;
-	--exclude|-e)
-		shift; [ "$1" ] || usage
-		hdr_blacklist="${hdr_blacklist}|${1}"
-		;;
-	--list-sensors|-l)
-		ls_sensors
-		exit 0
-		;;
-	--unique|-u)
-		shift; [ "$1" ] || usage
-		hdr_whitelist=$1
-		;;
-	--help|-h)
-		usage
-		;;
-	esac
-	shift
-done
+	while [ "$1" ]; do
+		case $1 in
+		--include | -i)
+			shift
+			[ "$1" ] || usage
+			hdr_whitelist="${hdr_whitelist}|${1}"
+			;;
+		--exclude | -e)
+			shift
+			[ "$1" ] || usage
+			hdr_blacklist="${hdr_blacklist}|${1}"
+			;;
+		--list-sensors | -l)
+			ls_sensors
+			exit 0
+			;;
+		--unique | -u)
+			shift
+			[ "$1" ] || usage
+			hdr_whitelist=$1
+			;;
+		--help | -h)
+			usage
+			;;
+		esac
+		shift
+	done
 
 sensors=$(ls_sensors)
 nb_sensors=$(echo "$sensors" | sed '/^$/d' | wc -l)
@@ -181,12 +189,13 @@ if [ "$nb_sensors" -eq 0 ]; then
 	exit 1
 fi
 
-try gen_sensors_h "$sensors" "$nb_sensors" > "$target_hdr"
-try gen_sensors_mk "$sensors" > "$target_mk"
+try gen_sensors_h "$sensors" "$nb_sensors" >"$target_hdr"
+try gen_sensors_mk "$sensors" >"$target_mk"
+try printf "LDFLAGS += %s\n" "$NVML_LDFLAGS" >>"$target_mk"
+try printf "IFLAGS += %s\n" "$NVML_IFLAGS" >>"$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
 printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
 echo "$sensors" >&2
 
 make clean >/dev/null
-
diff --git a/makefile b/makefile
index 81a4e41..1b636c4 100644
--- a/makefile
+++ b/makefile
@@ -9,6 +9,8 @@ TESTS_DIR = tests
 BIN = mojitos
 
 CAPTOR_OBJ =
+IFLAGS =
+LDFLAGS =
 
 include ./sensors.mk
 
@@ -17,9 +19,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib -I/usr/local/cuda/include
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(IFLAGS)
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS = -L/usr/local/cuda/lib64 -lnvidia-ml
+LDFLAGS +=
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-- 
GitLab


From ddbe21e68e58bc5923b17d59d64d08ae9fc45cee Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 09:19:06 +0100
Subject: [PATCH 203/229] fix: Readme

---
 README.md | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 8c6d591..9fee622 100644
--- a/README.md
+++ b/README.md
@@ -59,11 +59,15 @@ make
 ```
 You may want to run `./configure.sh --help` to see configuration options.
 
+To use `amd_rapl` you have to load the module `msr`
+```bash
+sudo modprobe msr
+```
 To execute mojitos without being root to monitor performance counters
 ```bash
 sudo sh -c 'echo 0 >/proc/sys/kernel/perf_event_paranoid'
 ```
-To execute mohitos without being root for accessing RAPL
+To execute mojitos without being root for accessing RAPL
 ```bash
 sudo chmod a+w /sys/class/powercap/intel-rapl/*/*
 sudo chmod a+w /sys/class/powercap/intel-rapl/*/*/*
-- 
GitLab


From bd68a69a55783fe7985910fe0e3e359de7102e3c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 11:36:10 +0100
Subject: [PATCH 204/229] auto configure nvml

---
 configure.sh | 5 +++--
 makefile     | 8 ++++----
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/configure.sh b/configure.sh
index 207cf07..ebf6881 100755
--- a/configure.sh
+++ b/configure.sh
@@ -191,8 +191,9 @@ fi
 
 try gen_sensors_h "$sensors" "$nb_sensors" >"$target_hdr"
 try gen_sensors_mk "$sensors" >"$target_mk"
-try printf "LDFLAGS += %s\n" "$NVML_LDFLAGS" >>"$target_mk"
-try printf "IFLAGS += %s\n" "$NVML_IFLAGS" >>"$target_mk"
+
+try printf "NVML_LDFLAGS = %s\n" "$NVML_LDFLAGS" >>"$target_mk"
+try printf "NVML_IFLAGS = %s\n" "$NVML_IFLAGS" >>"$target_mk"
 
 printf -- 'Run `make` to build `bin/mojitos`.\n' >&2
 printf -- 'The resulting binary will have the %d following sensors:\n' "$nb_sensors" >&2
diff --git a/makefile b/makefile
index 1b636c4..8a3c129 100644
--- a/makefile
+++ b/makefile
@@ -9,8 +9,8 @@ TESTS_DIR = tests
 BIN = mojitos
 
 CAPTOR_OBJ =
-IFLAGS =
-LDFLAGS =
+NVML_LDFLAGS =
+NVML_IFLAGS =
 
 include ./sensors.mk
 
@@ -19,9 +19,9 @@ OBJ =  \
 	$(OBJ_DIR)/util.o
 
 CC = gcc
-CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(IFLAGS)
+CPPFLAGS = -std=gnu99 -Wall -Wextra -Wpedantic -Wno-unused-function -I./lib $(NVML_IFLAGS)
 CFLAGS = $(CPPFLAGS) -O3 -Werror
-LDFLAGS +=
+LDFLAGS = $(NVML_LDFLAGS)
 
 ASTYLE = astyle --style=kr -xf -s4 -k3 -n -Z -Q
 
-- 
GitLab


From a7ae9dc8fc367af447a1a76c1ba72630e893e2b4 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 12:00:11 +0100
Subject: [PATCH 205/229] clean up

---
 src/nvidia_gpu.c | 55 +-----------------------------------------------
 1 file changed, 1 insertion(+), 54 deletions(-)

diff --git a/src/nvidia_gpu.c b/src/nvidia_gpu.c
index 17d77f5..4078002 100644
--- a/src/nvidia_gpu.c
+++ b/src/nvidia_gpu.c
@@ -18,13 +18,12 @@
 
  *******************************************************/
 
-// -- test :
-// gcc -std=gnu99 -Wall -Wextra -Wpedantic -fsanitize=address -D__NVIDIA__MAIN__TEST nvidia_gpu.c -I/lib -I/usr/local/cuda/include -L/usr/local/cuda/lib64 -lnvidia-ml
 #include <stdio.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
 
+// Pedantic throws a warning in the nvml library
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Wpedantic"
 #include <nvml.h>
@@ -428,16 +427,6 @@ void clean_temperature_sensor(void *data)
 {
     free(data);
 }
-// // Get the temperature
-// result = nvmlDeviceGetTemperature(device, NVML_TEMPERATURE_GPU, &temperature);
-// if (NVML_SUCCESS != result) {
-//   printf("Failed to get temperature for device %d: %s\n", i, nvmlErrorString(result));
-//   continue;
-// }
-// printf("\t - temperature: %u\n", temperature);
-
-// ----------------------------------------
-
 
 // -------------------------AVAIBLE_SENSORS
 static const ISensor avaible_sensors[COUNT_SENSOR] = {
@@ -602,45 +591,3 @@ void clean_nvidia_gpu(void *ptr)
     nvmlShutdown();
 }
 
-// -------------------------------TEST_MAIN
-
-#ifdef __NVIDIA__MAIN__TEST
-int main()
-{
-    void *ptr = NULL;
-    char *none = NULL;
-
-    unsigned int sensor_count = init_nvidia_gpu(none, &ptr);
-
-    NvidiaGpu *nvidia = (NvidiaGpu *) ptr;
-    printf("%d\n", nvidia->count);
-    printf("%u\n", sensor_count);
-
-
-
-    uint64_t results[sensor_count];
-    char *labels[sensor_count];
-
-    memset(results, 0, sensor_count * sizeof(uint64_t));
-    memset(labels, 0, sensor_count * sizeof(char **));
-
-
-    unsigned count_label = label_nvidia_gpu(labels, ptr);
-    unsigned count_get = get_nvidia_gpu(results, ptr);
-    printf("total : %u, get : %u, label : %u\n", sensor_count, count_get, count_label);
-
-
-    for (unsigned int i = 0; i < sensor_count; i++) {
-        printf("%s ", labels[i]);
-    }
-    printf("\n");
-    for (unsigned int i = 0; i < sensor_count; i++) {
-        printf("%lu ", results[i]);
-    }
-    printf("\n");
-    printf("sensor_count: %d\n", sensor_count);
-
-    clean_nvidia_gpu(ptr);
-}
-#endif
-
-- 
GitLab


From 82224cf547220db437b09b720285141c575c2982 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 20 Mar 2023 12:08:10 +0100
Subject: [PATCH 206/229] fix: usage msg

---
 src/nvidia_gpu.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/nvidia_gpu.h b/src/nvidia_gpu.h
index 681a028..1f3d053 100644
--- a/src/nvidia_gpu.h
+++ b/src/nvidia_gpu.h
@@ -38,6 +38,6 @@ Optparse nvidia_gpu_opt[1] = {
         .shortname = 'n',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "provides basic gpu information",
+        .usage_msg = "provides basic gpu information [clocks, memory, utilization, power, temperature].",
     },
 };
-- 
GitLab


From 80686673103879c1eb6b197c45493b521c7702a9 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 10:41:57 +0100
Subject: [PATCH 207/229] add memory sensor

---
 configure.sh |  6 +++-
 src/memory.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/memory.h | 43 +++++++++++++++++++++++
 3 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 src/memory.c
 create mode 100644 src/memory.h

diff --git a/configure.sh b/configure.sh
index 740e87a..7e10ec3 100755
--- a/configure.sh
+++ b/configure.sh
@@ -55,7 +55,7 @@ ls_sensors() {
 	try find src -type f -name '*.h' |
 		sed 's,src/\(.*\)\.h,\1,' |
 		grep -xEv "($hdr_blacklist)" |
-		grep -xE  "($hdr_whitelist)"
+		grep -xE "($hdr_whitelist)"
 }
 
 # gen_sensors_h(sensor, nb_sensors)
@@ -118,6 +118,10 @@ detect_caps() {
 	[ -d /sys/class/infiniband ] && hdr_whitelist="${hdr_whitelist}|infiniband"
 	[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
 
+	if [ "$(uname -r | cut -d "." -f 1)" -gt "2" ]; then
+		hdr_whitelist="${hdr_whitelist}|memory"
+	fi
+
 	if [ -r /proc/net/route ]; then
 		dev=$(awk 'NR == 2 { print $1 }' /proc/net/route)
 		[ -e "/sys/class/net/$dev" ] && hdr_whitelist="${hdr_whitelist}|network"
diff --git a/src/memory.c b/src/memory.c
new file mode 100644
index 0000000..3356a82
--- /dev/null
+++ b/src/memory.c
@@ -0,0 +1,97 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/sysinfo.h>
+#include <string.h>
+
+#include "util.h"
+
+typedef enum {
+    TOTALRAM = 0,
+    FREERAM,
+    SHAREDRAM,
+    BUFFERRAM,
+    TOTALSWAP,
+    FREESWAP,
+    PROCS,
+    TOTALHIGH,
+    FREEHIGH,
+    MEM_UNIT,
+
+    MEMORY_COUNT,
+} MemoryKind;
+
+static const char *memory_labels[MEMORY_COUNT] = {
+    "totalram", "freeram", "sharedram", "bufferram",
+    "totalswap", "freeswap",
+    "procs",
+    "totalhigh", "freehigh", "mem_unit",
+};
+
+unsigned int init_memory(char *none1, void **none2)
+{
+    UNUSED(none1);
+    UNUSED(none2);
+    struct sysinfo info;
+    if (sysinfo(&info) < 0) {
+        fprintf(stderr, "Failed to get the memory information");
+        return 0;
+    }
+    return MEMORY_COUNT;
+}
+
+unsigned int get_memory(uint64_t *results, void *none)
+{
+    UNUSED(none);
+    struct sysinfo info;
+    if (sysinfo(&info) < 0) {
+        fprintf(stderr, "Failed to get the memory information");
+        exit(99);
+    }
+
+    // Can't use memcpy, the size isn't always the same
+    results[TOTALRAM]  = info.totalram;
+    results[FREERAM]   = info.freeram;
+    results[SHAREDRAM] = info.sharedram;
+    results[BUFFERRAM] = info.bufferram;
+    results[TOTALSWAP] = info.totalswap;
+    results[FREESWAP]  = info.freeswap;
+    results[PROCS]     = info.procs;
+    results[TOTALHIGH] = info.totalhigh;
+    results[FREEHIGH]  = info.freehigh;
+    results[MEM_UNIT]  = info.mem_unit;
+
+    return MEMORY_COUNT;
+}
+
+void label_memory(char **labels, void *none)
+{
+    UNUSED(none);
+    memcpy(labels, memory_labels, sizeof(char *) * MEMORY_COUNT);
+}
+
+void clean_memory(void *none)
+{
+    UNUSED(none);
+    return;
+}
+
diff --git a/src/memory.h b/src/memory.h
new file mode 100644
index 0000000..6e275c6
--- /dev/null
+++ b/src/memory.h
@@ -0,0 +1,43 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_memory(char *, void **);
+unsigned int get_memory(uint64_t *results, void *);
+void clean_memory(void *);
+void label_memory(char **labels, void *);
+
+
+Sensor memory = {
+    .init = init_memory,
+    .get = get_memory,
+    .clean = clean_memory,
+    .label = label_memory,
+    .nb_opt = 1,
+};
+
+Optparse memory_opt[1] = {
+    {
+        .longname = "memory",
+        .shortname = 'm',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "Retrieves information about the memory via the syscall 'sysinfo(2)'.",
+    },
+};
-- 
GitLab


From 482202be2c2811baf0f5f4fff1c5056f9b2b3e04 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 11:21:58 +0100
Subject: [PATCH 208/229] non breaking change, ptr -> const ptr

---
 tests/small_test.h | 26 +++++++++++++-------------
 1 file changed, 13 insertions(+), 13 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 66c4de9..8301ae7 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -253,8 +253,8 @@
 #define DEFERRED_ERROR(nb_error) \
     INDENTED_PRINT("|_Deferred Error : %d\n",nb_error);
 
-typedef int (Comparator) (void *, void *);
-typedef char *(Formatter) (char[FMT_BUFFER_SIZE], void *);
+typedef int (Comparator) (const void *, const void *);
+typedef char *(Formatter) (char[FMT_BUFFER_SIZE], const void *);
 
 typedef struct {
     Comparator *compare;
@@ -263,7 +263,7 @@ typedef struct {
 
 // ---------------------------TEST FUNCTION
 
-int test(char *file, int line, unsigned int __indentation_level, void *result, void *expected, const TestInterface *interface)
+int test(char *file, int line, unsigned int __indentation_level, const void *result, const void *expected, const TestInterface *interface)
 {
     __indentation_level += 1;
     static char buffer_result[FMT_BUFFER_SIZE];
@@ -281,7 +281,7 @@ int test(char *file, int line, unsigned int __indentation_level, void *result, v
 // ------------------------------INTERFACES
 
 // -- str_interface
-int str_compare(void *ptr1, void *ptr2)
+int str_compare(const void *ptr1, const void *ptr2)
 {
     char *str1 = (char *) ptr1;
     char *str2 = (char *) ptr2;
@@ -295,7 +295,7 @@ int str_compare(void *ptr1, void *ptr2)
     }
 }
 
-char *str_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
+char *str_format(char buffer[FMT_BUFFER_SIZE], const void *ptr)
 {
     UNUSED(buffer);
     static char *str_null = "NULL";
@@ -310,14 +310,14 @@ static const TestInterface str_interface = {
 
 // -- bool_interface
 
-int bool_compare(void *ptr1, void *ptr2)
+int bool_compare(const void *ptr1, const void *ptr2)
 {
     bool *bool1 = (bool *) ptr1;
     bool *bool2 = (bool *) ptr2;
     return *bool1 == *bool2;
 }
 
-char *bool_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
+char *bool_format(char buffer[FMT_BUFFER_SIZE], const void *ptr)
 {
     UNUSED(buffer);
     bool *_bool = (bool *) ptr;
@@ -331,14 +331,14 @@ static const TestInterface bool_interface = {
 
 // -- int_interface
 
-int int_compare(void *ptr1, void *ptr2)
+int int_compare(const void *ptr1, const void *ptr2)
 {
     int *int1 = (int *) ptr1;
     int *int2 = (int *) ptr2;
     return *int1 == *int2;
 }
 
-char *int_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
+char *int_format(char buffer[FMT_BUFFER_SIZE], const void *ptr)
 {
     int *_int = (int *) ptr;
     snprintf(buffer, FMT_BUFFER_SIZE, "%d", *_int);
@@ -352,12 +352,12 @@ static const TestInterface int_interface = {
 
 // -- ptr_interface
 
-int ptr_compare(void *ptr1, void *ptr2)
+int ptr_compare(const void *ptr1, const void *ptr2)
 {
     return ptr1 == ptr2;
 }
 
-char *ptr_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
+char *ptr_format(char buffer[FMT_BUFFER_SIZE], const void *ptr)
 {
     snprintf(buffer, FMT_BUFFER_SIZE, "%p", ptr);
     return buffer;
@@ -370,14 +370,14 @@ static const TestInterface ptr_interface = {
 
 // -- u64_interface
 
-int u64_compare(void *ptr1, void *ptr2)
+int u64_compare(const void *ptr1, const void *ptr2)
 {
     uint64_t *v1 = (uint64_t *) ptr1;
     uint64_t *v2 = (uint64_t *) ptr2;
     return *v1 == *v2;
 }
 
-char *u64_format(char buffer[FMT_BUFFER_SIZE], void *ptr)
+char *u64_format(char buffer[FMT_BUFFER_SIZE], const void *ptr)
 {
     uint64_t *v = (uint64_t *) ptr;
     snprintf(buffer, FMT_BUFFER_SIZE, "%"PRIu64"", *v);
-- 
GitLab


From 32ff911bf1e940750eadf0e5080f374aa45921ef Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 11:23:21 +0100
Subject: [PATCH 209/229] add tests

---
 tests/main.c   |  2 ++
 tests/memory.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 80 insertions(+)
 create mode 100644 tests/memory.c

diff --git a/tests/main.c b/tests/main.c
index 3246f04..e90e8dd 100644
--- a/tests/main.c
+++ b/tests/main.c
@@ -21,9 +21,11 @@
 #include "util.c"
 #include "amd_rapl.c"
 #include "info_reader.c"
+#include "memory.c"
 
 TMAIN({
     CALL_TFUNCTION(test_util);
     CALL_TFUNCTION(test_amd_rapl);
     CALL_TFUNCTION(test_info_reader);
+    CALL_TFUNCTION(test_memory);
 })
diff --git a/tests/memory.c b/tests/memory.c
new file mode 100644
index 0000000..78efd28
--- /dev/null
+++ b/tests/memory.c
@@ -0,0 +1,78 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+*******************************************************/
+
+#include "small_test.h"
+#include "../src/memory.c"
+
+// In order to verify the integrity.
+TFUNCTION(test_labels, {
+    // If it fails update the tests
+    int tested_count = 10;
+    int expected_count = MEMORY_COUNT;
+    TEST_INT(&tested_count, &expected_count);
+
+    const char *result = NULL;
+    char *expected = NULL;
+
+    expected = "totalram";
+    result =  memory_labels[TOTALRAM];
+    TEST_STR(result, expected);
+
+    expected = "freeram";
+    result = memory_labels[FREERAM];
+    TEST_STR(result, expected);
+
+    expected = "sharedram";
+    result = memory_labels[SHAREDRAM];
+    TEST_STR(result, expected);
+
+    expected = "bufferram";
+    result = memory_labels[BUFFERRAM];
+    TEST_STR(result, expected);
+
+    expected = "totalswap";
+    result = memory_labels[TOTALSWAP];
+    TEST_STR(result, expected);
+
+    expected = "freeswap";
+    result = memory_labels[FREESWAP];
+    TEST_STR(result, expected);
+
+    expected = "procs";
+    result = memory_labels[PROCS];
+    TEST_STR(result, expected);
+
+    expected = "totalhigh";
+    result = memory_labels[TOTALHIGH];
+    TEST_STR(result, expected);
+
+    expected = "freehigh";
+    result = memory_labels[FREEHIGH];
+    TEST_STR(result, expected);
+
+    expected = "mem_unit";
+    result = memory_labels[MEM_UNIT];
+    TEST_STR(result, expected);
+})
+
+TFILE_ENTRY_POINT(test_memory, {
+    CALL_TFUNCTION(test_labels);
+})
+
-- 
GitLab


From 4ffdcfaf2192b0929cd7d0902bcb5a2cc34510fe Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 11:39:45 +0100
Subject: [PATCH 210/229] add tests

---
 tests/util.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 44 insertions(+)

diff --git a/tests/util.c b/tests/util.c
index 69941bf..231ab47 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -77,6 +77,50 @@ TFUNCTION(test_modulo_substraction, {
     TEST_UINT64_T(&result, &expected);
 })
 
+TFUNCTION(test_max, {
+  int expected = 0;
+  int result = 0;
+
+  expected = 10;
+  result = MAX(expected, 9);
+  TEST_INT(&result, &expected);
+
+  expected = -15;
+  result = MAX(expected, -16);
+  TEST_INT(&result, &expected);
+
+  expected = 0;
+  result = MAX(expected, -1);
+  TEST_INT(&result, &expected);
+
+  expected = 1;
+  result = MAX(expected, 0);
+  TEST_INT(&result, &expected);
+})
+
+TFUNCTION(test_min, {
+  int expected = 0;
+  int result = 0;
+
+  expected = 9;
+  result = MIN(expected, 10);
+  TEST_INT(&result, &expected);
+
+  expected = -16;
+  result = MIN(expected, -15);
+  TEST_INT(&result, &expected);
+
+  expected = -1;
+  result = MIN(expected, 0);
+  TEST_INT(&result, &expected);
+
+  expected = 0;
+  result = MIN(expected, 1);
+  TEST_INT(&result, &expected);
+})
+
 TFILE_ENTRY_POINT(test_util, {
     CALL_TFUNCTION(test_modulo_substraction);
+    CALL_TFUNCTION(test_max);
+    CALL_TFUNCTION(test_min);
 })
-- 
GitLab


From bdb2908f2cecc768711d92eede0d41e5d856c404 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 12:46:42 +0100
Subject: [PATCH 211/229] add: exit information

---
 src/amd_rapl.c | 24 +++++++++++++++++++-----
 1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index f08c5a7..adc4461 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -201,17 +201,36 @@ void debug_print_amd_rapl(AmdRapl *rapl)
 unsigned int get_nb_cpu()
 {
     char filename[BUFFER_SIZE];
+	int	cpy_errno;
 
     unsigned int n_cpu = 0;
     for (;; n_cpu++) {
         snprintf(filename, BUFFER_SIZE, base_str, n_cpu);
 
         int fd = open(filename, O_RDONLY);
+        cpy_errno = errno;
         if (fd < 0) {
             break;
         }
         close(fd);
     }
+
+	if (n_cpu == 0) {
+		perror("open()");
+		fprintf(stderr, "on %s\n", filename);
+		switch (cpy_errno) {
+			case ENOENT:
+				fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n");
+				exit(99);
+			case EACCES:
+				fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n");
+				exit(98);
+			default:
+				fprintf(stderr, "Unexpected error");
+				exit(97);
+		}
+	}
+	// n_cpu > 0
     return n_cpu;
 }
 
@@ -295,11 +314,6 @@ unsigned int init_amd_rapl(char *none, void **ptr)
     UNUSED(none);
 
     unsigned int max_cpus = get_nb_cpu();
-    if (max_cpus == 0) {
-        fprintf(stderr, base_str, 0);
-        perror(":open()");
-        exit(127);
-    }
 
     CpuSensor *cpu_information = (CpuSensor *) calloc(max_cpus, sizeof(CpuSensor));
     if (parse_cpuinfo(cpu_information, max_cpus)) {
-- 
GitLab


From f3368b52b60d7b46a39411a0e8f69e378a285f0a Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 21 Mar 2023 12:52:02 +0100
Subject: [PATCH 212/229] error handling

---
 src/amd_rapl.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index adc4461..9eaac45 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -217,7 +217,7 @@ unsigned int get_nb_cpu()
 
 	if (n_cpu == 0) {
 		perror("open()");
-		fprintf(stderr, "on %s\n", filename);
+		fprintf(stderr, "on the file: '%s'\n", filename);
 		switch (cpy_errno) {
 			case ENOENT:
 				fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n");
@@ -226,7 +226,7 @@ unsigned int get_nb_cpu()
 				fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n");
 				exit(98);
 			default:
-				fprintf(stderr, "Unexpected error");
+				fprintf(stderr, "Unexpected error\n");
 				exit(97);
 		}
 	}
-- 
GitLab


From b0ed77f36c82b785f193bf0a41b6fae1760b87e1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 27 Mar 2023 12:39:16 +0200
Subject: [PATCH 213/229] fix: fmt error msg

---
 tests/small_test.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/small_test.h b/tests/small_test.h
index 8301ae7..7e8c11e 100644
--- a/tests/small_test.h
+++ b/tests/small_test.h
@@ -270,8 +270,8 @@ int test(char *file, int line, unsigned int __indentation_level, const void *res
     static char buffer_expected[FMT_BUFFER_SIZE];
     int is_equal = interface->compare(result, expected);
 
-    char *fmt_result = interface->format(buffer_expected, expected);
-    char *fmt_expected = interface->format(buffer_result, result);
+    char *fmt_expected = interface->format(buffer_expected, expected);
+    char *fmt_result = interface->format(buffer_result, result);
     if  (!is_equal) {
         INDENTED_PRINT("%s:%d: failed, expected <%s>, got <%s>\n", file, line, fmt_expected, fmt_result);
     }
-- 
GitLab


From dadb4703629af08e5c329c0d2e1e67330874f6e3 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 27 Mar 2023 12:39:59 +0200
Subject: [PATCH 214/229] getline without alloc

---
 lib/info_reader.h          | 59 +++++++++++++++++++++++--
 tests/info_reader.c        | 90 ++++++++++++++++++++++++++++++--------
 tests/info_reader_test.txt |  9 ++++
 3 files changed, 137 insertions(+), 21 deletions(-)
 create mode 100644 tests/info_reader_test.txt

diff --git a/lib/info_reader.h b/lib/info_reader.h
index ec28db6..15a077c 100644
--- a/lib/info_reader.h
+++ b/lib/info_reader.h
@@ -105,6 +105,24 @@ static bool start_with(const char *prefix, const char *string);
  */
 static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value);
 
+/**
+* @brief Reads a line of text from a file stream and stores it in a static
+  buffer with a maximum size of PAGE_SIZE.
+
+* This function reads a line of text from the input stream pointed to by
+* 'stream'. The line of text is stored in a static buffer with a maximum size of
+* PAGE_SIZE. The function updates the pointer pointed to by 'lineptr' to point to
+* the buffer containing the line of text. If the line of text is longer than the
+* buffer, the function returns -1. If an error occurs,
+
+* @param lineptr A pointer to a pointer to the buffer where the line of text
+  will be stored.
+* @param stream A pointer to the input stream to read from.
+* @return The number of characters read, or -1 if an error occurred the
+  function returns -1.
+*/
+ssize_t buffer_getline(char **lineptr, FILE *stream);
+
 typedef size_t GenericPointer;
 typedef GenericPointer (CopyAllocator) (char *string);
 typedef void (Setter) (GenericPointer storage, GenericPointer value);
@@ -166,14 +184,50 @@ static unsigned int move_to_next(Parser *parser)
     return 1;
 }
 
+
+#define PAGE_SIZE 4096
+ssize_t buffer_getline(char **lineptr, FILE *stream) {
+    ssize_t num_chars_read = 0;
+    static char buffer[PAGE_SIZE] = {0};
+
+    if (!lineptr || !stream) {
+        return -1;
+    }
+
+    while (1) {
+        int ch = fgetc(stream);
+        if (ch == EOF) {
+            if (num_chars_read == 0) {
+                return -1;
+            } else {
+                break;
+            }
+        }
+
+        if (num_chars_read == PAGE_SIZE - 1) {
+            return -1;
+        }
+
+        buffer[num_chars_read++] = ch;
+        if (ch == '\n') {
+            break;
+        }
+    }
+
+    buffer[num_chars_read] = '\0';
+    *lineptr = buffer;
+
+    return num_chars_read;
+}
+
+
 static unsigned int parse(Parser *parser)
 {
     char *line = NULL;
-    size_t len = 0;
     ssize_t read;
     unsigned int key_assigned = 0;
 
-    while ((read = getline(&line, &len, parser->file)) != -1) {
+    while ((read = buffer_getline(&line, parser->file)) != -1) {
         if (key_assigned == parser->nb_keys && read > 1) {
             continue;
         } else if (read == 1) {
@@ -194,7 +248,6 @@ static unsigned int parse(Parser *parser)
     if (key_assigned > 0) {
         parser->nb_stored++;
     }
-    free(line);
     return 1;
 }
 
diff --git a/tests/info_reader.c b/tests/info_reader.c
index 5000f48..92f2ff9 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -169,28 +169,36 @@ TFUNCTION(test_start_with, {
 })
 
 #define NONE 0
+#define INIT_KEYFINDER(__key_finder, __key, __delimiter, __copy, __set)  \
+  do {                                                                   \
+    __key_finder = (KeyFinder) {                                         \
+      .key = __key,                                                      \
+      .delimiter = __delimiter,                                          \
+      .copy = __copy,                                                    \
+      .set = __set                                                       \
+    };                                                                   \
+  } while (0);
+
 #define DUMMY_KEYFINDER(__key_finder, __key, __delimiter) \
-  do {                                                    \
-    __key_finder = (KeyFinder) {                          \
-      .key = __key,                                       \
-      .delimiter = __delimiter,                           \
-      .copy = NONE,                                       \
-      .set = NONE                                         \
-    };                                                    \
+  INIT_KEYFINDER(__key_finder, __key, __delimiter, NONE, NONE)    \
+
+#define INIT_PARSER(__parser, __storage, __nb_stored, __capacity,     \
+                    __storage_struct_size, __keys, __nb_keys, __file) \
+do {                                                                  \
+    __parser = (Parser) {                                             \
+      .storage = __storage,                                           \
+      .nb_stored = __nb_stored,                                       \
+      .capacity = __capacity,                                         \
+      .storage_struct_size = __storage_struct_size,                   \
+      .keys = __keys,                                                 \
+      .nb_keys = __nb_keys,                                           \
+      .file = __file                                                  \
+    };                                                                \
   } while (0);
 
+
 #define DUMMY_PARSER(__parser, __keys, __nb_keys) \
-  do {                                            \
-    __parser = (Parser) {                         \
-      .storage = NONE,                            \
-      .nb_stored = NONE,                          \
-      .capacity = NONE,                           \
-      .storage_struct_size = NONE,                \
-      .keys = __keys,                             \
-      .nb_keys = __nb_keys,                       \
-      .file = NONE                                \
-    };                                            \
-  } while (0);
+  INIT_PARSER(__parser, NONE, NONE, NONE, NONE, __keys, __nb_keys, NONE)
 
 
 TFUNCTION(test_match, {
@@ -275,10 +283,56 @@ TFUNCTION(test_match, {
     TEST_STR(raw_value, NULL);
 })
 
+
+#define __NB_KEYS 4
+
+typedef struct {
+  int values[__NB_KEYS];
+} IntArray;
+
+GenericPointer __test_file_int_allocator(char *s)
+{
+    unsigned int value = atoi(s);
+    return (GenericPointer) value;
+}
+
+void __test_file_set_int(GenericPointer storage, GenericPointer data)
+{
+    IntArray *array = (IntArray*) storage;
+    int i = (int) data;
+    array->values[i] = i;
+}
+
+TFUNCTION(test_dummy_file, {
+    KeyFinder keys[__NB_KEYS];
+    INIT_KEYFINDER(keys[0], "int0", " : ", __test_file_int_allocator, __test_file_set_int);
+    INIT_KEYFINDER(keys[1], "int1", " ", __test_file_int_allocator, __test_file_set_int);
+    INIT_KEYFINDER(keys[2], "int2", " -> ", __test_file_int_allocator, __test_file_set_int);
+    INIT_KEYFINDER(keys[3], "int3", "--", __test_file_int_allocator, __test_file_set_int);
+
+    IntArray results;
+    IntArray expected;
+
+    expected.values[0] = 0;
+    expected.values[1] = 1;
+    expected.values[2] = 2;
+    expected.values[3] = 3;
+
+    Parser parser;
+    FILE* file = fopen("./tests/info_reader_test.txt", "r");
+    INIT_PARSER(parser, (GenericPointer) &results, 0, 1, sizeof(IntArray), keys, __NB_KEYS, file);
+    parse(&parser);
+
+    for (unsigned int i = 0; i < __NB_KEYS; i++) {
+        TEST_INT(&(results.values[i]), &(expected.values[i]));
+    }
+})
+
 TFILE_ENTRY_POINT(test_info_reader, {
     CALL_TFUNCTION(test_replace_first);
     CALL_TFUNCTION(test_split_on_delimiter);
     CALL_TFUNCTION(test_start_with);
     CALL_TFUNCTION(test_match);
+    CALL_TFUNCTION(test_dummy_file);
 })
 
diff --git a/tests/info_reader_test.txt b/tests/info_reader_test.txt
new file mode 100644
index 0000000..17d4ee4
--- /dev/null
+++ b/tests/info_reader_test.txt
@@ -0,0 +1,9 @@
+noise:
+int0 : 0
+noise--
+int1 1
+int2 -> 2
+noise->
+int3--3
+noise----->>ss<<
+noiseee
-- 
GitLab


From e6199994a3da3d66e0addd1eefd487e263d6cc19 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 27 Mar 2023 15:18:50 +0200
Subject: [PATCH 215/229] fix: leak close

---
 tests/info_reader.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/info_reader.c b/tests/info_reader.c
index 92f2ff9..af2873c 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -326,6 +326,7 @@ TFUNCTION(test_dummy_file, {
     for (unsigned int i = 0; i < __NB_KEYS; i++) {
         TEST_INT(&(results.values[i]), &(expected.values[i]));
     }
+    fclose(file);
 })
 
 TFILE_ENTRY_POINT(test_info_reader, {
-- 
GitLab


From 881086c732d33f02d7a3ef77d9620f06dd33d042 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 27 Mar 2023 15:20:19 +0200
Subject: [PATCH 216/229] fix: make format

---
 src/amd_rapl.c      | 34 +++++++++++++--------------
 src/network.c       |  6 ++---
 tests/info_reader.c |  9 ++++----
 tests/util.c        | 56 ++++++++++++++++++++++-----------------------
 4 files changed, 53 insertions(+), 52 deletions(-)

diff --git a/src/amd_rapl.c b/src/amd_rapl.c
index 9eaac45..572ac56 100644
--- a/src/amd_rapl.c
+++ b/src/amd_rapl.c
@@ -201,7 +201,7 @@ void debug_print_amd_rapl(AmdRapl *rapl)
 unsigned int get_nb_cpu()
 {
     char filename[BUFFER_SIZE];
-	int	cpy_errno;
+    int	cpy_errno;
 
     unsigned int n_cpu = 0;
     for (;; n_cpu++) {
@@ -215,22 +215,22 @@ unsigned int get_nb_cpu()
         close(fd);
     }
 
-	if (n_cpu == 0) {
-		perror("open()");
-		fprintf(stderr, "on the file: '%s'\n", filename);
-		switch (cpy_errno) {
-			case ENOENT:
-				fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n");
-				exit(99);
-			case EACCES:
-				fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n");
-				exit(98);
-			default:
-				fprintf(stderr, "Unexpected error\n");
-				exit(97);
-		}
-	}
-	// n_cpu > 0
+    if (n_cpu == 0) {
+        perror("open()");
+        fprintf(stderr, "on the file: '%s'\n", filename);
+        switch (cpy_errno) {
+        case ENOENT:
+            fprintf(stderr, "Amd rapl works with msr module, try to run 'sudo modprobe msr', then retry.\n");
+            exit(99);
+        case EACCES:
+            fprintf(stderr, "Amd rapl must be executed with the administrator privilege, try with 'sudo'.\n");
+            exit(98);
+        default:
+            fprintf(stderr, "Unexpected error\n");
+            exit(97);
+        }
+    }
+    // n_cpu > 0
     return n_cpu;
 }
 
diff --git a/src/network.c b/src/network.c
index a668725..fec9424 100644
--- a/src/network.c
+++ b/src/network.c
@@ -159,9 +159,9 @@ unsigned int init_network(char *dev, void **ptr)
             /* compare dev name to the previously saved one */
             int newdev = 1;
             for (int i = 0; i < state->ndev && newdev; i++) {
-	            if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
-	            	newdev = 0;
-	            }
+                if (strncmp(start_of_dev, state->devs[i], s - start_of_dev) == 0) {
+                    newdev = 0;
+                }
             }
             if (newdev) {
                 if (state->ndev >= NB_MAX_DEV) {
diff --git a/tests/info_reader.c b/tests/info_reader.c
index af2873c..1e4f281 100644
--- a/tests/info_reader.c
+++ b/tests/info_reader.c
@@ -287,7 +287,7 @@ TFUNCTION(test_match, {
 #define __NB_KEYS 4
 
 typedef struct {
-  int values[__NB_KEYS];
+    int values[__NB_KEYS];
 } IntArray;
 
 GenericPointer __test_file_int_allocator(char *s)
@@ -298,7 +298,7 @@ GenericPointer __test_file_int_allocator(char *s)
 
 void __test_file_set_int(GenericPointer storage, GenericPointer data)
 {
-    IntArray *array = (IntArray*) storage;
+    IntArray *array = (IntArray *) storage;
     int i = (int) data;
     array->values[i] = i;
 }
@@ -319,11 +319,12 @@ TFUNCTION(test_dummy_file, {
     expected.values[3] = 3;
 
     Parser parser;
-    FILE* file = fopen("./tests/info_reader_test.txt", "r");
+    FILE *file = fopen("./tests/info_reader_test.txt", "r");
     INIT_PARSER(parser, (GenericPointer) &results, 0, 1, sizeof(IntArray), keys, __NB_KEYS, file);
     parse(&parser);
 
-    for (unsigned int i = 0; i < __NB_KEYS; i++) {
+    for (unsigned int i = 0; i < __NB_KEYS; i++)
+    {
         TEST_INT(&(results.values[i]), &(expected.values[i]));
     }
     fclose(file);
diff --git a/tests/util.c b/tests/util.c
index 231ab47..ff979b9 100644
--- a/tests/util.c
+++ b/tests/util.c
@@ -78,45 +78,45 @@ TFUNCTION(test_modulo_substraction, {
 })
 
 TFUNCTION(test_max, {
-  int expected = 0;
-  int result = 0;
+    int expected = 0;
+    int result = 0;
 
-  expected = 10;
-  result = MAX(expected, 9);
-  TEST_INT(&result, &expected);
+    expected = 10;
+    result = MAX(expected, 9);
+    TEST_INT(&result, &expected);
 
-  expected = -15;
-  result = MAX(expected, -16);
-  TEST_INT(&result, &expected);
+    expected = -15;
+    result = MAX(expected, -16);
+    TEST_INT(&result, &expected);
 
-  expected = 0;
-  result = MAX(expected, -1);
-  TEST_INT(&result, &expected);
+    expected = 0;
+    result = MAX(expected, -1);
+    TEST_INT(&result, &expected);
 
-  expected = 1;
-  result = MAX(expected, 0);
-  TEST_INT(&result, &expected);
+    expected = 1;
+    result = MAX(expected, 0);
+    TEST_INT(&result, &expected);
 })
 
 TFUNCTION(test_min, {
-  int expected = 0;
-  int result = 0;
+    int expected = 0;
+    int result = 0;
 
-  expected = 9;
-  result = MIN(expected, 10);
-  TEST_INT(&result, &expected);
+    expected = 9;
+    result = MIN(expected, 10);
+    TEST_INT(&result, &expected);
 
-  expected = -16;
-  result = MIN(expected, -15);
-  TEST_INT(&result, &expected);
+    expected = -16;
+    result = MIN(expected, -15);
+    TEST_INT(&result, &expected);
 
-  expected = -1;
-  result = MIN(expected, 0);
-  TEST_INT(&result, &expected);
+    expected = -1;
+    result = MIN(expected, 0);
+    TEST_INT(&result, &expected);
 
-  expected = 0;
-  result = MIN(expected, 1);
-  TEST_INT(&result, &expected);
+    expected = 0;
+    result = MIN(expected, 1);
+    TEST_INT(&result, &expected);
 })
 
 TFILE_ENTRY_POINT(test_util, {
-- 
GitLab


From 064cfdf09660498e5b001c5d075585c7530164c3 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Mon, 27 Mar 2023 18:55:37 +0200
Subject: [PATCH 217/229] working on progress

---
 meminfo_option.sh    |  48 ++++++
 src/meminfo_option.h | 402 +++++++++++++++++++++++++++++++++++++++++++
 src/memory_extra.c   |  95 ++++++++++
 3 files changed, 545 insertions(+)
 create mode 100644 meminfo_option.sh
 create mode 100644 src/meminfo_option.h
 create mode 100644 src/memory_extra.c

diff --git a/meminfo_option.sh b/meminfo_option.sh
new file mode 100644
index 0000000..4443868
--- /dev/null
+++ b/meminfo_option.sh
@@ -0,0 +1,48 @@
+#!bin/sh
+
+MEMINFO="/proc/meminfo"
+COUNT=0
+
+function get_meminfo_words {
+	printf "char *meminfo_words[] = {\n"
+	while read line; do
+		COUNT=$(expr $COUNT + 1)
+		word=$(echo $line | awk '{print $1}')
+		printf "    \"${word::-1}\",\n"
+	done <$MEMINFO
+
+	printf "};\n\n"
+}
+
+function get_count {
+	printf "static const unsigned int meminfo_count = $COUNT;\n\n"
+}
+
+function get_meminfo_setter {
+	count=0
+	while [ $count -lt $COUNT ]; do
+		printf "void set_result_offset$count(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[$count] = (uint64_t) data;
+}\n\n"
+		count=$(expr $count + 1)
+	done
+}
+
+function get_functions {
+	printf "static void (*setter_functions[])(GenericPointer, GenericPointer) = {\n"
+	count=0
+	while [ $count -lt $COUNT ]; do
+		printf "    set_result_offset$count,\n"
+		count=$(expr $count + 1)
+	done
+	printf "};\n\n"
+}
+
+DEST="./src/meminfo_option.h"
+printf "#include \"inttypes.h\"\n" >$DEST
+printf "#include <info_reader.h>\n\n" >>$DEST
+get_meminfo_words "./text.h" >>$DEST
+get_count >>$DEST
+get_meminfo_setter >>$DEST
+get_functions >>$DEST
diff --git a/src/meminfo_option.h b/src/meminfo_option.h
new file mode 100644
index 0000000..f3369b8
--- /dev/null
+++ b/src/meminfo_option.h
@@ -0,0 +1,402 @@
+#include "inttypes.h"
+#include <info_reader.h>
+char *meminfo_words[] = {
+    "MemTotal",
+    "MemFree",
+    "MemAvailable",
+    "Buffers",
+    "Cached",
+    "SwapCached",
+    "Active",
+    "Inactive",
+    "Active(anon)",
+    "Inactive(anon)",
+    "Active(file)",
+    "Inactive(file)",
+    "Unevictable",
+    "Mlocked",
+    "SwapTotal",
+    "SwapFree",
+    "Zswap",
+    "Zswapped",
+    "Dirty",
+    "Writeback",
+    "AnonPages",
+    "Mapped",
+    "Shmem",
+    "KReclaimable",
+    "Slab",
+    "SReclaimable",
+    "SUnreclaim",
+    "KernelStack",
+    "PageTables",
+    "SecPageTables",
+    "NFS_Unstable",
+    "Bounce",
+    "WritebackTmp",
+    "CommitLimit",
+    "Committed_AS",
+    "VmallocTotal",
+    "VmallocUsed",
+    "VmallocChunk",
+    "Percpu",
+    "HardwareCorrupted",
+    "AnonHugePages",
+    "ShmemHugePages",
+    "ShmemPmdMapped",
+    "FileHugePages",
+    "FilePmdMapped",
+    "CmaTotal",
+    "CmaFree",
+    "HugePages_Total",
+    "HugePages_Free",
+    "HugePages_Rsvd",
+    "HugePages_Surp",
+    "Hugepagesize",
+    "Hugetlb",
+    "DirectMap4k",
+    "DirectMap2M",
+    "DirectMap1G",
+};
+
+static const unsigned int meminfo_count = 56;
+
+void set_result_offset0(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[0] = (uint64_t) data;
+}
+
+void set_result_offset1(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[1] = (uint64_t) data;
+}
+
+void set_result_offset2(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[2] = (uint64_t) data;
+}
+
+void set_result_offset3(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[3] = (uint64_t) data;
+}
+
+void set_result_offset4(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[4] = (uint64_t) data;
+}
+
+void set_result_offset5(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[5] = (uint64_t) data;
+}
+
+void set_result_offset6(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[6] = (uint64_t) data;
+}
+
+void set_result_offset7(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[7] = (uint64_t) data;
+}
+
+void set_result_offset8(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[8] = (uint64_t) data;
+}
+
+void set_result_offset9(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[9] = (uint64_t) data;
+}
+
+void set_result_offset10(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[10] = (uint64_t) data;
+}
+
+void set_result_offset11(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[11] = (uint64_t) data;
+}
+
+void set_result_offset12(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[12] = (uint64_t) data;
+}
+
+void set_result_offset13(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[13] = (uint64_t) data;
+}
+
+void set_result_offset14(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[14] = (uint64_t) data;
+}
+
+void set_result_offset15(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[15] = (uint64_t) data;
+}
+
+void set_result_offset16(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[16] = (uint64_t) data;
+}
+
+void set_result_offset17(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[17] = (uint64_t) data;
+}
+
+void set_result_offset18(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[18] = (uint64_t) data;
+}
+
+void set_result_offset19(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[19] = (uint64_t) data;
+}
+
+void set_result_offset20(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[20] = (uint64_t) data;
+}
+
+void set_result_offset21(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[21] = (uint64_t) data;
+}
+
+void set_result_offset22(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[22] = (uint64_t) data;
+}
+
+void set_result_offset23(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[23] = (uint64_t) data;
+}
+
+void set_result_offset24(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[24] = (uint64_t) data;
+}
+
+void set_result_offset25(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[25] = (uint64_t) data;
+}
+
+void set_result_offset26(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[26] = (uint64_t) data;
+}
+
+void set_result_offset27(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[27] = (uint64_t) data;
+}
+
+void set_result_offset28(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[28] = (uint64_t) data;
+}
+
+void set_result_offset29(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[29] = (uint64_t) data;
+}
+
+void set_result_offset30(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[30] = (uint64_t) data;
+}
+
+void set_result_offset31(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[31] = (uint64_t) data;
+}
+
+void set_result_offset32(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[32] = (uint64_t) data;
+}
+
+void set_result_offset33(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[33] = (uint64_t) data;
+}
+
+void set_result_offset34(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[34] = (uint64_t) data;
+}
+
+void set_result_offset35(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[35] = (uint64_t) data;
+}
+
+void set_result_offset36(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[36] = (uint64_t) data;
+}
+
+void set_result_offset37(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[37] = (uint64_t) data;
+}
+
+void set_result_offset38(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[38] = (uint64_t) data;
+}
+
+void set_result_offset39(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[39] = (uint64_t) data;
+}
+
+void set_result_offset40(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[40] = (uint64_t) data;
+}
+
+void set_result_offset41(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[41] = (uint64_t) data;
+}
+
+void set_result_offset42(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[42] = (uint64_t) data;
+}
+
+void set_result_offset43(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[43] = (uint64_t) data;
+}
+
+void set_result_offset44(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[44] = (uint64_t) data;
+}
+
+void set_result_offset45(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[45] = (uint64_t) data;
+}
+
+void set_result_offset46(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[46] = (uint64_t) data;
+}
+
+void set_result_offset47(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[47] = (uint64_t) data;
+}
+
+void set_result_offset48(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[48] = (uint64_t) data;
+}
+
+void set_result_offset49(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[49] = (uint64_t) data;
+}
+
+void set_result_offset50(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[50] = (uint64_t) data;
+}
+
+void set_result_offset51(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[51] = (uint64_t) data;
+}
+
+void set_result_offset52(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[52] = (uint64_t) data;
+}
+
+void set_result_offset53(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[53] = (uint64_t) data;
+}
+
+void set_result_offset54(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[54] = (uint64_t) data;
+}
+
+void set_result_offset55(GenericPointer ptr, GenericPointer data) {
+    uint64_t* result = (uint64_t *) ptr;
+    result[55] = (uint64_t) data;
+}
+
+static void (*setter_functions[])(GenericPointer, GenericPointer) = {
+    set_result_offset0,
+    set_result_offset1,
+    set_result_offset2,
+    set_result_offset3,
+    set_result_offset4,
+    set_result_offset5,
+    set_result_offset6,
+    set_result_offset7,
+    set_result_offset8,
+    set_result_offset9,
+    set_result_offset10,
+    set_result_offset11,
+    set_result_offset12,
+    set_result_offset13,
+    set_result_offset14,
+    set_result_offset15,
+    set_result_offset16,
+    set_result_offset17,
+    set_result_offset18,
+    set_result_offset19,
+    set_result_offset20,
+    set_result_offset21,
+    set_result_offset22,
+    set_result_offset23,
+    set_result_offset24,
+    set_result_offset25,
+    set_result_offset26,
+    set_result_offset27,
+    set_result_offset28,
+    set_result_offset29,
+    set_result_offset30,
+    set_result_offset31,
+    set_result_offset32,
+    set_result_offset33,
+    set_result_offset34,
+    set_result_offset35,
+    set_result_offset36,
+    set_result_offset37,
+    set_result_offset38,
+    set_result_offset39,
+    set_result_offset40,
+    set_result_offset41,
+    set_result_offset42,
+    set_result_offset43,
+    set_result_offset44,
+    set_result_offset45,
+    set_result_offset46,
+    set_result_offset47,
+    set_result_offset48,
+    set_result_offset49,
+    set_result_offset50,
+    set_result_offset51,
+    set_result_offset52,
+    set_result_offset53,
+    set_result_offset54,
+    set_result_offset55,
+};
+
diff --git a/src/memory_extra.c b/src/memory_extra.c
new file mode 100644
index 0000000..f616870
--- /dev/null
+++ b/src/memory_extra.c
@@ -0,0 +1,95 @@
+#include "meminfo_option.h"
+#include <info_reader.h>
+#include <inttypes.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *path = "/proc/meminfo";
+
+GenericPointer long_allocator(char *s) {
+  long value = atol(s);
+  return (GenericPointer)value;
+}
+
+KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) {
+  KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
+  for (unsigned int i = 0; i < count; i++) {
+    unsigned int idx = indexes[i];
+    KeyFinder key = {.key = meminfo_words[idx],
+                     .delimiter = ":",
+                     .copy = long_allocator,
+                     .set = setter_functions[i]};
+    memcpy(&keys[i], &key, sizeof(KeyFinder));
+  }
+  return keys;
+}
+
+void memory_list(char *memory_string, unsigned int *count,
+                 unsigned int *indexes) {
+  char *token;
+  *count = 0;
+
+  while ((token = strtok(memory_string, ",")) != NULL) {
+    memory_string = NULL;
+
+    unsigned int i;
+    for (i = 0; i < meminfo_count; i++) {
+      if (strcmp(meminfo_words[i], token) == 0) {
+        (*count)++;
+        indexes[*count - 1] = i;
+        break;
+      }
+    }
+
+    if (i == meminfo_count) {
+      fprintf(stderr, "Unknown memory counter: %s\n", token);
+      exit(EXIT_FAILURE);
+    }
+
+    if ((*count) > meminfo_count) {
+      fprintf(stderr, "Too much counters, there are probably duplicates\n");
+      exit(EXIT_FAILURE);
+    }
+  }
+}
+
+int main(int argc, char **argv) {
+
+  if (argc != 2) {
+    fprintf(stderr, "Usage ... [elem1,elem2...]\n");
+    exit(EXIT_FAILURE);
+  }
+
+  unsigned int indexes[meminfo_count];
+  unsigned int count = 0;
+  memory_list(argv[1], &count, indexes);
+
+  printf("%d, count \n", count);
+
+  KeyFinder *keys = build_keyfinder(count, indexes);
+  uint64_t value[count];
+
+  // -- Init the parser
+  Parser parser = {.storage = (GenericPointer)&value,
+                   .capacity = 1,
+                   .storage_struct_size = sizeof(uint64_t) * count,
+                   .keys = keys,
+                   .nb_keys = count,
+                   .file = fopen(path, "r")};
+
+  // -- Parse the file
+  while (1) {
+    parse(&parser);
+    for (unsigned int i = 0; i < count; i++) {
+      printf("%s: %" PRIu64 "\n", keys[i].key, value[i]);
+    }
+  }
+
+  free(keys);
+
+  // Print and free the results
+
+  fclose(parser.file);
+  return 0;
+}
-- 
GitLab


From 5149f2fe08bc672f671b9afff72192885f14b120 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 09:36:14 +0200
Subject: [PATCH 218/229] update: script

---
 .gitignore                                |   1 +
 meminfo_option.sh                         |  48 ---
 src/meminfo_option.h                      | 402 ----------------------
 src/meminfo_option.sh                     |  46 +++
 src/{memory_extra.c => memory_counters.c} |  12 +-
 5 files changed, 53 insertions(+), 456 deletions(-)
 delete mode 100644 meminfo_option.sh
 delete mode 100644 src/meminfo_option.h
 create mode 100644 src/meminfo_option.sh
 rename src/{memory_extra.c => memory_counters.c} (89%)

diff --git a/.gitignore b/.gitignore
index 83a8dc0..eb6940e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@ doc/info_reader_ex
 doc/mojitos.1
 tests/run
 src/counters_option.h
+src/meminfo_option.h
 src/sensors.h
 sensors.mk
 bin
diff --git a/meminfo_option.sh b/meminfo_option.sh
deleted file mode 100644
index 4443868..0000000
--- a/meminfo_option.sh
+++ /dev/null
@@ -1,48 +0,0 @@
-#!bin/sh
-
-MEMINFO="/proc/meminfo"
-COUNT=0
-
-function get_meminfo_words {
-	printf "char *meminfo_words[] = {\n"
-	while read line; do
-		COUNT=$(expr $COUNT + 1)
-		word=$(echo $line | awk '{print $1}')
-		printf "    \"${word::-1}\",\n"
-	done <$MEMINFO
-
-	printf "};\n\n"
-}
-
-function get_count {
-	printf "static const unsigned int meminfo_count = $COUNT;\n\n"
-}
-
-function get_meminfo_setter {
-	count=0
-	while [ $count -lt $COUNT ]; do
-		printf "void set_result_offset$count(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[$count] = (uint64_t) data;
-}\n\n"
-		count=$(expr $count + 1)
-	done
-}
-
-function get_functions {
-	printf "static void (*setter_functions[])(GenericPointer, GenericPointer) = {\n"
-	count=0
-	while [ $count -lt $COUNT ]; do
-		printf "    set_result_offset$count,\n"
-		count=$(expr $count + 1)
-	done
-	printf "};\n\n"
-}
-
-DEST="./src/meminfo_option.h"
-printf "#include \"inttypes.h\"\n" >$DEST
-printf "#include <info_reader.h>\n\n" >>$DEST
-get_meminfo_words "./text.h" >>$DEST
-get_count >>$DEST
-get_meminfo_setter >>$DEST
-get_functions >>$DEST
diff --git a/src/meminfo_option.h b/src/meminfo_option.h
deleted file mode 100644
index f3369b8..0000000
--- a/src/meminfo_option.h
+++ /dev/null
@@ -1,402 +0,0 @@
-#include "inttypes.h"
-#include <info_reader.h>
-char *meminfo_words[] = {
-    "MemTotal",
-    "MemFree",
-    "MemAvailable",
-    "Buffers",
-    "Cached",
-    "SwapCached",
-    "Active",
-    "Inactive",
-    "Active(anon)",
-    "Inactive(anon)",
-    "Active(file)",
-    "Inactive(file)",
-    "Unevictable",
-    "Mlocked",
-    "SwapTotal",
-    "SwapFree",
-    "Zswap",
-    "Zswapped",
-    "Dirty",
-    "Writeback",
-    "AnonPages",
-    "Mapped",
-    "Shmem",
-    "KReclaimable",
-    "Slab",
-    "SReclaimable",
-    "SUnreclaim",
-    "KernelStack",
-    "PageTables",
-    "SecPageTables",
-    "NFS_Unstable",
-    "Bounce",
-    "WritebackTmp",
-    "CommitLimit",
-    "Committed_AS",
-    "VmallocTotal",
-    "VmallocUsed",
-    "VmallocChunk",
-    "Percpu",
-    "HardwareCorrupted",
-    "AnonHugePages",
-    "ShmemHugePages",
-    "ShmemPmdMapped",
-    "FileHugePages",
-    "FilePmdMapped",
-    "CmaTotal",
-    "CmaFree",
-    "HugePages_Total",
-    "HugePages_Free",
-    "HugePages_Rsvd",
-    "HugePages_Surp",
-    "Hugepagesize",
-    "Hugetlb",
-    "DirectMap4k",
-    "DirectMap2M",
-    "DirectMap1G",
-};
-
-static const unsigned int meminfo_count = 56;
-
-void set_result_offset0(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[0] = (uint64_t) data;
-}
-
-void set_result_offset1(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[1] = (uint64_t) data;
-}
-
-void set_result_offset2(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[2] = (uint64_t) data;
-}
-
-void set_result_offset3(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[3] = (uint64_t) data;
-}
-
-void set_result_offset4(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[4] = (uint64_t) data;
-}
-
-void set_result_offset5(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[5] = (uint64_t) data;
-}
-
-void set_result_offset6(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[6] = (uint64_t) data;
-}
-
-void set_result_offset7(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[7] = (uint64_t) data;
-}
-
-void set_result_offset8(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[8] = (uint64_t) data;
-}
-
-void set_result_offset9(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[9] = (uint64_t) data;
-}
-
-void set_result_offset10(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[10] = (uint64_t) data;
-}
-
-void set_result_offset11(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[11] = (uint64_t) data;
-}
-
-void set_result_offset12(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[12] = (uint64_t) data;
-}
-
-void set_result_offset13(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[13] = (uint64_t) data;
-}
-
-void set_result_offset14(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[14] = (uint64_t) data;
-}
-
-void set_result_offset15(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[15] = (uint64_t) data;
-}
-
-void set_result_offset16(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[16] = (uint64_t) data;
-}
-
-void set_result_offset17(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[17] = (uint64_t) data;
-}
-
-void set_result_offset18(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[18] = (uint64_t) data;
-}
-
-void set_result_offset19(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[19] = (uint64_t) data;
-}
-
-void set_result_offset20(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[20] = (uint64_t) data;
-}
-
-void set_result_offset21(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[21] = (uint64_t) data;
-}
-
-void set_result_offset22(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[22] = (uint64_t) data;
-}
-
-void set_result_offset23(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[23] = (uint64_t) data;
-}
-
-void set_result_offset24(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[24] = (uint64_t) data;
-}
-
-void set_result_offset25(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[25] = (uint64_t) data;
-}
-
-void set_result_offset26(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[26] = (uint64_t) data;
-}
-
-void set_result_offset27(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[27] = (uint64_t) data;
-}
-
-void set_result_offset28(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[28] = (uint64_t) data;
-}
-
-void set_result_offset29(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[29] = (uint64_t) data;
-}
-
-void set_result_offset30(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[30] = (uint64_t) data;
-}
-
-void set_result_offset31(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[31] = (uint64_t) data;
-}
-
-void set_result_offset32(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[32] = (uint64_t) data;
-}
-
-void set_result_offset33(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[33] = (uint64_t) data;
-}
-
-void set_result_offset34(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[34] = (uint64_t) data;
-}
-
-void set_result_offset35(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[35] = (uint64_t) data;
-}
-
-void set_result_offset36(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[36] = (uint64_t) data;
-}
-
-void set_result_offset37(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[37] = (uint64_t) data;
-}
-
-void set_result_offset38(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[38] = (uint64_t) data;
-}
-
-void set_result_offset39(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[39] = (uint64_t) data;
-}
-
-void set_result_offset40(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[40] = (uint64_t) data;
-}
-
-void set_result_offset41(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[41] = (uint64_t) data;
-}
-
-void set_result_offset42(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[42] = (uint64_t) data;
-}
-
-void set_result_offset43(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[43] = (uint64_t) data;
-}
-
-void set_result_offset44(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[44] = (uint64_t) data;
-}
-
-void set_result_offset45(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[45] = (uint64_t) data;
-}
-
-void set_result_offset46(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[46] = (uint64_t) data;
-}
-
-void set_result_offset47(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[47] = (uint64_t) data;
-}
-
-void set_result_offset48(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[48] = (uint64_t) data;
-}
-
-void set_result_offset49(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[49] = (uint64_t) data;
-}
-
-void set_result_offset50(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[50] = (uint64_t) data;
-}
-
-void set_result_offset51(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[51] = (uint64_t) data;
-}
-
-void set_result_offset52(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[52] = (uint64_t) data;
-}
-
-void set_result_offset53(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[53] = (uint64_t) data;
-}
-
-void set_result_offset54(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[54] = (uint64_t) data;
-}
-
-void set_result_offset55(GenericPointer ptr, GenericPointer data) {
-    uint64_t* result = (uint64_t *) ptr;
-    result[55] = (uint64_t) data;
-}
-
-static void (*setter_functions[])(GenericPointer, GenericPointer) = {
-    set_result_offset0,
-    set_result_offset1,
-    set_result_offset2,
-    set_result_offset3,
-    set_result_offset4,
-    set_result_offset5,
-    set_result_offset6,
-    set_result_offset7,
-    set_result_offset8,
-    set_result_offset9,
-    set_result_offset10,
-    set_result_offset11,
-    set_result_offset12,
-    set_result_offset13,
-    set_result_offset14,
-    set_result_offset15,
-    set_result_offset16,
-    set_result_offset17,
-    set_result_offset18,
-    set_result_offset19,
-    set_result_offset20,
-    set_result_offset21,
-    set_result_offset22,
-    set_result_offset23,
-    set_result_offset24,
-    set_result_offset25,
-    set_result_offset26,
-    set_result_offset27,
-    set_result_offset28,
-    set_result_offset29,
-    set_result_offset30,
-    set_result_offset31,
-    set_result_offset32,
-    set_result_offset33,
-    set_result_offset34,
-    set_result_offset35,
-    set_result_offset36,
-    set_result_offset37,
-    set_result_offset38,
-    set_result_offset39,
-    set_result_offset40,
-    set_result_offset41,
-    set_result_offset42,
-    set_result_offset43,
-    set_result_offset44,
-    set_result_offset45,
-    set_result_offset46,
-    set_result_offset47,
-    set_result_offset48,
-    set_result_offset49,
-    set_result_offset50,
-    set_result_offset51,
-    set_result_offset52,
-    set_result_offset53,
-    set_result_offset54,
-    set_result_offset55,
-};
-
diff --git a/src/meminfo_option.sh b/src/meminfo_option.sh
new file mode 100644
index 0000000..54a2c6e
--- /dev/null
+++ b/src/meminfo_option.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# SPDX-License-Identifier: GPL-3.0-or-later
+# Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+MEMINFO_PATH="/proc/meminfo"
+
+FUNCTION_TEMPLATE="void set_result_offset%s(GenericPointer ptr, GenericPointer data)
+{
+    uint64_t* result = (uint64_t *) ptr;
+    result[%s] = (uint64_t) data;
+}\n\n"
+
+nb_counters=0
+
+echo '#include <inttypes.h>'
+echo "#include <info_reader.h>"
+echo
+
+echo 'static char *memory_counters[] = {'
+while read line; do
+  nb_counters=$(expr $nb_counters + 1)
+  word=$(echo $line | awk '{print $1}')
+  echo "    \"${word::-1}\","
+done <$MEMINFO_PATH
+echo "};"
+echo
+
+echo "#define NB_COUNTERS $nb_counters"
+echo
+
+count=0
+while [ $count -lt $nb_counters ]; do
+  printf "$FUNCTION_TEMPLATE" $count $count
+  count=$(expr $count + 1)
+done
+
+echo "static void (*setter_functions[])(GenericPointer, GenericPointer) = {"
+count=0
+while [ $count -lt $nb_counters ]; do
+  echo "    set_result_offset$count,"
+  count=$(expr $count + 1)
+done
+echo "};"
+echo
+
diff --git a/src/memory_extra.c b/src/memory_counters.c
similarity index 89%
rename from src/memory_extra.c
rename to src/memory_counters.c
index f616870..4572ff0 100644
--- a/src/memory_extra.c
+++ b/src/memory_counters.c
@@ -16,7 +16,7 @@ KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) {
   KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
   for (unsigned int i = 0; i < count; i++) {
     unsigned int idx = indexes[i];
-    KeyFinder key = {.key = meminfo_words[idx],
+    KeyFinder key = {.key = memory_counters[idx],
                      .delimiter = ":",
                      .copy = long_allocator,
                      .set = setter_functions[i]};
@@ -34,20 +34,20 @@ void memory_list(char *memory_string, unsigned int *count,
     memory_string = NULL;
 
     unsigned int i;
-    for (i = 0; i < meminfo_count; i++) {
-      if (strcmp(meminfo_words[i], token) == 0) {
+    for (i = 0; i < NB_COUNTERS; i++) {
+      if (strcmp(memory_counters[i], token) == 0) {
         (*count)++;
         indexes[*count - 1] = i;
         break;
       }
     }
 
-    if (i == meminfo_count) {
+    if (i == NB_COUNTERS) {
       fprintf(stderr, "Unknown memory counter: %s\n", token);
       exit(EXIT_FAILURE);
     }
 
-    if ((*count) > meminfo_count) {
+    if ((*count) > NB_COUNTERS) {
       fprintf(stderr, "Too much counters, there are probably duplicates\n");
       exit(EXIT_FAILURE);
     }
@@ -61,7 +61,7 @@ int main(int argc, char **argv) {
     exit(EXIT_FAILURE);
   }
 
-  unsigned int indexes[meminfo_count];
+  unsigned int indexes[NB_COUNTERS];
   unsigned int count = 0;
   memory_list(argv[1], &count, indexes);
 
-- 
GitLab


From db433cca717ddc0ec8842eb6a3c155817e95a7fc Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:00:50 +0200
Subject: [PATCH 219/229] update: create api

---
 src/memory_counters.c | 74 +++++++++++++++++++++++++------------------
 1 file changed, 44 insertions(+), 30 deletions(-)

diff --git a/src/memory_counters.c b/src/memory_counters.c
index 4572ff0..7225352 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -1,4 +1,6 @@
 #include "meminfo_option.h"
+#include <bits/stdint-uintn.h>
+#include <fcntl.h>
 #include <info_reader.h>
 #include <inttypes.h>
 #include <stdio.h>
@@ -7,6 +9,12 @@
 
 static const char *path = "/proc/meminfo";
 
+typedef struct {
+  KeyFinder *keys;
+  unsigned int count;
+  FILE *file;
+} MemoryCounters;
+
 GenericPointer long_allocator(char *s) {
   long value = atol(s);
   return (GenericPointer)value;
@@ -54,42 +62,48 @@ void memory_list(char *memory_string, unsigned int *count,
   }
 }
 
-int main(int argc, char **argv) {
-
-  if (argc != 2) {
-    fprintf(stderr, "Usage ... [elem1,elem2...]\n");
-    exit(EXIT_FAILURE);
-  }
-
+unsigned int init_memory_counters(char *args, void **ptr) {
   unsigned int indexes[NB_COUNTERS];
   unsigned int count = 0;
-  memory_list(argv[1], &count, indexes);
-
-  printf("%d, count \n", count);
+  memory_list(args, &count, indexes);
 
   KeyFinder *keys = build_keyfinder(count, indexes);
-  uint64_t value[count];
+  FILE *file = fopen(path, "r");
 
-  // -- Init the parser
-  Parser parser = {.storage = (GenericPointer)&value,
-                   .capacity = 1,
-                   .storage_struct_size = sizeof(uint64_t) * count,
-                   .keys = keys,
-                   .nb_keys = count,
-                   .file = fopen(path, "r")};
-
-  // -- Parse the file
-  while (1) {
-    parse(&parser);
-    for (unsigned int i = 0; i < count; i++) {
-      printf("%s: %" PRIu64 "\n", keys[i].key, value[i]);
-    }
-  }
+  MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
+  counters->keys = keys;
+  counters->count = count;
+  counters->file = file;
 
-  free(keys);
+  *ptr = (void *)counters;
+  return count;
+}
 
-  // Print and free the results
+unsigned int get_memory_counters(uint64_t *results, void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  fseek(counters->file, 0, SEEK_SET);
+  Parser parser = {.storage = (GenericPointer)results,
+                   .capacity = 1,
+                   .nb_stored = 0,
+                   .storage_struct_size = sizeof(uint64_t) * counters->count,
+                   .keys = counters->keys,
+                   .nb_keys = counters->count,
+                   .file = counters->file};
+
+  parse(&parser);
+  return counters->count;
+}
+
+void label_memory_counters(char **labels, void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  for (unsigned int i = 0; i < counters->count; i++) {
+    labels[i] = counters->keys[i].key;
+  }
+}
 
-  fclose(parser.file);
-  return 0;
+void clean_memory_counters(void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  fclose(counters->file);
+  free(counters->keys);
+  free(ptr);
 }
-- 
GitLab


From f1348876b0dd2f8872f0ebf0bab6b9f80ca63f79 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:11:08 +0200
Subject: [PATCH 220/229] update header

---
 src/memory_counters.c | 13 ++++++++++-
 src/memory_counters.h | 54 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 66 insertions(+), 1 deletion(-)
 create mode 100644 src/memory_counters.h

diff --git a/src/memory_counters.c b/src/memory_counters.c
index 7225352..23e3f96 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -1,5 +1,5 @@
 #include "meminfo_option.h"
-#include <bits/stdint-uintn.h>
+#include "util.h"
 #include <fcntl.h>
 #include <info_reader.h>
 #include <inttypes.h>
@@ -107,3 +107,14 @@ void clean_memory_counters(void *ptr) {
   free(counters->keys);
   free(ptr);
 }
+
+void *show_all_memory_counters(void *none1, size_t none2) {
+  for (unsigned int i = 0; i < NB_COUNTERS; i++) {
+    printf("%s\n", memory_counters[i]);
+  }
+
+  UNUSED(none1);
+  UNUSED(none2);
+  exit(EXIT_SUCCESS);
+  return NULL; /* not reached */
+}
diff --git a/src/memory_counters.h b/src/memory_counters.h
new file mode 100644
index 0000000..a066c42
--- /dev/null
+++ b/src/memory_counters.h
@@ -0,0 +1,54 @@
+/*******************************************************
+ Copyright (C) 2023-2023 Georges Da Costa <georges.da-costa@irit.fr>
+
+    This file is part of Mojitos.
+
+    Mojitos is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    Mojitos is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with MojitO/S.  If not, see <https://www.gnu.org/licenses/>.
+
+ *******************************************************/
+
+unsigned int init_memory_counters(char *args, void **ptr);
+unsigned int get_memory_counters(uint64_t *results, void *ptr);
+void label_memory_counters(char **labels, void *ptr);
+void clean_memory_counters(void *ptr);
+void *show_all_memory_counters(void *, size_t);
+
+sensor memory_counters = {
+    .init = init_memory_counters,
+    .get = get_memory_counters,
+    .clean = clean_memory_counters,
+    .label = label_memory_counters,
+    .nb_opt = 2,
+};
+
+Optparse memory_counters_opt[2] = {
+    {
+        .longname = "memory-counters",
+        .shortname = 'M',
+        .argtype = OPTPARSE_REQUIRED,
+        .usage_arg = "<memory_list>",
+        .usage_msg =
+            "memory counters\n"
+            "\tmemory_list is a coma separated list of memory counters.\n"
+            "\tEx: Zswap,Zswapped",
+    },
+    {
+        .longname = "memory-list",
+        .shortname = 'L',
+        .argtype = OPTPARSE_NONE,
+        .usage_arg = NULL,
+        .usage_msg = "list the available performance counters and quit",
+        .fn = show_all_memory_counters,
+    },
+};
-- 
GitLab


From a9496a7f8861c9bbe7994b110f89a93f2d6bfdd5 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:28:33 +0200
Subject: [PATCH 221/229] update: add in autoconf

---
 .gitignore                                  | 2 +-
 configure.sh                                | 1 +
 makefile                                    | 6 +++++-
 src/memory_counters.h                       | 2 +-
 src/{meminfo_option.sh => memory_option.sh} | 0
 5 files changed, 8 insertions(+), 3 deletions(-)
 rename src/{meminfo_option.sh => memory_option.sh} (100%)
 mode change 100644 => 100755

diff --git a/.gitignore b/.gitignore
index eb6940e..d652549 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,7 +6,7 @@ doc/info_reader_ex
 doc/mojitos.1
 tests/run
 src/counters_option.h
-src/meminfo_option.h
+src/memory_option.h
 src/sensors.h
 sensors.mk
 bin
diff --git a/configure.sh b/configure.sh
index 7e10ec3..56abf93 100755
--- a/configure.sh
+++ b/configure.sh
@@ -117,6 +117,7 @@ detect_caps() {
 	[ -r /usr/include/linux/perf_event.h ] && hdr_whitelist=counters
 	[ -d /sys/class/infiniband ] && hdr_whitelist="${hdr_whitelist}|infiniband"
 	[ -r /proc/stat ] && hdr_whitelist="${hdr_whitelist}|load"
+	[ -r /proc/meminfo ] && hdr_whitelist="${hdr_whitelist}|memory_counters"
 
 	if [ "$(uname -r | cut -d "." -f 1)" -gt "2" ]; then
 		hdr_whitelist="${hdr_whitelist}|memory"
diff --git a/makefile b/makefile
index f25d563..63fa983 100644
--- a/makefile
+++ b/makefile
@@ -40,8 +40,9 @@ $(BIN): $(BIN_DIR) $(OBJ) $(OBJ_DIR)/$(BIN).o
 
 $(OBJ): $(OBJ_DIR)
 $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
+$(OBJ_DIR)/memory_counters.o: $(SRC_DIR)/memory_option.h
 
-$(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h
+$(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h $(SRC_DIR)/memory_counters.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
 $(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
@@ -50,6 +51,9 @@ $(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
 $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
 	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
 
+$(SRC_DIR)/memory_option.h: $(SRC_DIR)/memory_option.sh
+	sh ./$(SRC_DIR)/memory_option.sh > $(SRC_DIR)/memory_option.h
+
 $(OBJ_DIR):
 	mkdir -p $(OBJ_DIR)
 
diff --git a/src/memory_counters.h b/src/memory_counters.h
index a066c42..a0b9613 100644
--- a/src/memory_counters.h
+++ b/src/memory_counters.h
@@ -24,7 +24,7 @@ void label_memory_counters(char **labels, void *ptr);
 void clean_memory_counters(void *ptr);
 void *show_all_memory_counters(void *, size_t);
 
-sensor memory_counters = {
+Sensor memory_counters = {
     .init = init_memory_counters,
     .get = get_memory_counters,
     .clean = clean_memory_counters,
diff --git a/src/meminfo_option.sh b/src/memory_option.sh
old mode 100644
new mode 100755
similarity index 100%
rename from src/meminfo_option.sh
rename to src/memory_option.sh
-- 
GitLab


From 0e090d56181052a6fd014377602915efd8d69c7c Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:29:39 +0200
Subject: [PATCH 222/229] fix header name

---
 src/memory_counters.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/memory_counters.c b/src/memory_counters.c
index 23e3f96..8e8e916 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -1,4 +1,4 @@
-#include "meminfo_option.h"
+#include "memory_option.h"
 #include "util.h"
 #include <fcntl.h>
 #include <info_reader.h>
-- 
GitLab


From e969987e3c39fdd4e7ddcdbc084a89fb00431cda Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:43:45 +0200
Subject: [PATCH 223/229] fix: clean, usage

---
 makefile              | 1 +
 src/memory_counters.h | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/makefile b/makefile
index 63fa983..a57eca2 100644
--- a/makefile
+++ b/makefile
@@ -75,6 +75,7 @@ format:
 clean:
 	\rm -f $(OBJ_DIR)/* $(BIN_DIR)/* \
 		$(SRC_DIR)/counters_option.h \
+		$(SRC_DIR)/memory_option.h \
 		$(TESTS_DIR)/run \
 		$(DOC_DIR)/test_main_ex \
 		$(DOC_DIR)/info_reader_ex
diff --git a/src/memory_counters.h b/src/memory_counters.h
index a0b9613..50e0be3 100644
--- a/src/memory_counters.h
+++ b/src/memory_counters.h
@@ -48,7 +48,7 @@ Optparse memory_counters_opt[2] = {
         .shortname = 'L',
         .argtype = OPTPARSE_NONE,
         .usage_arg = NULL,
-        .usage_msg = "list the available performance counters and quit",
+        .usage_msg = "list the available memory counters and quit",
         .fn = show_all_memory_counters,
     },
 };
-- 
GitLab


From aa98e7f8ce29bd899fd484883bb3865d063d4d97 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Tue, 28 Mar 2023 10:52:08 +0200
Subject: [PATCH 224/229] format

---
 src/memory_counters.c | 180 ++++++++++++++++++++++--------------------
 src/memory_counters.h |   6 +-
 2 files changed, 98 insertions(+), 88 deletions(-)

diff --git a/src/memory_counters.c b/src/memory_counters.c
index 8e8e916..185f454 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -10,111 +10,121 @@
 static const char *path = "/proc/meminfo";
 
 typedef struct {
-  KeyFinder *keys;
-  unsigned int count;
-  FILE *file;
+    KeyFinder *keys;
+    unsigned int count;
+    FILE *file;
 } MemoryCounters;
 
-GenericPointer long_allocator(char *s) {
-  long value = atol(s);
-  return (GenericPointer)value;
+GenericPointer long_allocator(char *s)
+{
+    long value = atol(s);
+    return (GenericPointer)value;
 }
 
-KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) {
-  KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
-  for (unsigned int i = 0; i < count; i++) {
-    unsigned int idx = indexes[i];
-    KeyFinder key = {.key = memory_counters[idx],
-                     .delimiter = ":",
-                     .copy = long_allocator,
-                     .set = setter_functions[i]};
-    memcpy(&keys[i], &key, sizeof(KeyFinder));
-  }
-  return keys;
+KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes)
+{
+    KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
+    for (unsigned int i = 0; i < count; i++) {
+        unsigned int idx = indexes[i];
+        KeyFinder key = {.key = memory_counters[idx],
+                         .delimiter = ":",
+                         .copy = long_allocator,
+                         .set = setter_functions[i]
+                        };
+        memcpy(&keys[i], &key, sizeof(KeyFinder));
+    }
+    return keys;
 }
 
 void memory_list(char *memory_string, unsigned int *count,
-                 unsigned int *indexes) {
-  char *token;
-  *count = 0;
-
-  while ((token = strtok(memory_string, ",")) != NULL) {
-    memory_string = NULL;
-
-    unsigned int i;
-    for (i = 0; i < NB_COUNTERS; i++) {
-      if (strcmp(memory_counters[i], token) == 0) {
-        (*count)++;
-        indexes[*count - 1] = i;
-        break;
-      }
-    }
-
-    if (i == NB_COUNTERS) {
-      fprintf(stderr, "Unknown memory counter: %s\n", token);
-      exit(EXIT_FAILURE);
+                 unsigned int *indexes)
+{
+    char *token;
+    *count = 0;
+
+    while ((token = strtok(memory_string, ",")) != NULL) {
+        memory_string = NULL;
+
+        unsigned int i;
+        for (i = 0; i < NB_COUNTERS; i++) {
+            if (strcmp(memory_counters[i], token) == 0) {
+                (*count)++;
+                indexes[*count - 1] = i;
+                break;
+            }
+        }
+
+        if (i == NB_COUNTERS) {
+            fprintf(stderr, "Unknown memory counter: %s\n", token);
+            exit(EXIT_FAILURE);
+        }
+
+        if ((*count) > NB_COUNTERS) {
+            fprintf(stderr, "Too much counters, there are probably duplicates\n");
+            exit(EXIT_FAILURE);
+        }
     }
-
-    if ((*count) > NB_COUNTERS) {
-      fprintf(stderr, "Too much counters, there are probably duplicates\n");
-      exit(EXIT_FAILURE);
-    }
-  }
 }
 
-unsigned int init_memory_counters(char *args, void **ptr) {
-  unsigned int indexes[NB_COUNTERS];
-  unsigned int count = 0;
-  memory_list(args, &count, indexes);
+unsigned int init_memory_counters(char *args, void **ptr)
+{
+    unsigned int indexes[NB_COUNTERS];
+    unsigned int count = 0;
+    memory_list(args, &count, indexes);
 
-  KeyFinder *keys = build_keyfinder(count, indexes);
-  FILE *file = fopen(path, "r");
+    KeyFinder *keys = build_keyfinder(count, indexes);
+    FILE *file = fopen(path, "r");
 
-  MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
-  counters->keys = keys;
-  counters->count = count;
-  counters->file = file;
+    MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
+    counters->keys = keys;
+    counters->count = count;
+    counters->file = file;
 
-  *ptr = (void *)counters;
-  return count;
+    *ptr = (void *)counters;
+    return count;
 }
 
-unsigned int get_memory_counters(uint64_t *results, void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  fseek(counters->file, 0, SEEK_SET);
-  Parser parser = {.storage = (GenericPointer)results,
-                   .capacity = 1,
-                   .nb_stored = 0,
-                   .storage_struct_size = sizeof(uint64_t) * counters->count,
-                   .keys = counters->keys,
-                   .nb_keys = counters->count,
-                   .file = counters->file};
-
-  parse(&parser);
-  return counters->count;
+unsigned int get_memory_counters(uint64_t *results, void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    fseek(counters->file, 0, SEEK_SET);
+    Parser parser = {.storage = (GenericPointer)results,
+                     .capacity = 1,
+                     .nb_stored = 0,
+                     .storage_struct_size = sizeof(uint64_t) * counters->count,
+                     .keys = counters->keys,
+                     .nb_keys = counters->count,
+                     .file = counters->file
+                    };
+
+    parse(&parser);
+    return counters->count;
 }
 
-void label_memory_counters(char **labels, void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  for (unsigned int i = 0; i < counters->count; i++) {
-    labels[i] = counters->keys[i].key;
-  }
+void label_memory_counters(char **labels, void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    for (unsigned int i = 0; i < counters->count; i++) {
+        labels[i] = counters->keys[i].key;
+    }
 }
 
-void clean_memory_counters(void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  fclose(counters->file);
-  free(counters->keys);
-  free(ptr);
+void clean_memory_counters(void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    fclose(counters->file);
+    free(counters->keys);
+    free(ptr);
 }
 
-void *show_all_memory_counters(void *none1, size_t none2) {
-  for (unsigned int i = 0; i < NB_COUNTERS; i++) {
-    printf("%s\n", memory_counters[i]);
-  }
+void *show_all_memory_counters(void *none1, size_t none2)
+{
+    for (unsigned int i = 0; i < NB_COUNTERS; i++) {
+        printf("%s\n", memory_counters[i]);
+    }
 
-  UNUSED(none1);
-  UNUSED(none2);
-  exit(EXIT_SUCCESS);
-  return NULL; /* not reached */
+    UNUSED(none1);
+    UNUSED(none2);
+    exit(EXIT_SUCCESS);
+    return NULL; /* not reached */
 }
diff --git a/src/memory_counters.h b/src/memory_counters.h
index 50e0be3..eaf9f36 100644
--- a/src/memory_counters.h
+++ b/src/memory_counters.h
@@ -39,9 +39,9 @@ Optparse memory_counters_opt[2] = {
         .argtype = OPTPARSE_REQUIRED,
         .usage_arg = "<memory_list>",
         .usage_msg =
-            "memory counters\n"
-            "\tmemory_list is a coma separated list of memory counters.\n"
-            "\tEx: Zswap,Zswapped",
+        "memory counters\n"
+        "\tmemory_list is a coma separated list of memory counters.\n"
+        "\tEx: Zswap,Zswapped",
     },
     {
         .longname = "memory-list",
-- 
GitLab


From b6fb43a0eb175610ea618bcee8ab765e511c3c05 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Thu, 30 Mar 2023 15:58:48 +0200
Subject: [PATCH 225/229] modify memory_option.sh

---
 src/memory_option.sh | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)

diff --git a/src/memory_option.sh b/src/memory_option.sh
index 54a2c6e..30a3831 100755
--- a/src/memory_option.sh
+++ b/src/memory_option.sh
@@ -3,9 +3,9 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 # Copyright (C) 2018-2023 Georges Da Costa <georges.da-costa@irit.fr>
 
-MEMINFO_PATH="/proc/meminfo"
+meminfo_path=/proc/meminfo
 
-FUNCTION_TEMPLATE="void set_result_offset%s(GenericPointer ptr, GenericPointer data)
+function_template="void set_result_offset%s(GenericPointer ptr, GenericPointer data)
 {
     uint64_t* result = (uint64_t *) ptr;
     result[%s] = (uint64_t) data;
@@ -14,16 +14,15 @@ FUNCTION_TEMPLATE="void set_result_offset%s(GenericPointer ptr, GenericPointer d
 nb_counters=0
 
 echo '#include <inttypes.h>'
-echo "#include <info_reader.h>"
+echo '#include <info_reader.h>'
 echo
 
 echo 'static char *memory_counters[] = {'
 while read line; do
-  nb_counters=$(expr $nb_counters + 1)
-  word=$(echo $line | awk '{print $1}')
-  echo "    \"${word::-1}\","
-done <$MEMINFO_PATH
-echo "};"
+  : $((nb_counters += 1))
+  echo "$line" | awk -F ':' '{printf("    \"%s\",\n", $1)}'
+done < "$meminfo_path"
+echo '};'
 echo
 
 echo "#define NB_COUNTERS $nb_counters"
@@ -31,16 +30,16 @@ echo
 
 count=0
 while [ $count -lt $nb_counters ]; do
-  printf "$FUNCTION_TEMPLATE" $count $count
-  count=$(expr $count + 1)
+  printf "$function_template" $count $count
+  : $((count += 1))
 done
 
-echo "static void (*setter_functions[])(GenericPointer, GenericPointer) = {"
+echo 'static void (*setter_functions[])(GenericPointer, GenericPointer) = {'
 count=0
 while [ $count -lt $nb_counters ]; do
   echo "    set_result_offset$count,"
-  count=$(expr $count + 1)
+  : $((count += 1))
 done
-echo "};"
+echo '};'
 echo
 
-- 
GitLab


From 2ad61f79f7eb594e04afb260db8839cb0be5ec53 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Flor=C3=A9al=20Risso?= <floreal.risso@univ-tlse3.fr>
Date: Wed, 19 Apr 2023 08:48:51 +0200
Subject: [PATCH 226/229] fix: make dependency

---
 makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/makefile b/makefile
index a57eca2..3997f40 100644
--- a/makefile
+++ b/makefile
@@ -42,7 +42,7 @@ $(OBJ): $(OBJ_DIR)
 $(OBJ_DIR)/counters.o: $(SRC_DIR)/counters_option.h
 $(OBJ_DIR)/memory_counters.o: $(SRC_DIR)/memory_option.h
 
-$(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c $(SRC_DIR)/counters_option.h $(SRC_DIR)/memory_counters.h
+$(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c
 	$(CC) $(CFLAGS) -c $< -o $@
 
 $(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
-- 
GitLab


From a7c3287ae184633e49b732938eaf4d6ecfd0dd56 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Thu, 20 Apr 2023 10:05:05 +0200
Subject: [PATCH 227/229] fix make

---
 README.md             |  14 ++-
 configure.sh          |   4 +-
 lib/info_reader.c     | 146 ++++++++++++++++++++++++++
 lib/info_reader.h     | 236 ++++++++++--------------------------------
 makefile              |  15 ++-
 src/memory_counters.c | 180 +++++++++++++++-----------------
 6 files changed, 313 insertions(+), 282 deletions(-)
 create mode 100644 lib/info_reader.c

diff --git a/README.md b/README.md
index 9fee622..4c0b186 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ The following is an exhaustive list of all the sensors (it is very likely
 that one will not have all the sensors activated in his build):
 ```bash
 SENSORS:
--a|--amd-rapl
+-r|--amd-rapl
 	AMD RAPL
 -p|--perf-list <perf_list>
 	performance counters
@@ -41,8 +41,20 @@ SENSORS:
 	system load
 -d|--net-dev <net_dev>
 	network monitoring (if network_device is X, tries to detect it automatically)
+-n|--nvidia-gpu
+	provides basic gpu information [clocks, memory, utilization, power, temperature].
 -r|--intel-rapl
 	INTEL RAPL
+-c|--cpu-temp
+	processor temperature
+-m|--memory
+	Retrieves information about the memory via the syscall 'sysinfo(2)'.
+-M|--memory-counters <memory_list>
+	memory counters
+	memory_list is a coma separated list of memory counters.
+	Ex: Zswap,Zswapped
+-L|--memory-list
+	list the available memory counters and quit
 ```
 
 ## Installation Instructions
diff --git a/configure.sh b/configure.sh
index 56abf93..1246b0c 100755
--- a/configure.sh
+++ b/configure.sh
@@ -29,7 +29,7 @@ debug=0
 target_hdr=src/sensors.h
 target_mk=sensors.mk
 
-nonsensor='counters_option|sensors|util'
+nonsensor='counters_option|memory_option|sensors|util'
 
 hdr_blacklist=$nonsensor
 hdr_whitelist=''
@@ -157,6 +157,8 @@ detect_caps() {
 case $1 in
 --all | -a)
 	all=1
+	NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml"
+	NVML_IFLAGS="-I/usr/local/cuda/include"
 	;;
 esac
 
diff --git a/lib/info_reader.c b/lib/info_reader.c
new file mode 100644
index 0000000..d23f554
--- /dev/null
+++ b/lib/info_reader.c
@@ -0,0 +1,146 @@
+#include <info_reader.h>
+
+ void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value)
+{
+    GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored);
+    GenericPointer value = key_finder->copy(raw_value);
+    key_finder->set(address, value);
+}
+
+ unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value)
+{
+    for (unsigned int i = 0; i < parser->nb_keys; i++) {
+        KeyFinder *finder = &parser->keys[i];
+
+        if (start_with(finder->key, line)) {
+            char *value = NULL;
+            char *key = NULL;
+
+            split_on_delimiter(line, finder->delimiter, &key, &value);
+            if ( key == NULL || value == NULL) {
+                return 0;
+            }
+            *key_finder = finder;
+            *raw_value = value;
+            return 1;
+        }
+    }
+    return 0;
+}
+
+ unsigned int move_to_next(Parser *parser)
+{
+    parser->nb_stored += 1;
+    if (parser->nb_stored >= parser->capacity) {
+        return 0;
+    }
+    return 1;
+}
+
+
+#define PAGE_SIZE 4096
+ssize_t buffer_getline(char **lineptr, FILE *stream) {
+    ssize_t num_chars_read = 0;
+    static char buffer[PAGE_SIZE] = {0};
+
+    if (!lineptr || !stream) {
+        return -1;
+    }
+
+    while (1) {
+        int ch = fgetc(stream);
+        if (ch == EOF) {
+            if (num_chars_read == 0) {
+                return -1;
+            } else {
+                break;
+            }
+        }
+
+        if (num_chars_read == PAGE_SIZE - 1) {
+            return -1;
+        }
+
+        buffer[num_chars_read++] = ch;
+        if (ch == '\n') {
+            break;
+        }
+    }
+
+    buffer[num_chars_read] = '\0';
+    *lineptr = buffer;
+
+    return num_chars_read;
+}
+
+
+ unsigned int parse(Parser *parser)
+{
+    char *line = NULL;
+    ssize_t read;
+    unsigned int key_assigned = 0;
+
+    while ((read = buffer_getline(&line, parser->file)) != -1) {
+        if (key_assigned == parser->nb_keys && read > 1) {
+            continue;
+        } else if (read == 1) {
+            if (!move_to_next(parser)) {
+                return 0;
+            }
+            key_assigned = 0;
+        } else {
+            KeyFinder *key_finder = NULL;
+            char *raw_value = NULL;
+            replace_first(line, '\n', '\0');
+            if (match(parser, line, &key_finder, &raw_value)) {
+                set_value(parser, key_finder, raw_value);
+                ++key_assigned;
+            }
+        }
+    }
+    if (key_assigned > 0) {
+        parser->nb_stored++;
+    }
+    return 1;
+}
+
+
+
+ void replace_first(char *string, char from, char to)
+{
+    for (int i = 0; string[i] != '\0'; i++) {
+        if (string[i] == from) {
+            string[i] = to;
+            break;
+        }
+    }
+}
+
+ void split_on_delimiter(char *string, const char *delimiter, char **key, char **value)
+{
+    *key = NULL;
+    *value = NULL;
+    size_t delimiter_len = strlen(delimiter);
+    char *start_delimiter = strstr(string, delimiter);
+    if (start_delimiter != NULL) {
+        *start_delimiter = '\0';
+        *key = string;
+        *value = start_delimiter + delimiter_len;
+    }
+}
+
+bool start_with(const char *prefix, const char *string)
+{
+    if (prefix == NULL || string == NULL) {
+        return false;
+    }
+
+    size_t prefix_len = strlen(prefix);
+    size_t string_len = strlen(string);
+
+    if (string_len < prefix_len) {
+        return false;
+    } else {
+        return  memcmp(prefix, string, prefix_len) == 0;
+    }
+}
diff --git a/lib/info_reader.h b/lib/info_reader.h
index 15a077c..403bb19 100644
--- a/lib/info_reader.h
+++ b/lib/info_reader.h
@@ -21,36 +21,42 @@
 #ifndef _INFO_READER_H
 #define _INFO_READER_H
 
-#include <string.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 
 /**
  * @struct Parser
  * @brief The parser struct
- * The struct containing all the necessary informations and functions to parse a file
+ * The struct containing all the necessary informations and functions to parse a
+ * file
  *
- * @var storage : GenericPointer : pointer to the storage where the parsed data will be stored
+ * @var storage : GenericPointer : pointer to the storage where the parsed data
+ * will be stored
  * @var nb_stored : unsigned int : the number of struct stored
- * @var capacity : unsigned int : the maximum number of struct that can be stored
- * @var storage_struct_size : size_t : the size of the struct stored in the storage
- * @var keys : KeyFinder* : pointer to an array of KeyFinder containing the possible keys
+ * @var capacity : unsigned int : the maximum number of struct that can be
+ * stored
+ * @var storage_struct_size : size_t : the size of the struct stored in the
+ * storage
+ * @var keys : KeyFinder* : pointer to an array of KeyFinder containing the
+ * possible keys
  * @var nb_keys : unsigned int : number of key finders
  * @var file : FILE* : pointer to the file that will be parsed
-*/
+ */
 typedef struct Parser Parser;
 
 /**
  * @struct KeyFinder
  * @brief The key finder struct
- * The struct containing all the necessary informations and functions to find a key in a line of text
+ * The struct containing all the necessary informations and functions to find a
+ * key in a line of text
  *
  * @var key : char* : the key to be found
  * @var delimiter : char* : the delimiter between the key and the value
  * @var copy : CopyAllocator*: the function to use to make a copy of the value
  * @var set : Setter*: the function to use to store the value in the storage
-*/
+ */
 typedef struct KeyFinder KeyFinder;
 
 /**
@@ -68,20 +74,24 @@ typedef struct KeyFinder KeyFinder;
  * @param[out] value A pointer to a char pointer where the value will be stored.
  * @return None.
  */
-static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value);
+void split_on_delimiter(char *string, const char *delimiter, char **key,
+                        char **value);
 
 /**
- * @brief Replace the first occurrence of a character in a string with another character.
+ * @brief Replace the first occurrence of a character in a string with another
+ * character.
  *
- * The function takes a string and two characters as input, and replaces the first
- * occurrence of the first character in the string with the second character.
+ * The function takes a string and two characters as input, and replaces the
+ * first occurrence of the first character in the string with the second
+ * character.
  *
- * @param[in,out] string The input string where the replacement should take place.
+ * @param[in,out] string The input string where the replacement should take
+ * place.
  * @param[in] from The character to be replaced.
  * @param[in] to The character to replace with.
  * @return None.
  */
-static void replace_first(char *string, char from, char to);
+void replace_first(char *string, char from, char to);
 
 /**
  * @brief Check if a string starts with a prefix.
@@ -89,21 +99,25 @@ static void replace_first(char *string, char from, char to);
  * @param[in] prefix The prefix to check.
  * @param[in] string The string to check.
  * @return true The string starts with the prefix.
- * @return false The string does not start with the prefix or one of the input pointers is NULL.
+ * @return false The string does not start with the prefix or one of the input
+ * pointers is NULL.
  */
-static bool start_with(const char *prefix, const char *string);
+bool start_with(const char *prefix, const char *string);
 
 /**
  * @brief Matches a line of text to a key in the parser's list of keys.
  *
  * @param[in] parser Pointer to the Parser struct.
  * @param[in] line Line of text to match.
- * @param[out] key_finder Pointer to a KeyFinder pointer where the matched key will be stored.
- * @param[out] raw_value Pointer to a char pointer where the value associated with the matched key will be stored.
+ * @param[out] key_finder Pointer to a KeyFinder pointer where the matched key
+ * will be stored.
+ * @param[out] raw_value Pointer to a char pointer where the value associated
+ * with the matched key will be stored.
  *
  * @return Returns 1 if a key is matched, 0 otherwise.
  */
-static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value);
+unsigned int match(Parser *parser, char *line, KeyFinder **key_finder,
+                   char **raw_value);
 
 /**
 * @brief Reads a line of text from a file stream and stores it in a static
@@ -111,7 +125,8 @@ static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, ch
 
 * This function reads a line of text from the input stream pointed to by
 * 'stream'. The line of text is stored in a static buffer with a maximum size of
-* PAGE_SIZE. The function updates the pointer pointed to by 'lineptr' to point to
+* PAGE_SIZE. The function updates the pointer pointed to by 'lineptr' to point
+to
 * the buffer containing the line of text. If the line of text is longer than the
 * buffer, the function returns -1. If an error occurs,
 
@@ -123,174 +138,35 @@ static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, ch
 */
 ssize_t buffer_getline(char **lineptr, FILE *stream);
 
+/**
+ * @brief Parse with the configured parser.
+ *
+ * @param parser the parser.
+ */
+unsigned int parse(Parser *parser);
+
 typedef size_t GenericPointer;
-typedef GenericPointer (CopyAllocator) (char *string);
-typedef void (Setter) (GenericPointer storage, GenericPointer value);
+typedef GenericPointer(CopyAllocator)(char *string);
+typedef void(Setter)(GenericPointer storage, GenericPointer value);
 
 struct KeyFinder {
-    char *key;
-    char *delimiter;
+  char *key;
+  char *delimiter;
 
-    CopyAllocator *copy;
-    Setter *set;
+  CopyAllocator *copy;
+  Setter *set;
 };
 
 struct Parser {
-    GenericPointer storage;
-    unsigned int nb_stored;
-    unsigned int capacity;
-    size_t storage_struct_size;
+  GenericPointer storage;
+  unsigned int nb_stored;
+  unsigned int capacity;
+  size_t storage_struct_size;
 
-    KeyFinder *keys;
-    unsigned int nb_keys;
+  KeyFinder *keys;
+  unsigned int nb_keys;
 
-    FILE *file;
+  FILE *file;
 };
 
-static void set_value(Parser *parser, KeyFinder *key_finder, char *raw_value)
-{
-    GenericPointer address = parser->storage + (parser->storage_struct_size * parser->nb_stored);
-    GenericPointer value = key_finder->copy(raw_value);
-    key_finder->set(address, value);
-}
-
-static unsigned int match(Parser *parser, char *line, KeyFinder **key_finder, char **raw_value)
-{
-    for (unsigned int i = 0; i < parser->nb_keys; i++) {
-        KeyFinder *finder = &parser->keys[i];
-
-        if (start_with(finder->key, line)) {
-            char *value = NULL;
-            char *key = NULL;
-
-            split_on_delimiter(line, finder->delimiter, &key, &value);
-            if ( key == NULL || value == NULL) {
-                return 0;
-            }
-            *key_finder = finder;
-            *raw_value = value;
-            return 1;
-        }
-    }
-    return 0;
-}
-
-static unsigned int move_to_next(Parser *parser)
-{
-    parser->nb_stored += 1;
-    if (parser->nb_stored >= parser->capacity) {
-        return 0;
-    }
-    return 1;
-}
-
-
-#define PAGE_SIZE 4096
-ssize_t buffer_getline(char **lineptr, FILE *stream) {
-    ssize_t num_chars_read = 0;
-    static char buffer[PAGE_SIZE] = {0};
-
-    if (!lineptr || !stream) {
-        return -1;
-    }
-
-    while (1) {
-        int ch = fgetc(stream);
-        if (ch == EOF) {
-            if (num_chars_read == 0) {
-                return -1;
-            } else {
-                break;
-            }
-        }
-
-        if (num_chars_read == PAGE_SIZE - 1) {
-            return -1;
-        }
-
-        buffer[num_chars_read++] = ch;
-        if (ch == '\n') {
-            break;
-        }
-    }
-
-    buffer[num_chars_read] = '\0';
-    *lineptr = buffer;
-
-    return num_chars_read;
-}
-
-
-static unsigned int parse(Parser *parser)
-{
-    char *line = NULL;
-    ssize_t read;
-    unsigned int key_assigned = 0;
-
-    while ((read = buffer_getline(&line, parser->file)) != -1) {
-        if (key_assigned == parser->nb_keys && read > 1) {
-            continue;
-        } else if (read == 1) {
-            if (!move_to_next(parser)) {
-                return 0;
-            }
-            key_assigned = 0;
-        } else {
-            KeyFinder *key_finder = NULL;
-            char *raw_value = NULL;
-            replace_first(line, '\n', '\0');
-            if (match(parser, line, &key_finder, &raw_value)) {
-                set_value(parser, key_finder, raw_value);
-                ++key_assigned;
-            }
-        }
-    }
-    if (key_assigned > 0) {
-        parser->nb_stored++;
-    }
-    return 1;
-}
-
-
-
-static void replace_first(char *string, char from, char to)
-{
-    for (int i = 0; string[i] != '\0'; i++) {
-        if (string[i] == from) {
-            string[i] = to;
-            break;
-        }
-    }
-}
-
-static void split_on_delimiter(char *string, const char *delimiter, char **key, char **value)
-{
-    *key = NULL;
-    *value = NULL;
-    size_t delimiter_len = strlen(delimiter);
-    char *start_delimiter = strstr(string, delimiter);
-    if (start_delimiter != NULL) {
-        *start_delimiter = '\0';
-        *key = string;
-        *value = start_delimiter + delimiter_len;
-    }
-}
-
-static bool start_with(const char *prefix, const char *string)
-{
-    if (prefix == NULL || string == NULL) {
-        return false;
-    }
-
-    size_t prefix_len = strlen(prefix);
-    size_t string_len = strlen(string);
-
-    if (string_len < prefix_len) {
-        return false;
-    } else {
-        return  memcmp(prefix, string, prefix_len) == 0;
-    }
-}
-
 #endif
-
diff --git a/makefile b/makefile
index 3997f40..4dcbce4 100644
--- a/makefile
+++ b/makefile
@@ -3,6 +3,7 @@
 SRC_DIR = src
 DOC_DIR = doc
 OBJ_DIR = obj
+LIB_DIR = lib
 BIN_DIR = bin
 TESTS_DIR = tests
 
@@ -25,8 +26,9 @@ NVML_IFLAGS =
 include ./sensors.mk
 
 OBJ =  \
-	$(CAPTOR_OBJ) \
-	$(OBJ_DIR)/util.o
+	$(OBJ_DIR)/util.o \
+	$(OBJ_DIR)/info_reader.o \
+	$(CAPTOR_OBJ)
 
 options:
 	@echo BIN: $(BIN)
@@ -48,6 +50,9 @@ $(OBJ_DIR)/$(BIN).o: $(SRC_DIR)/$(BIN).c
 $(OBJ_DIR)/util.o: $(SRC_DIR)/util.c $(SRC_DIR)/util.h
 	$(CC) $(CFLAGS) -c $< -o $@
 
+$(OBJ_DIR)/info_reader.o: $(LIB_DIR)/info_reader.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
 $(SRC_DIR)/counters_option.h: $(SRC_DIR)/counters_option.sh
 	sh ./$(SRC_DIR)/counters_option.sh > $(SRC_DIR)/counters_option.h
 
@@ -63,8 +68,8 @@ $(BIN_DIR):
 debug: CFLAGS = $(CPPFLAGS) -DDEBUG -g -Og
 debug: $(BIN)
 
-tests:
-	$(CC) $(CPPFLAGS) $(TESTS_DIR)/main.c $(SRC_DIR)/util.c -o $(TESTS_DIR)/run
+tests: $(OBJ_DIR)/util.o $(OBJ_DIR)/info_reader.o
+	$(CC) $(CPPFLAGS) $(OBJ_DIR)/util.o $(OBJ_DIR)/info_reader.o $(TESTS_DIR)/main.c  -o $(TESTS_DIR)/run
 	$(TESTS_DIR)/run
 
 format:
@@ -80,7 +85,7 @@ clean:
 		$(DOC_DIR)/test_main_ex \
 		$(DOC_DIR)/info_reader_ex
 
-readme: $(BIN)
+readme:
 	sh ./tools/update-readme-usage.sh
 
 man: $(BIN)
diff --git a/src/memory_counters.c b/src/memory_counters.c
index 185f454..8e8e916 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -10,121 +10,111 @@
 static const char *path = "/proc/meminfo";
 
 typedef struct {
-    KeyFinder *keys;
-    unsigned int count;
-    FILE *file;
+  KeyFinder *keys;
+  unsigned int count;
+  FILE *file;
 } MemoryCounters;
 
-GenericPointer long_allocator(char *s)
-{
-    long value = atol(s);
-    return (GenericPointer)value;
+GenericPointer long_allocator(char *s) {
+  long value = atol(s);
+  return (GenericPointer)value;
 }
 
-KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes)
-{
-    KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
-    for (unsigned int i = 0; i < count; i++) {
-        unsigned int idx = indexes[i];
-        KeyFinder key = {.key = memory_counters[idx],
-                         .delimiter = ":",
-                         .copy = long_allocator,
-                         .set = setter_functions[i]
-                        };
-        memcpy(&keys[i], &key, sizeof(KeyFinder));
-    }
-    return keys;
+KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) {
+  KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
+  for (unsigned int i = 0; i < count; i++) {
+    unsigned int idx = indexes[i];
+    KeyFinder key = {.key = memory_counters[idx],
+                     .delimiter = ":",
+                     .copy = long_allocator,
+                     .set = setter_functions[i]};
+    memcpy(&keys[i], &key, sizeof(KeyFinder));
+  }
+  return keys;
 }
 
 void memory_list(char *memory_string, unsigned int *count,
-                 unsigned int *indexes)
-{
-    char *token;
-    *count = 0;
-
-    while ((token = strtok(memory_string, ",")) != NULL) {
-        memory_string = NULL;
-
-        unsigned int i;
-        for (i = 0; i < NB_COUNTERS; i++) {
-            if (strcmp(memory_counters[i], token) == 0) {
-                (*count)++;
-                indexes[*count - 1] = i;
-                break;
-            }
-        }
-
-        if (i == NB_COUNTERS) {
-            fprintf(stderr, "Unknown memory counter: %s\n", token);
-            exit(EXIT_FAILURE);
-        }
-
-        if ((*count) > NB_COUNTERS) {
-            fprintf(stderr, "Too much counters, there are probably duplicates\n");
-            exit(EXIT_FAILURE);
-        }
+                 unsigned int *indexes) {
+  char *token;
+  *count = 0;
+
+  while ((token = strtok(memory_string, ",")) != NULL) {
+    memory_string = NULL;
+
+    unsigned int i;
+    for (i = 0; i < NB_COUNTERS; i++) {
+      if (strcmp(memory_counters[i], token) == 0) {
+        (*count)++;
+        indexes[*count - 1] = i;
+        break;
+      }
+    }
+
+    if (i == NB_COUNTERS) {
+      fprintf(stderr, "Unknown memory counter: %s\n", token);
+      exit(EXIT_FAILURE);
     }
+
+    if ((*count) > NB_COUNTERS) {
+      fprintf(stderr, "Too much counters, there are probably duplicates\n");
+      exit(EXIT_FAILURE);
+    }
+  }
 }
 
-unsigned int init_memory_counters(char *args, void **ptr)
-{
-    unsigned int indexes[NB_COUNTERS];
-    unsigned int count = 0;
-    memory_list(args, &count, indexes);
+unsigned int init_memory_counters(char *args, void **ptr) {
+  unsigned int indexes[NB_COUNTERS];
+  unsigned int count = 0;
+  memory_list(args, &count, indexes);
 
-    KeyFinder *keys = build_keyfinder(count, indexes);
-    FILE *file = fopen(path, "r");
+  KeyFinder *keys = build_keyfinder(count, indexes);
+  FILE *file = fopen(path, "r");
 
-    MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
-    counters->keys = keys;
-    counters->count = count;
-    counters->file = file;
+  MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
+  counters->keys = keys;
+  counters->count = count;
+  counters->file = file;
 
-    *ptr = (void *)counters;
-    return count;
+  *ptr = (void *)counters;
+  return count;
 }
 
-unsigned int get_memory_counters(uint64_t *results, void *ptr)
-{
-    MemoryCounters *counters = (MemoryCounters *)ptr;
-    fseek(counters->file, 0, SEEK_SET);
-    Parser parser = {.storage = (GenericPointer)results,
-                     .capacity = 1,
-                     .nb_stored = 0,
-                     .storage_struct_size = sizeof(uint64_t) * counters->count,
-                     .keys = counters->keys,
-                     .nb_keys = counters->count,
-                     .file = counters->file
-                    };
-
-    parse(&parser);
-    return counters->count;
+unsigned int get_memory_counters(uint64_t *results, void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  fseek(counters->file, 0, SEEK_SET);
+  Parser parser = {.storage = (GenericPointer)results,
+                   .capacity = 1,
+                   .nb_stored = 0,
+                   .storage_struct_size = sizeof(uint64_t) * counters->count,
+                   .keys = counters->keys,
+                   .nb_keys = counters->count,
+                   .file = counters->file};
+
+  parse(&parser);
+  return counters->count;
 }
 
-void label_memory_counters(char **labels, void *ptr)
-{
-    MemoryCounters *counters = (MemoryCounters *)ptr;
-    for (unsigned int i = 0; i < counters->count; i++) {
-        labels[i] = counters->keys[i].key;
-    }
+void label_memory_counters(char **labels, void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  for (unsigned int i = 0; i < counters->count; i++) {
+    labels[i] = counters->keys[i].key;
+  }
 }
 
-void clean_memory_counters(void *ptr)
-{
-    MemoryCounters *counters = (MemoryCounters *)ptr;
-    fclose(counters->file);
-    free(counters->keys);
-    free(ptr);
+void clean_memory_counters(void *ptr) {
+  MemoryCounters *counters = (MemoryCounters *)ptr;
+  fclose(counters->file);
+  free(counters->keys);
+  free(ptr);
 }
 
-void *show_all_memory_counters(void *none1, size_t none2)
-{
-    for (unsigned int i = 0; i < NB_COUNTERS; i++) {
-        printf("%s\n", memory_counters[i]);
-    }
+void *show_all_memory_counters(void *none1, size_t none2) {
+  for (unsigned int i = 0; i < NB_COUNTERS; i++) {
+    printf("%s\n", memory_counters[i]);
+  }
 
-    UNUSED(none1);
-    UNUSED(none2);
-    exit(EXIT_SUCCESS);
-    return NULL; /* not reached */
+  UNUSED(none1);
+  UNUSED(none2);
+  exit(EXIT_SUCCESS);
+  return NULL; /* not reached */
 }
-- 
GitLab


From 079b25060bce14922749bc006e2dd8b08486baa1 Mon Sep 17 00:00:00 2001
From: FlorealRISSO <floreal.risso@univ-tlse3.fr>
Date: Thu, 20 Apr 2023 10:15:52 +0200
Subject: [PATCH 228/229] format

---
 doc/info_reader_ex.c  |  85 +++++++++++++-------
 src/memory_counters.c | 180 ++++++++++++++++++++++--------------------
 2 files changed, 152 insertions(+), 113 deletions(-)

diff --git a/doc/info_reader_ex.c b/doc/info_reader_ex.c
index f1e6d96..d99e916 100644
--- a/doc/info_reader_ex.c
+++ b/doc/info_reader_ex.c
@@ -18,8 +18,10 @@
 
 *******************************************************/
 
+// ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex
+// info_reader_ex.c ./../src/util.c && ./info_reader_ex
 
-// ~/mojitos/doc/$ gcc -Wall -Wextra -Wpedantic -O3 -o info_reader_ex info_reader_ex.c ./../src/util.c && ./info_reader_ex
+#include "./../lib/info_reader.c"
 #include "./../lib/info_reader.h"
 
 #define MAX_PROCS 64
@@ -40,7 +42,7 @@ typedef struct {
 GenericPointer int_allocator(char *s)
 {
     unsigned int value = atoi(s);
-    return (GenericPointer) value;
+    return (GenericPointer)value;
 }
 
 // -- Define the behaviour if the attempted value is a string
@@ -48,49 +50,49 @@ GenericPointer string_allocator(char *s)
 {
     char *value = malloc(strlen(s) + 1);
     strcpy(value, s);
-    return (GenericPointer) value;
+    return (GenericPointer)value;
 }
 
 // -- Define the processor setter
 void set_processor(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
+    Cpu *cpu = (Cpu *)storage;
     cpu->processor = data;
 }
 
 // -- Define the vendor_id setter
 void set_vendor_id(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
-    cpu->vendor_id = (char *) data;
+    Cpu *cpu = (Cpu *)storage;
+    cpu->vendor_id = (char *)data;
 }
 
 // -- Define the family setter
 void set_family(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
+    Cpu *cpu = (Cpu *)storage;
     cpu->family = data;
 }
 
 // -- Define the core_id setter
 void set_core_id(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
+    Cpu *cpu = (Cpu *)storage;
     cpu->core_id = data;
 }
 
 // -- Define the physical_id setter
 void set_physical_id(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
+    Cpu *cpu = (Cpu *)storage;
     cpu->physical_id = data;
 }
 
 // -- Define the model_name setter
 void set_model_name(GenericPointer storage, GenericPointer data)
 {
-    Cpu *cpu = (Cpu *) storage;
-    cpu->model_name = (char *) data;
+    Cpu *cpu = (Cpu *)storage;
+    cpu->model_name = (char *)data;
 }
 
 int main()
@@ -98,26 +100,54 @@ int main()
     Cpu cpus[MAX_PROCS];
 
     // -- Define the setter, the allocator for each key / separator.
-    KeyFinder keys[] = {
-        {.key = "processor", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_processor},
-        {.key = "vendor_id", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_vendor_id},
-        {.key = "cpu family", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_family},
-        {.key = "core id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_core_id},
-        {.key = "physical id", .delimiter = ": ", .copy = (CopyAllocator *) int_allocator, .set = (Setter *)set_physical_id},
-        {.key = "model name", .delimiter = ": ", .copy = (CopyAllocator *) string_allocator, .set = (Setter *)set_model_name}
+    KeyFinder keys[] = {{
+            .key = "processor",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)int_allocator,
+            .set = (Setter *)set_processor
+        },
+        {
+            .key = "vendor_id",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)string_allocator,
+            .set = (Setter *)set_vendor_id
+        },
+        {
+            .key = "cpu family",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)int_allocator,
+            .set = (Setter *)set_family
+        },
+        {
+            .key = "core id",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)int_allocator,
+            .set = (Setter *)set_core_id
+        },
+        {
+            .key = "physical id",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)int_allocator,
+            .set = (Setter *)set_physical_id
+        },
+        {
+            .key = "model name",
+            .delimiter = ": ",
+            .copy = (CopyAllocator *)string_allocator,
+            .set = (Setter *)set_model_name
+        }
     };
 
-    size_t nb_keys = sizeof(keys)/sizeof(KeyFinder);
+    size_t nb_keys = sizeof(keys) / sizeof(KeyFinder);
 
     // -- Init the parser
-    Parser parser = {
-        .storage = (GenericPointer) cpus,
-        .capacity = MAX_PROCS,
-        .storage_struct_size = sizeof(Cpu),
-        .keys = keys,
-        .nb_keys = nb_keys,
-        .file = fopen("/proc/cpuinfo", "r")
-    };
+    Parser parser = {.storage = (GenericPointer)cpus,
+                     .capacity = MAX_PROCS,
+                     .storage_struct_size = sizeof(Cpu),
+                     .keys = keys,
+                     .nb_keys = nb_keys,
+                     .file = fopen("/proc/cpuinfo", "r")
+                    };
 
     // -- Parse the file
     parse(&parser);
@@ -137,4 +167,3 @@ int main()
     printf("==============================\n");
     return 0;
 }
-
diff --git a/src/memory_counters.c b/src/memory_counters.c
index 8e8e916..185f454 100644
--- a/src/memory_counters.c
+++ b/src/memory_counters.c
@@ -10,111 +10,121 @@
 static const char *path = "/proc/meminfo";
 
 typedef struct {
-  KeyFinder *keys;
-  unsigned int count;
-  FILE *file;
+    KeyFinder *keys;
+    unsigned int count;
+    FILE *file;
 } MemoryCounters;
 
-GenericPointer long_allocator(char *s) {
-  long value = atol(s);
-  return (GenericPointer)value;
+GenericPointer long_allocator(char *s)
+{
+    long value = atol(s);
+    return (GenericPointer)value;
 }
 
-KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes) {
-  KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
-  for (unsigned int i = 0; i < count; i++) {
-    unsigned int idx = indexes[i];
-    KeyFinder key = {.key = memory_counters[idx],
-                     .delimiter = ":",
-                     .copy = long_allocator,
-                     .set = setter_functions[i]};
-    memcpy(&keys[i], &key, sizeof(KeyFinder));
-  }
-  return keys;
+KeyFinder *build_keyfinder(unsigned int count, unsigned int *indexes)
+{
+    KeyFinder *keys = (KeyFinder *)calloc(count, sizeof(KeyFinder));
+    for (unsigned int i = 0; i < count; i++) {
+        unsigned int idx = indexes[i];
+        KeyFinder key = {.key = memory_counters[idx],
+                         .delimiter = ":",
+                         .copy = long_allocator,
+                         .set = setter_functions[i]
+                        };
+        memcpy(&keys[i], &key, sizeof(KeyFinder));
+    }
+    return keys;
 }
 
 void memory_list(char *memory_string, unsigned int *count,
-                 unsigned int *indexes) {
-  char *token;
-  *count = 0;
-
-  while ((token = strtok(memory_string, ",")) != NULL) {
-    memory_string = NULL;
-
-    unsigned int i;
-    for (i = 0; i < NB_COUNTERS; i++) {
-      if (strcmp(memory_counters[i], token) == 0) {
-        (*count)++;
-        indexes[*count - 1] = i;
-        break;
-      }
-    }
-
-    if (i == NB_COUNTERS) {
-      fprintf(stderr, "Unknown memory counter: %s\n", token);
-      exit(EXIT_FAILURE);
+                 unsigned int *indexes)
+{
+    char *token;
+    *count = 0;
+
+    while ((token = strtok(memory_string, ",")) != NULL) {
+        memory_string = NULL;
+
+        unsigned int i;
+        for (i = 0; i < NB_COUNTERS; i++) {
+            if (strcmp(memory_counters[i], token) == 0) {
+                (*count)++;
+                indexes[*count - 1] = i;
+                break;
+            }
+        }
+
+        if (i == NB_COUNTERS) {
+            fprintf(stderr, "Unknown memory counter: %s\n", token);
+            exit(EXIT_FAILURE);
+        }
+
+        if ((*count) > NB_COUNTERS) {
+            fprintf(stderr, "Too much counters, there are probably duplicates\n");
+            exit(EXIT_FAILURE);
+        }
     }
-
-    if ((*count) > NB_COUNTERS) {
-      fprintf(stderr, "Too much counters, there are probably duplicates\n");
-      exit(EXIT_FAILURE);
-    }
-  }
 }
 
-unsigned int init_memory_counters(char *args, void **ptr) {
-  unsigned int indexes[NB_COUNTERS];
-  unsigned int count = 0;
-  memory_list(args, &count, indexes);
+unsigned int init_memory_counters(char *args, void **ptr)
+{
+    unsigned int indexes[NB_COUNTERS];
+    unsigned int count = 0;
+    memory_list(args, &count, indexes);
 
-  KeyFinder *keys = build_keyfinder(count, indexes);
-  FILE *file = fopen(path, "r");
+    KeyFinder *keys = build_keyfinder(count, indexes);
+    FILE *file = fopen(path, "r");
 
-  MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
-  counters->keys = keys;
-  counters->count = count;
-  counters->file = file;
+    MemoryCounters *counters = calloc(1, sizeof(MemoryCounters));
+    counters->keys = keys;
+    counters->count = count;
+    counters->file = file;
 
-  *ptr = (void *)counters;
-  return count;
+    *ptr = (void *)counters;
+    return count;
 }
 
-unsigned int get_memory_counters(uint64_t *results, void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  fseek(counters->file, 0, SEEK_SET);
-  Parser parser = {.storage = (GenericPointer)results,
-                   .capacity = 1,
-                   .nb_stored = 0,
-                   .storage_struct_size = sizeof(uint64_t) * counters->count,
-                   .keys = counters->keys,
-                   .nb_keys = counters->count,
-                   .file = counters->file};
-
-  parse(&parser);
-  return counters->count;
+unsigned int get_memory_counters(uint64_t *results, void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    fseek(counters->file, 0, SEEK_SET);
+    Parser parser = {.storage = (GenericPointer)results,
+                     .capacity = 1,
+                     .nb_stored = 0,
+                     .storage_struct_size = sizeof(uint64_t) * counters->count,
+                     .keys = counters->keys,
+                     .nb_keys = counters->count,
+                     .file = counters->file
+                    };
+
+    parse(&parser);
+    return counters->count;
 }
 
-void label_memory_counters(char **labels, void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  for (unsigned int i = 0; i < counters->count; i++) {
-    labels[i] = counters->keys[i].key;
-  }
+void label_memory_counters(char **labels, void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    for (unsigned int i = 0; i < counters->count; i++) {
+        labels[i] = counters->keys[i].key;
+    }
 }
 
-void clean_memory_counters(void *ptr) {
-  MemoryCounters *counters = (MemoryCounters *)ptr;
-  fclose(counters->file);
-  free(counters->keys);
-  free(ptr);
+void clean_memory_counters(void *ptr)
+{
+    MemoryCounters *counters = (MemoryCounters *)ptr;
+    fclose(counters->file);
+    free(counters->keys);
+    free(ptr);
 }
 
-void *show_all_memory_counters(void *none1, size_t none2) {
-  for (unsigned int i = 0; i < NB_COUNTERS; i++) {
-    printf("%s\n", memory_counters[i]);
-  }
+void *show_all_memory_counters(void *none1, size_t none2)
+{
+    for (unsigned int i = 0; i < NB_COUNTERS; i++) {
+        printf("%s\n", memory_counters[i]);
+    }
 
-  UNUSED(none1);
-  UNUSED(none2);
-  exit(EXIT_SUCCESS);
-  return NULL; /* not reached */
+    UNUSED(none1);
+    UNUSED(none2);
+    exit(EXIT_SUCCESS);
+    return NULL; /* not reached */
 }
-- 
GitLab


From 1dc25900b97a9bb08a29929a00674d6cad485fc4 Mon Sep 17 00:00:00 2001
From: ghuter <ghuter@disroot.org>
Date: Mon, 24 Apr 2023 10:35:19 +0200
Subject: [PATCH 229/229] configure: no capability detection with `-u` flag

---
 configure.sh | 11 ++++++++---
 1 file changed, 8 insertions(+), 3 deletions(-)

diff --git a/configure.sh b/configure.sh
index 1246b0c..4d0eb76 100755
--- a/configure.sh
+++ b/configure.sh
@@ -130,8 +130,8 @@ detect_caps() {
 
 	if [ -e /usr/local/cuda/lib64 ] && [ -e /usr/local/cuda/include ]; then
 		hdr_whitelist="${hdr_whitelist}|nvidia_gpu"
-		NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml"
-		NVML_IFLAGS="-I/usr/local/cuda/include"
+		NVML_LDFLAGS='-L/usr/local/cuda/lib64 -lnvidia-ml'
+		NVML_IFLAGS='-I/usr/local/cuda/include'
 	fi
 
 	vendor=$(awk '/vendor_id/ {print $3; exit}' /proc/cpuinfo)
@@ -160,9 +160,14 @@ case $1 in
 	NVML_LDFLAGS="-L/usr/local/cuda/lib64 -lnvidia-ml"
 	NVML_IFLAGS="-I/usr/local/cuda/include"
 	;;
+--unique | -u)
+	unique=1
+	;;
 esac
 
-[ "$all" ] || detect_caps
+if ! [ "$all" ] && ! [ "$unique" ]; then
+	detect_caps
+fi
 
 [ "$all" ] ||
 	while [ "$1" ]; do
-- 
GitLab